mirror of https://github.com/buster-so/buster.git
emit and once
This commit is contained in:
parent
da8fd8ba18
commit
7fdae13b7c
|
@ -93,7 +93,7 @@ export type ChatDeleteChat = BusterSocketRequestBase<
|
|||
{
|
||||
/** The unique identifier of the chat to delete */
|
||||
id: string;
|
||||
}
|
||||
}[]
|
||||
>;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import type { BusterSocketResponse, BusterSocketResponseRoute } from '@/api/buster_socket';
|
||||
import type {
|
||||
BusterSocketRequest,
|
||||
BusterSocketResponse,
|
||||
BusterSocketResponseRoute
|
||||
} from '@/api/buster_socket';
|
||||
|
||||
//RESPONSE TYPES
|
||||
|
||||
export type BusterSocketResponseConfig<TRoute extends BusterSocketResponseRoute> = {
|
||||
route: TRoute;
|
||||
|
@ -14,3 +20,16 @@ export type InferBusterSocketResponseData<TRoute extends BusterSocketResponseRou
|
|||
>['callback'] extends (d: infer D) => void
|
||||
? D
|
||||
: never;
|
||||
|
||||
//REQUEST TYPES
|
||||
|
||||
export type BusterSocketRequestRoute = BusterSocketRequest['route'];
|
||||
|
||||
export type BusterSocketRequestConfig<TRoute extends BusterSocketRequestRoute> = {
|
||||
route: TRoute;
|
||||
};
|
||||
|
||||
export type InferBusterSocketRequestPayload<TRoute extends BusterSocketRequestRoute> = Extract<
|
||||
BusterSocketRequest,
|
||||
{ route: TRoute }
|
||||
>['payload'];
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
'use client';
|
||||
|
||||
import {
|
||||
type QueryFunction,
|
||||
type QueryKey,
|
||||
type UseQueryOptions,
|
||||
type UseMutationOptions,
|
||||
useMutation,
|
||||
useQueryClient
|
||||
} from '@tanstack/react-query';
|
||||
import type {
|
||||
BusterSocketRequest,
|
||||
BusterSocketResponse,
|
||||
BusterSocketResponseRoute
|
||||
} from '@/api/buster_socket';
|
||||
import { useBusterWebSocket } from '@/context/BusterWebSocket';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { queryOptionsConfig } from './queryKeyConfig';
|
||||
import type {
|
||||
BusterSocketRequestConfig,
|
||||
BusterSocketRequestRoute,
|
||||
BusterSocketResponseConfig,
|
||||
InferBusterSocketRequestPayload,
|
||||
InferBusterSocketResponseData
|
||||
} from './types';
|
||||
|
||||
export function useSocketMutation<
|
||||
TRequestRoute extends BusterSocketRequestRoute,
|
||||
TRoute extends BusterSocketResponseRoute,
|
||||
TError = unknown,
|
||||
TData = InferBusterSocketResponseData<TRoute>,
|
||||
TPayload = InferBusterSocketRequestPayload<TRequestRoute>
|
||||
>(
|
||||
socketRequest: BusterSocketRequestConfig<TRequestRoute>,
|
||||
socketResponse: BusterSocketResponseConfig<TRoute>,
|
||||
options?: Omit<UseMutationOptions<TData, TError, TPayload>, 'mutationFn'>
|
||||
) {
|
||||
const busterSocket = useBusterWebSocket();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const mutationFn = useMemoizedFn(async (variables: TPayload): Promise<TData> => {
|
||||
try {
|
||||
const result = await busterSocket.emitAndOnce({
|
||||
emitEvent: {
|
||||
route: socketRequest.route,
|
||||
payload: variables
|
||||
} as BusterSocketRequest,
|
||||
responseEvent: {
|
||||
route: socketResponse.route,
|
||||
onError: socketResponse.onError,
|
||||
callback: (d: unknown) => d
|
||||
} as BusterSocketResponse
|
||||
});
|
||||
|
||||
return result as TData;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
return useMutation<TData, TError, TPayload>({
|
||||
mutationFn,
|
||||
...options
|
||||
});
|
||||
}
|
||||
|
||||
const ExampleComponent = () => {
|
||||
const { mutate } = useSocketMutation<'/chats/delete', '/chats/delete:deleteChat'>(
|
||||
{ route: '/chats/delete' },
|
||||
{ route: '/chats/delete:deleteChat' },
|
||||
{
|
||||
onSuccess: (data) => {
|
||||
console.log(data);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
mutate([{ id: '123' }]);
|
||||
};
|
|
@ -1,11 +1,11 @@
|
|||
'use client';
|
||||
|
||||
import {
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
type QueryFunction,
|
||||
type QueryKey,
|
||||
type UseQueryOptions,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
UseQueryOptions
|
||||
useQueryClient
|
||||
} from '@tanstack/react-query';
|
||||
import type {
|
||||
BusterSocketRequest,
|
||||
|
@ -13,16 +13,10 @@ import type {
|
|||
BusterSocketResponseRoute
|
||||
} from '@/api/buster_socket';
|
||||
import { useBusterWebSocket } from '@/context/BusterWebSocket';
|
||||
import type {
|
||||
UseBusterSocketQueryResult,
|
||||
InferBusterSocketResponseData,
|
||||
BusterSocketResponseConfig
|
||||
} from '../useSocketQuery/types';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { createQueryKey } from '../useSocketQuery/helpers';
|
||||
import { useMemo } from 'react';
|
||||
import { queryOptionsConfig } from './queryKeyConfig';
|
||||
import { BusterChat } from '@/api/asset_interfaces';
|
||||
import type { BusterChat } from '@/api/asset_interfaces';
|
||||
import { InferBusterSocketResponseData } from './types';
|
||||
|
||||
export function useSocketQueryEmitAndOnce<
|
||||
TRoute extends BusterSocketResponseRoute,
|
||||
|
@ -34,34 +28,32 @@ export function useSocketQueryEmitAndOnce<
|
|||
socketResponse: TRoute,
|
||||
options: UseQueryOptions<TData, TError, TData, TQueryKey>,
|
||||
callback?: (currentData: TData | null, newData: InferBusterSocketResponseData<TRoute>) => TData
|
||||
): UseBusterSocketQueryResult<TData, TError> {
|
||||
) {
|
||||
const busterSocket = useBusterWebSocket();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const queryFn: QueryFunction<TData> = useMemoizedFn(
|
||||
async ({ queryKey, ...rest }): Promise<TData> => {
|
||||
try {
|
||||
const result = await busterSocket.emitAndOnce({
|
||||
emitEvent: socketRequest,
|
||||
responseEvent: {
|
||||
route: socketResponse,
|
||||
callback: (d: unknown) => {
|
||||
const socketData = d as InferBusterSocketResponseData<TRoute>;
|
||||
if (callback) {
|
||||
const currentData = queryClient.getQueryData<TData>(queryKey) ?? null;
|
||||
return callback(currentData, socketData);
|
||||
}
|
||||
return socketData as TData;
|
||||
const queryFn: QueryFunction<TData> = useMemoizedFn(async ({ queryKey }): Promise<TData> => {
|
||||
try {
|
||||
const result = await busterSocket.emitAndOnce({
|
||||
emitEvent: socketRequest,
|
||||
responseEvent: {
|
||||
route: socketResponse,
|
||||
callback: (d: unknown) => {
|
||||
const socketData = d as InferBusterSocketResponseData<TRoute>;
|
||||
if (callback) {
|
||||
const currentData = queryClient.getQueryData<TData>(queryKey) ?? null;
|
||||
return callback(currentData, socketData);
|
||||
}
|
||||
} as BusterSocketResponse
|
||||
});
|
||||
return socketData as TData;
|
||||
}
|
||||
} as BusterSocketResponse
|
||||
});
|
||||
|
||||
return result as TData;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
return result as TData;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return useQuery({
|
||||
queryFn,
|
||||
|
|
Loading…
Reference in New Issue