mirror of https://github.com/buster-so/buster.git
update to use new syntax
This commit is contained in:
parent
bdd1cbd64c
commit
f32bbf0a75
|
@ -31,12 +31,14 @@ export const useCollectionCreate = () => {
|
||||||
{ route: '/collections/delete' },
|
{ route: '/collections/delete' },
|
||||||
{ route: '/collections/delete:deleteCollections' },
|
{ route: '/collections/delete:deleteCollections' },
|
||||||
{
|
{
|
||||||
preSetQueryDataFunction: {
|
preSetQueryData: [
|
||||||
responseRoute: '/collections/list:listCollections',
|
{
|
||||||
callback: (data, variables) => {
|
responseRoute: '/collections/list:listCollections',
|
||||||
return data?.filter((collection) => !variables.ids.includes(collection.id)) || [];
|
callback: (data, variables) => {
|
||||||
|
return data?.filter((collection) => !variables.ids.includes(collection.id)) || [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -8,23 +8,28 @@ export const useCollectionUpdate = () => {
|
||||||
{ route: '/collections/update' },
|
{ route: '/collections/update' },
|
||||||
{ route: '/collections/update:collectionState' },
|
{ route: '/collections/update:collectionState' },
|
||||||
{
|
{
|
||||||
preSetQueryData(data, _variables) {
|
preSetQueryData: [
|
||||||
const variables = _variables as Partial<BusterCollection>;
|
{
|
||||||
const newObject: BusterCollection = { ...data!, ...variables };
|
responseRoute: '/collections/get:collectionState',
|
||||||
return newObject;
|
callback: (data, _variables) => {
|
||||||
},
|
const variables = _variables as Partial<BusterCollection>;
|
||||||
preSetQueryDataFunction: {
|
const newObject: BusterCollection = { ...data!, ...variables };
|
||||||
responseRoute: '/collections/list:listCollections',
|
return newObject;
|
||||||
callback: (data, _variables) => {
|
}
|
||||||
const existingData = data || [];
|
},
|
||||||
const variables = _variables as Partial<BusterCollection>;
|
{
|
||||||
return existingData.map((collection) =>
|
responseRoute: '/collections/list:listCollections',
|
||||||
collection.id === variables.id
|
callback: (data, _variables) => {
|
||||||
? { ...collection, name: variables.name || collection.name }
|
const existingData = data || [];
|
||||||
: collection
|
const variables = _variables as Partial<BusterCollection>;
|
||||||
);
|
return existingData.map((collection) =>
|
||||||
|
collection.id === variables.id
|
||||||
|
? { ...collection, name: variables.name || collection.name }
|
||||||
|
: collection
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -20,17 +20,19 @@ export const useDashboardUpdateConfig = ({
|
||||||
{ route: '/dashboards/update' },
|
{ route: '/dashboards/update' },
|
||||||
{ route: '/dashboards/update:updateDashboard' },
|
{ route: '/dashboards/update:updateDashboard' },
|
||||||
{
|
{
|
||||||
preSetQueryDataFunction: {
|
preSetQueryData: [
|
||||||
responseRoute: '/dashboards/get:getDashboardState',
|
{
|
||||||
callback: (data, variables) => {
|
responseRoute: '/dashboards/get:getDashboardState',
|
||||||
const newObject: BusterDashboardResponse = create(data!, (draft) => {
|
callback: (data, variables) => {
|
||||||
Object.assign(draft.dashboard, variables, {
|
const newObject: BusterDashboardResponse = create(data!, (draft) => {
|
||||||
config: { ...draft.dashboard.config, ...variables.config }
|
Object.assign(draft.dashboard, variables, {
|
||||||
|
config: { ...draft.dashboard.config, ...variables.config }
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
return newObject;
|
||||||
return newObject;
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -10,15 +10,26 @@ export const useFavoriteProvider = () => {
|
||||||
const { mutate: addItemToFavorite } = useSocketQueryMutation(
|
const { mutate: addItemToFavorite } = useSocketQueryMutation(
|
||||||
{ route: '/users/favorites/post' },
|
{ route: '/users/favorites/post' },
|
||||||
{ route: '/users/favorites/post:createFavorite' },
|
{ route: '/users/favorites/post:createFavorite' },
|
||||||
{ preSetQueryData: (prev, mutationParams) => [mutationParams, ...(prev || [])] }
|
{
|
||||||
|
preSetQueryData: [
|
||||||
|
{
|
||||||
|
responseRoute: '/users/favorites/list:listFavorites',
|
||||||
|
callback: (prev, mutationParams) => [mutationParams, ...(prev || [])]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const { mutate: removeItemFromFavorite } = useSocketQueryMutation(
|
const { mutate: removeItemFromFavorite } = useSocketQueryMutation(
|
||||||
{ route: '/users/favorites/delete' },
|
{ route: '/users/favorites/delete' },
|
||||||
{ route: '/users/favorites/post:createFavorite' },
|
{ route: '/users/favorites/post:createFavorite' },
|
||||||
{
|
{
|
||||||
preSetQueryData: (prev, mutationParams) =>
|
preSetQueryData: [
|
||||||
prev?.filter((f) => f.id !== mutationParams.id) || []
|
{
|
||||||
|
responseRoute: '/users/favorites/list:listFavorites',
|
||||||
|
callback: (prev, mutationParams) => prev?.filter((f) => f.id !== mutationParams.id) || []
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -27,12 +38,17 @@ export const useFavoriteProvider = () => {
|
||||||
{ route: '/users/favorites/update:updateFavorite' },
|
{ route: '/users/favorites/update:updateFavorite' },
|
||||||
{
|
{
|
||||||
awaitPrefetchQueryData: true,
|
awaitPrefetchQueryData: true,
|
||||||
preSetQueryData: (prev, mutationParams) => {
|
preSetQueryData: [
|
||||||
return mutationParams.favorites.map((id, index) => {
|
{
|
||||||
let favorite = (prev || []).find((f) => f.id === id || f.collection_id === id)!;
|
responseRoute: '/users/favorites/list:listFavorites',
|
||||||
return { ...favorite, index };
|
callback: (prev, mutationParams) => {
|
||||||
});
|
return mutationParams.favorites.map((id, index) => {
|
||||||
}
|
let favorite = (prev || []).find((f) => f.id === id || f.collection_id === id)!;
|
||||||
|
return { ...favorite, index };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { UseMutationOptions } from '@tanstack/react-query';
|
||||||
|
import { BusterSocketResponseRoute } from '@/api/buster_socket';
|
||||||
|
import type { InferBusterSocketResponseData, BusterSocketRequestRoute } from './types';
|
||||||
|
|
||||||
|
export type QueryDataStrategy = 'replace' | 'append' | 'prepend' | 'merge' | 'ignore';
|
||||||
|
|
||||||
|
export type PreSetQueryDataItem<TVariables> = {
|
||||||
|
[Route in BusterSocketResponseRoute]: {
|
||||||
|
responseRoute: Route;
|
||||||
|
requestRoute?: BusterSocketRequestRoute;
|
||||||
|
callback: (
|
||||||
|
data: InferBusterSocketResponseData<Route>,
|
||||||
|
variables: TVariables
|
||||||
|
) => InferBusterSocketResponseData<Route>;
|
||||||
|
};
|
||||||
|
}[BusterSocketResponseRoute];
|
||||||
|
|
||||||
|
export type SinglePreSetQueryDataItem<TRoute extends BusterSocketResponseRoute, TVariables> = {
|
||||||
|
requestRoute?: BusterSocketRequestRoute;
|
||||||
|
callback: (
|
||||||
|
data: InferBusterSocketResponseData<TRoute>,
|
||||||
|
variables: TVariables
|
||||||
|
) => InferBusterSocketResponseData<TRoute>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SocketQueryMutationOptions<
|
||||||
|
TRoute extends BusterSocketResponseRoute,
|
||||||
|
TError,
|
||||||
|
TVariables
|
||||||
|
> = Omit<
|
||||||
|
UseMutationOptions<InferBusterSocketResponseData<TRoute>, TError, TVariables>,
|
||||||
|
'mutationFn'
|
||||||
|
> & {
|
||||||
|
/**
|
||||||
|
* Configuration for optimistically updating query data before the mutation completes.
|
||||||
|
* Can be either a single item or an array of items.
|
||||||
|
*/
|
||||||
|
preSetQueryData?:
|
||||||
|
| Array<PreSetQueryDataItem<TVariables>>
|
||||||
|
| SinglePreSetQueryDataItem<TRoute, TVariables>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When true, adds a small delay before applying preSetQueryData to ensure React Query's cache
|
||||||
|
* is properly initialized.
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
awaitPrefetchQueryData?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strategy for integrating mutation response data into existing query data.
|
||||||
|
* @property 'replace' - Replace existing data
|
||||||
|
* @property 'append' - Add to end of array
|
||||||
|
* @property 'prepend' - Add to start of array
|
||||||
|
* @property 'merge' - Merge objects (requires ID field)
|
||||||
|
* @property 'ignore' - No automatic update
|
||||||
|
* @default 'ignore'
|
||||||
|
*/
|
||||||
|
queryDataStrategy?: QueryDataStrategy;
|
||||||
|
};
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { QueryClient } from '@tanstack/react-query';
|
||||||
|
import { QueryDataStrategy } from './mutationTypes';
|
||||||
|
import { BusterSocketResponseRoute } from '@/api/buster_socket';
|
||||||
|
import { InferBusterSocketResponseData } from './types';
|
||||||
|
|
||||||
|
export const executeQueryDataStrategy = async <TRoute extends BusterSocketResponseRoute>(
|
||||||
|
queryClient: QueryClient,
|
||||||
|
queryKey: unknown[],
|
||||||
|
data: InferBusterSocketResponseData<TRoute>,
|
||||||
|
strategy: QueryDataStrategy
|
||||||
|
) => {
|
||||||
|
if (strategy === 'ignore') return;
|
||||||
|
|
||||||
|
const strategies: Record<Exclude<QueryDataStrategy, 'ignore'>, () => Promise<void>> = {
|
||||||
|
replace: async () => {
|
||||||
|
await queryClient.setQueryData(queryKey, data);
|
||||||
|
},
|
||||||
|
append: async () => {
|
||||||
|
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>[]>(queryKey, (prev) => [
|
||||||
|
...(Array.isArray(prev) ? prev : []),
|
||||||
|
data
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
prepend: async () => {
|
||||||
|
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>[]>(queryKey, (prev) => [
|
||||||
|
data,
|
||||||
|
...(Array.isArray(prev) ? prev : [])
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
merge: async () => {
|
||||||
|
if (typeof data === 'object' && data !== null && 'id' in data) {
|
||||||
|
await queryClient.setQueryData<Record<string, InferBusterSocketResponseData<TRoute>>>(
|
||||||
|
queryKey,
|
||||||
|
(prev) => ({
|
||||||
|
...(prev || {}),
|
||||||
|
[(data as { id: string }).id]: data
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateStrategy = strategies[strategy as Exclude<QueryDataStrategy, 'ignore'>];
|
||||||
|
|
||||||
|
if (updateStrategy) {
|
||||||
|
await updateStrategy();
|
||||||
|
}
|
||||||
|
};
|
|
@ -3,7 +3,7 @@ import {
|
||||||
BusterSocketResponse,
|
BusterSocketResponse,
|
||||||
BusterSocketResponseRoute
|
BusterSocketResponseRoute
|
||||||
} from '@/api/buster_socket';
|
} from '@/api/buster_socket';
|
||||||
import { QueryKey, useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import { useBusterWebSocket } from '@/context/BusterWebSocket';
|
import { useBusterWebSocket } from '@/context/BusterWebSocket';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import {
|
import {
|
||||||
|
@ -13,105 +13,39 @@ import {
|
||||||
BusterSocketRequestConfig,
|
BusterSocketRequestConfig,
|
||||||
BusterSocketRequestRoute
|
BusterSocketRequestRoute
|
||||||
} from './types';
|
} from './types';
|
||||||
import { ShareAssetType, BusterUserFavorite } from '@/api/asset_interfaces';
|
import { SocketQueryMutationOptions } from './mutationTypes';
|
||||||
|
import { executeQueryDataStrategy } from './queryDataStrategies';
|
||||||
import { createQueryKey } from './helpers';
|
import { createQueryKey } from './helpers';
|
||||||
|
|
||||||
type QueryDataStrategy = 'replace' | 'append' | 'prepend' | 'merge' | 'ignore';
|
|
||||||
|
|
||||||
// For array items, each item's callback data type is inferred from its responseRoute
|
|
||||||
type PreSetQueryDataItem<TVariables> = {
|
|
||||||
[Route in BusterSocketResponseRoute]: {
|
|
||||||
responseRoute: Route;
|
|
||||||
requestRoute?: BusterSocketRequestRoute;
|
|
||||||
callback: (
|
|
||||||
data: InferBusterSocketResponseData<Route>,
|
|
||||||
variables: TVariables
|
|
||||||
) => InferBusterSocketResponseData<Route>;
|
|
||||||
};
|
|
||||||
}[BusterSocketResponseRoute];
|
|
||||||
|
|
||||||
// For single items, callback data type is either from provided responseRoute or main route
|
|
||||||
type SinglePreSetQueryDataItem<TRoute extends BusterSocketResponseRoute, TVariables> = {
|
|
||||||
requestRoute?: BusterSocketRequestRoute;
|
|
||||||
callback: (
|
|
||||||
data: InferBusterSocketResponseData<TRoute>,
|
|
||||||
variables: TVariables
|
|
||||||
) => InferBusterSocketResponseData<TRoute>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SocketQueryMutationOptions<
|
|
||||||
TRoute extends BusterSocketResponseRoute,
|
|
||||||
TError,
|
|
||||||
TVariables
|
|
||||||
> = Omit<
|
|
||||||
UseMutationOptions<InferBusterSocketResponseData<TRoute>, TError, TVariables>,
|
|
||||||
'mutationFn'
|
|
||||||
> & {
|
|
||||||
/**
|
|
||||||
* Configuration for optimistically updating query data before the mutation completes.
|
|
||||||
* Can be either a single item or an array of items.
|
|
||||||
*
|
|
||||||
* For array items: callback data type is inferred from each item's responseRoute
|
|
||||||
* For single item:
|
|
||||||
* - If responseRoute provided: callback data type is inferred from that route
|
|
||||||
* - If no responseRoute: callback data type is inferred from main response route
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* // Single item without responseRoute (uses main response route's type)
|
|
||||||
* useSocketQueryMutation(
|
|
||||||
* { route: '/users/favorites/post' },
|
|
||||||
* { route: '/users/favorites/post:createFavorite' },
|
|
||||||
* {
|
|
||||||
* preSetQueryData: {
|
|
||||||
* callback: (existingFavorites, variables) => [...(existingFavorites || []), variables]
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
preSetQueryData?:
|
|
||||||
| Array<PreSetQueryDataItem<TVariables>>
|
|
||||||
| SinglePreSetQueryDataItem<TRoute, TVariables>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When true, adds a small delay before applying preSetQueryData to ensure React Query's cache
|
|
||||||
* is properly initialized. This is useful when the mutation is called immediately after
|
|
||||||
* component mount and you need to ensure the cache exists before updating it.
|
|
||||||
*
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
awaitPrefetchQueryData?: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines how the mutation response data should be integrated into existing query data.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* // Example: Append new item to a list
|
|
||||||
* queryDataStrategy: 'append'
|
|
||||||
*
|
|
||||||
* @property 'replace' - Completely replace existing data with new data
|
|
||||||
* @property 'append' - Add new data to the end of an existing array
|
|
||||||
* @property 'prepend' - Add new data to the beginning of an existing array
|
|
||||||
* @property 'merge' - Merge new data with existing data (useful for objects with IDs)
|
|
||||||
* @property 'ignore' - Don't automatically update query data
|
|
||||||
*
|
|
||||||
* @default 'ignore'
|
|
||||||
*/
|
|
||||||
queryDataStrategy?: QueryDataStrategy;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A hook that creates a mutation for emitting socket requests and handling responses.
|
* A hook that creates a mutation for emitting socket requests and handling responses.
|
||||||
|
* Supports optimistic updates and various strategies for updating the query cache.
|
||||||
*
|
*
|
||||||
* @template TRoute - The type of socket response route
|
* @template TRequestRoute - The socket request route type
|
||||||
* @template TData - The type of data returned by the socket response
|
* @template TRoute - The socket response route type
|
||||||
* @template TVariables - The type of variables passed to the mutation function
|
* @template TError - The error type that can occur
|
||||||
* @template TError - The type of error that can occur
|
* @template TVariables - The variables type passed to the mutation function
|
||||||
*
|
*
|
||||||
* @param socketRequest - The base socket request to emit (variables will be merged with this)
|
* @param socketRequest - The base socket request configuration
|
||||||
* @param socketResponse - Configuration for the socket response including route and error handler
|
* @param socketResponse - The socket response configuration with optional error handler
|
||||||
* @param options - Additional options for the React Query mutation hook
|
* @param options - Additional options for configuring the mutation behavior
|
||||||
*
|
*
|
||||||
* @returns A React Query mutation result for handling socket requests
|
* @example
|
||||||
|
* ```tsx
|
||||||
|
* const { mutate } = useSocketQueryMutation(
|
||||||
|
* { route: '/users/favorites/post' },
|
||||||
|
* { route: '/users/favorites/post:createFavorite' },
|
||||||
|
* {
|
||||||
|
* preSetQueryData: [
|
||||||
|
* {
|
||||||
|
* responseRoute: '/users/favorites/list:listFavorites',
|
||||||
|
* callback: (data, variables) => [...(data || []), variables]
|
||||||
|
* }
|
||||||
|
* ],
|
||||||
|
* queryDataStrategy: 'append'
|
||||||
|
* }
|
||||||
|
* );
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
export const useSocketQueryMutation = <
|
export const useSocketQueryMutation = <
|
||||||
TRequestRoute extends BusterSocketRequestRoute,
|
TRequestRoute extends BusterSocketRequestRoute,
|
||||||
|
@ -129,45 +63,26 @@ export const useSocketQueryMutation = <
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { preSetQueryData, queryDataStrategy = 'ignore', ...mutationOptions } = options || {};
|
const { preSetQueryData, queryDataStrategy = 'ignore', ...mutationOptions } = options || {};
|
||||||
|
|
||||||
const updateQueryData = useMemoizedFn(
|
const handlePreSetQueryData = useMemoizedFn(async (variables: TVariables) => {
|
||||||
async (queryKey: QueryKey, data: InferBusterSocketResponseData<TRoute>) => {
|
if (!preSetQueryData) return;
|
||||||
if (queryDataStrategy === 'ignore') return;
|
|
||||||
|
|
||||||
const strategies: Record<Exclude<QueryDataStrategy, 'ignore'>, () => Promise<void>> = {
|
if (options?.awaitPrefetchQueryData) {
|
||||||
replace: async () => {
|
await new Promise((resolve) => requestAnimationFrame(resolve));
|
||||||
await queryClient.setQueryData(queryKey, data);
|
|
||||||
},
|
|
||||||
append: async () => {
|
|
||||||
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>[]>(
|
|
||||||
queryKey,
|
|
||||||
(prev) => [...(Array.isArray(prev) ? prev : []), data]
|
|
||||||
);
|
|
||||||
},
|
|
||||||
prepend: async () => {
|
|
||||||
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>[]>(
|
|
||||||
queryKey,
|
|
||||||
(prev) => [data, ...(Array.isArray(prev) ? prev : [])]
|
|
||||||
);
|
|
||||||
},
|
|
||||||
merge: async () => {
|
|
||||||
if (typeof data === 'object' && data !== null && 'id' in data) {
|
|
||||||
await queryClient.setQueryData<Record<string, InferBusterSocketResponseData<TRoute>>>(
|
|
||||||
queryKey,
|
|
||||||
(prev) => ({
|
|
||||||
...(prev || {}),
|
|
||||||
[(data as { id: string }).id]: data
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateStrategy = strategies[queryDataStrategy as Exclude<QueryDataStrategy, 'ignore'>];
|
|
||||||
if (updateStrategy) {
|
|
||||||
await updateStrategy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
const arrayOfPreSetQueryData = Array.isArray(preSetQueryData)
|
||||||
|
? preSetQueryData
|
||||||
|
: [{ ...preSetQueryData, responseRoute: socketResponse.route }];
|
||||||
|
|
||||||
|
for (const item of arrayOfPreSetQueryData) {
|
||||||
|
const { responseRoute, requestRoute, callback } = item!;
|
||||||
|
const requestPayload: undefined | BusterSocketRequest = requestRoute
|
||||||
|
? ({ route: requestRoute, payload: variables } as BusterSocketRequest)
|
||||||
|
: undefined;
|
||||||
|
const presetQueryKey = createQueryKey({ route: responseRoute! }, requestPayload);
|
||||||
|
await queryClient.setQueryData(presetQueryKey, (prev: any) => callback(prev, variables));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const mutationFn = useMemoizedFn(async (variables: TVariables) => {
|
const mutationFn = useMemoizedFn(async (variables: TVariables) => {
|
||||||
const request = {
|
const request = {
|
||||||
|
@ -176,33 +91,7 @@ export const useSocketQueryMutation = <
|
||||||
} as BusterSocketRequest;
|
} as BusterSocketRequest;
|
||||||
|
|
||||||
const queryKey = createQueryKey(socketResponse, request);
|
const queryKey = createQueryKey(socketResponse, request);
|
||||||
const arrayOfPreSetQueryData = Array.isArray(preSetQueryData)
|
await handlePreSetQueryData(variables);
|
||||||
? preSetQueryData
|
|
||||||
: preSetQueryData
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
...preSetQueryData,
|
|
||||||
responseRoute: socketResponse.route
|
|
||||||
}
|
|
||||||
]
|
|
||||||
: [];
|
|
||||||
|
|
||||||
if (preSetQueryData && arrayOfPreSetQueryData.filter(Boolean).length > 0) {
|
|
||||||
if (options?.awaitPrefetchQueryData) {
|
|
||||||
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const item of arrayOfPreSetQueryData) {
|
|
||||||
const { responseRoute, requestRoute, callback } = item!;
|
|
||||||
const requestPayload: undefined | BusterSocketRequest = requestRoute
|
|
||||||
? ({ route: requestRoute, payload: request.payload } as BusterSocketRequest)
|
|
||||||
: undefined;
|
|
||||||
const presetQueryKey = createQueryKey({ route: responseRoute! }, requestPayload);
|
|
||||||
await queryClient.setQueryData(presetQueryKey, (prev: any) => {
|
|
||||||
return callback(prev, variables);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await busterSocket.emitAndOnce({
|
const response = await busterSocket.emitAndOnce({
|
||||||
emitEvent: request,
|
emitEvent: request,
|
||||||
|
@ -216,7 +105,12 @@ export const useSocketQueryMutation = <
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response !== undefined) {
|
if (response !== undefined) {
|
||||||
await updateQueryData(queryKey, response as InferBusterSocketResponseData<TRoute>);
|
await executeQueryDataStrategy(
|
||||||
|
queryClient,
|
||||||
|
queryKey as unknown[],
|
||||||
|
response as InferBusterSocketResponseData<TRoute>,
|
||||||
|
queryDataStrategy
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response as InferBusterSocketResponseData<TRoute>;
|
return response as InferBusterSocketResponseData<TRoute>;
|
||||||
|
@ -227,66 +121,3 @@ export const useSocketQueryMutation = <
|
||||||
mutationFn
|
mutationFn
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const Example = () => {
|
|
||||||
// Example: Favorites mutation with multiple preSetQueryData updates
|
|
||||||
const { mutate } = useSocketQueryMutation(
|
|
||||||
{ route: '/users/favorites/post' },
|
|
||||||
{ route: '/users/favorites/post:createFavorite' },
|
|
||||||
{
|
|
||||||
preSetQueryData: [
|
|
||||||
{
|
|
||||||
responseRoute: '/users/favorites/list:listFavorites',
|
|
||||||
callback: (data, variables) => {
|
|
||||||
const favorites = Array.isArray(data) ? data : [];
|
|
||||||
return [variables, ...favorites];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
responseRoute: '/users/favorites/post:createFavorite',
|
|
||||||
callback: (_: unknown, variables: BusterUserFavorite) => {
|
|
||||||
return [variables];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
mutate({
|
|
||||||
id: 'some-asset-id',
|
|
||||||
asset_type: ShareAssetType.DASHBOARD,
|
|
||||||
name: 'some-title'
|
|
||||||
});
|
|
||||||
|
|
||||||
const { mutate: mutate2 } = useSocketQueryMutation(
|
|
||||||
{ route: '/dashboards/delete' },
|
|
||||||
{ route: '/dashboards/delete:deleteDashboard' },
|
|
||||||
{
|
|
||||||
preSetQueryData: [
|
|
||||||
{
|
|
||||||
responseRoute: '/chats/list:getChatsList',
|
|
||||||
callback: (data, variables) => {
|
|
||||||
data[0].id;
|
|
||||||
return [...(data || [])];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const { mutate: mutate3 } = useSocketQueryMutation(
|
|
||||||
{ route: '/dashboards/delete' },
|
|
||||||
{ route: '/chats/get:getChat' },
|
|
||||||
{
|
|
||||||
preSetQueryData: {
|
|
||||||
// responseRoute: '/chats/list:getChatsList',
|
|
||||||
callback: (data, variables) => {
|
|
||||||
data.id;
|
|
||||||
return { ...data };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in New Issue