mirror of https://github.com/buster-so/buster.git
test
This commit is contained in:
parent
e91e0d9f86
commit
04a884da50
|
@ -1,7 +1,7 @@
|
||||||
import { useBusterWebSocket } from '../BusterWebSocket';
|
import { useBusterWebSocket } from '../BusterWebSocket';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { BusterUserFavorite, ShareAssetType } from '@/api/asset_interfaces';
|
import { BusterUserFavorite, ShareAssetType } from '@/api/asset_interfaces';
|
||||||
import { createQueryKey, useSocketQueryEmitOn } from '@/hooks';
|
import { createQueryKey, useSocketQueryEmitOn, useSocketQueryMutation } from '@/hooks';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
|
||||||
|
@ -19,6 +19,13 @@ export const useFavoriteProvider = () => {
|
||||||
{ route: '/users/favorites/list:listFavorites' }
|
{ route: '/users/favorites/list:listFavorites' }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { mutate: addItemToFavorite } = useSocketQueryMutation(
|
||||||
|
{ route: '/users/favorites/post' },
|
||||||
|
{
|
||||||
|
route: '/users/favorites/post:createFavorite'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const setUserFavorites = useMemoizedFn(
|
const setUserFavorites = useMemoizedFn(
|
||||||
(updater: (v: BusterUserFavorite[]) => BusterUserFavorite[]) => {
|
(updater: (v: BusterUserFavorite[]) => BusterUserFavorite[]) => {
|
||||||
queryClient.setQueryData(favoritesQueryKey, (v: BusterUserFavorite[] | undefined) => {
|
queryClient.setQueryData(favoritesQueryKey, (v: BusterUserFavorite[] | undefined) => {
|
||||||
|
@ -27,7 +34,7 @@ export const useFavoriteProvider = () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const addItemToFavorite = useMemoizedFn(
|
const aXddItemToFavorite = useMemoizedFn(
|
||||||
async ({
|
async ({
|
||||||
id,
|
id,
|
||||||
asset_type,
|
asset_type,
|
||||||
|
|
|
@ -4,5 +4,6 @@ import { BusterSocketResponseConfig } from './types';
|
||||||
export * from './useSocketQueryEmitAndOnce';
|
export * from './useSocketQueryEmitAndOnce';
|
||||||
export * from './useSocketQueryEmitOn';
|
export * from './useSocketQueryEmitOn';
|
||||||
export * from './useSocketQueryOn';
|
export * from './useSocketQueryOn';
|
||||||
|
export * from './useSocketQueryMutation';
|
||||||
|
|
||||||
export { createQueryKey, type BusterSocketResponseConfig };
|
export { createQueryKey, type BusterSocketResponseConfig };
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
import type { BusterSocketResponse, BusterSocketResponseRoute } from '@/api/buster_socket';
|
import type {
|
||||||
|
BusterSocketRequest,
|
||||||
|
BusterSocketResponse,
|
||||||
|
BusterSocketResponseRoute
|
||||||
|
} from '@/api/buster_socket';
|
||||||
import { UseQueryResult } from '@tanstack/react-query';
|
import { UseQueryResult } from '@tanstack/react-query';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,3 +24,17 @@ export type BusterSocketResponseConfig<TRoute extends BusterSocketResponseRoute>
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UseBusterSocketQueryResult<TData, TError = unknown> = UseQueryResult<TData, TError>;
|
export type UseBusterSocketQueryResult<TData, TError = unknown> = UseQueryResult<TData, TError>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the route type from BusterSocketRequest
|
||||||
|
*/
|
||||||
|
export type BusterSocketRequestRoute = BusterSocketRequest['route'];
|
||||||
|
|
||||||
|
export type BusterSocketRequestConfig<TRoute extends BusterSocketRequestRoute> = {
|
||||||
|
route: TRoute;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type InferBusterSocketRequestPayload<TRoute extends BusterSocketRequestRoute> = Extract<
|
||||||
|
BusterSocketRequest,
|
||||||
|
{ route: TRoute }
|
||||||
|
>['payload'];
|
||||||
|
|
|
@ -35,7 +35,6 @@ export const useSocketQueryEmitOn = <TRoute extends BusterSocketResponseRoute, T
|
||||||
>
|
>
|
||||||
): UseBusterSocketQueryResult<InferBusterSocketResponseData<TRoute>, TError> => {
|
): UseBusterSocketQueryResult<InferBusterSocketResponseData<TRoute>, TError> => {
|
||||||
const busterSocket = useBusterWebSocket();
|
const busterSocket = useBusterWebSocket();
|
||||||
const queryClient = useQueryClient();
|
|
||||||
|
|
||||||
const queryKey = createQueryKey(socketResponse, socketRequest);
|
const queryKey = createQueryKey(socketResponse, socketRequest);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,13 @@ import {
|
||||||
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query';
|
||||||
import { useBusterWebSocket } from '@/context/BusterWebSocket';
|
import { useBusterWebSocket } from '@/context/BusterWebSocket';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { BusterSocketResponseConfig, InferBusterSocketResponseData } from './types';
|
import {
|
||||||
|
BusterSocketResponseConfig,
|
||||||
|
InferBusterSocketResponseData,
|
||||||
|
InferBusterSocketRequestPayload,
|
||||||
|
BusterSocketRequestConfig,
|
||||||
|
BusterSocketRequestRoute
|
||||||
|
} from './types';
|
||||||
import { ShareAssetType } from '@/api/asset_interfaces';
|
import { ShareAssetType } from '@/api/asset_interfaces';
|
||||||
import { createQueryKey } from './helpers';
|
import { createQueryKey } from './helpers';
|
||||||
|
|
||||||
|
@ -25,11 +31,12 @@ import { createQueryKey } from './helpers';
|
||||||
* @returns A React Query mutation result for handling socket requests
|
* @returns A React Query mutation result for handling socket requests
|
||||||
*/
|
*/
|
||||||
export const useSocketQueryMutation = <
|
export const useSocketQueryMutation = <
|
||||||
|
TRequestRoute extends BusterSocketRequestRoute,
|
||||||
TRoute extends BusterSocketResponseRoute,
|
TRoute extends BusterSocketResponseRoute,
|
||||||
TVariables = void,
|
TError = unknown,
|
||||||
TError = unknown
|
TVariables = InferBusterSocketRequestPayload<TRequestRoute>
|
||||||
>(
|
>(
|
||||||
socketRequest: BusterSocketRequest,
|
socketRequest: BusterSocketRequestConfig<TRequestRoute>,
|
||||||
socketResponse: BusterSocketResponseConfig<TRoute> & {
|
socketResponse: BusterSocketResponseConfig<TRoute> & {
|
||||||
callback?: (d: unknown) => InferBusterSocketResponseData<TRoute>;
|
callback?: (d: unknown) => InferBusterSocketResponseData<TRoute>;
|
||||||
},
|
},
|
||||||
|
@ -49,7 +56,11 @@ export const useSocketQueryMutation = <
|
||||||
const { preSetQueryData, queryDataStrategy = 'ignore', ...options } = optionsProps || {};
|
const { preSetQueryData, queryDataStrategy = 'ignore', ...options } = optionsProps || {};
|
||||||
|
|
||||||
const mutationFn = useMemoizedFn(async (variables: TVariables) => {
|
const mutationFn = useMemoizedFn(async (variables: TVariables) => {
|
||||||
const queryKey = createQueryKey(socketResponse, socketRequest);
|
const compiledSocketRequest = {
|
||||||
|
...socketRequest,
|
||||||
|
payload: variables
|
||||||
|
} as unknown as BusterSocketRequest;
|
||||||
|
const queryKey = createQueryKey(socketResponse, compiledSocketRequest);
|
||||||
|
|
||||||
if (preSetQueryData) {
|
if (preSetQueryData) {
|
||||||
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>>(queryKey, (d) => {
|
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>>(queryKey, (d) => {
|
||||||
|
@ -58,7 +69,7 @@ export const useSocketQueryMutation = <
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await busterSocket.emitAndOnce({
|
const res = await busterSocket.emitAndOnce({
|
||||||
emitEvent: socketRequest,
|
emitEvent: compiledSocketRequest,
|
||||||
responseEvent: {
|
responseEvent: {
|
||||||
...socketResponse,
|
...socketResponse,
|
||||||
callback: (d: unknown) => {
|
callback: (d: unknown) => {
|
||||||
|
@ -70,61 +81,62 @@ export const useSocketQueryMutation = <
|
||||||
} as BusterSocketResponse
|
} as BusterSocketResponse
|
||||||
});
|
});
|
||||||
|
|
||||||
if (queryDataStrategy === 'replace') {
|
if (res !== undefined) {
|
||||||
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>>(queryKey, () => {
|
if (queryDataStrategy === 'replace') {
|
||||||
return res as InferBusterSocketResponseData<TRoute>;
|
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>>(queryKey, () => {
|
||||||
});
|
return res as InferBusterSocketResponseData<TRoute>;
|
||||||
} else if (queryDataStrategy === 'append') {
|
});
|
||||||
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>[]>(queryKey, (d) => {
|
} else if (queryDataStrategy === 'append') {
|
||||||
return [...(Array.isArray(d) ? d : []), res as InferBusterSocketResponseData<TRoute>];
|
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>[]>(queryKey, (d) => {
|
||||||
});
|
return [...(Array.isArray(d) ? d : []), res as InferBusterSocketResponseData<TRoute>];
|
||||||
} else if (queryDataStrategy === 'prepend') {
|
});
|
||||||
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>[]>(queryKey, (d) => {
|
} else if (queryDataStrategy === 'prepend') {
|
||||||
return [res as InferBusterSocketResponseData<TRoute>, ...(Array.isArray(d) ? d : [])];
|
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>[]>(queryKey, (d) => {
|
||||||
});
|
return [res as InferBusterSocketResponseData<TRoute>, ...(Array.isArray(d) ? d : [])];
|
||||||
} else if (queryDataStrategy === 'merge') {
|
});
|
||||||
await queryClient.setQueryData<Record<string, InferBusterSocketResponseData<TRoute>>>(
|
} else if (queryDataStrategy === 'merge') {
|
||||||
queryKey,
|
await queryClient.setQueryData<Record<string, InferBusterSocketResponseData<TRoute>>>(
|
||||||
(d) => {
|
queryKey,
|
||||||
if (typeof res === 'object' && res !== null && 'id' in res) {
|
(d) => {
|
||||||
const typedRes = res as InferBusterSocketResponseData<TRoute> & { id: string };
|
if (typeof res === 'object' && res !== null && 'id' in res) {
|
||||||
return {
|
const typedRes = res as InferBusterSocketResponseData<TRoute> & { id: string };
|
||||||
...(d || {}),
|
return {
|
||||||
[typedRes.id]: typedRes
|
...(d || {}),
|
||||||
};
|
[typedRes.id]: typedRes
|
||||||
} else {
|
};
|
||||||
console.warn('response is not an object with an id', res);
|
} else {
|
||||||
|
console.warn('response is not an object with an id', res);
|
||||||
|
}
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
return d;
|
);
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res as InferBusterSocketResponseData<TRoute>;
|
return res as InferBusterSocketResponseData<TRoute>;
|
||||||
});
|
});
|
||||||
|
|
||||||
return useMutation<InferBusterSocketResponseData<TRoute>, TError, TVariables>({
|
return useMutation({
|
||||||
...options,
|
...options,
|
||||||
mutationFn
|
mutationFn: mutationFn
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const Example = () => {
|
const Example = () => {
|
||||||
const { mutate, data, ...rest } = useSocketQueryMutation(
|
// Example 1: Favorites mutation
|
||||||
|
const { mutate, data } = useSocketQueryMutation(
|
||||||
{
|
{
|
||||||
route: '/users/favorites/post',
|
route: '/users/favorites/post'
|
||||||
payload: {
|
|
||||||
id: '1',
|
|
||||||
asset_type: ShareAssetType.DASHBOARD
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
route: '/users/favorites/post:createFavorite'
|
route: '/users/favorites/post:createFavorite'
|
||||||
},
|
|
||||||
{
|
|
||||||
preSetQueryData: (d) => {
|
|
||||||
return d || [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
mutate({
|
||||||
|
id: 'some-asset-id',
|
||||||
|
asset_type: ShareAssetType.DASHBOARD
|
||||||
|
});
|
||||||
|
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue