This commit is contained in:
Nate Kelley 2025-02-12 14:45:34 -07:00
parent e91e0d9f86
commit 04a884da50
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
5 changed files with 87 additions and 50 deletions

View File

@ -1,7 +1,7 @@
import { useBusterWebSocket } from '../BusterWebSocket';
import { useMemoizedFn } from 'ahooks';
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 { useHotkeys } from 'react-hotkeys-hook';
@ -19,6 +19,13 @@ export const useFavoriteProvider = () => {
{ route: '/users/favorites/list:listFavorites' }
);
const { mutate: addItemToFavorite } = useSocketQueryMutation(
{ route: '/users/favorites/post' },
{
route: '/users/favorites/post:createFavorite'
}
);
const setUserFavorites = useMemoizedFn(
(updater: (v: BusterUserFavorite[]) => BusterUserFavorite[]) => {
queryClient.setQueryData(favoritesQueryKey, (v: BusterUserFavorite[] | undefined) => {
@ -27,7 +34,7 @@ export const useFavoriteProvider = () => {
}
);
const addItemToFavorite = useMemoizedFn(
const aXddItemToFavorite = useMemoizedFn(
async ({
id,
asset_type,

View File

@ -4,5 +4,6 @@ import { BusterSocketResponseConfig } from './types';
export * from './useSocketQueryEmitAndOnce';
export * from './useSocketQueryEmitOn';
export * from './useSocketQueryOn';
export * from './useSocketQueryMutation';
export { createQueryKey, type BusterSocketResponseConfig };

View File

@ -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';
/**
@ -20,3 +24,17 @@ export type BusterSocketResponseConfig<TRoute extends BusterSocketResponseRoute>
};
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'];

View File

@ -35,7 +35,6 @@ export const useSocketQueryEmitOn = <TRoute extends BusterSocketResponseRoute, T
>
): UseBusterSocketQueryResult<InferBusterSocketResponseData<TRoute>, TError> => {
const busterSocket = useBusterWebSocket();
const queryClient = useQueryClient();
const queryKey = createQueryKey(socketResponse, socketRequest);

View File

@ -6,7 +6,13 @@ import {
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query';
import { useBusterWebSocket } from '@/context/BusterWebSocket';
import { useMemoizedFn } from 'ahooks';
import { BusterSocketResponseConfig, InferBusterSocketResponseData } from './types';
import {
BusterSocketResponseConfig,
InferBusterSocketResponseData,
InferBusterSocketRequestPayload,
BusterSocketRequestConfig,
BusterSocketRequestRoute
} from './types';
import { ShareAssetType } from '@/api/asset_interfaces';
import { createQueryKey } from './helpers';
@ -25,11 +31,12 @@ import { createQueryKey } from './helpers';
* @returns A React Query mutation result for handling socket requests
*/
export const useSocketQueryMutation = <
TRequestRoute extends BusterSocketRequestRoute,
TRoute extends BusterSocketResponseRoute,
TVariables = void,
TError = unknown
TError = unknown,
TVariables = InferBusterSocketRequestPayload<TRequestRoute>
>(
socketRequest: BusterSocketRequest,
socketRequest: BusterSocketRequestConfig<TRequestRoute>,
socketResponse: BusterSocketResponseConfig<TRoute> & {
callback?: (d: unknown) => InferBusterSocketResponseData<TRoute>;
},
@ -49,7 +56,11 @@ export const useSocketQueryMutation = <
const { preSetQueryData, queryDataStrategy = 'ignore', ...options } = optionsProps || {};
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) {
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>>(queryKey, (d) => {
@ -58,7 +69,7 @@ export const useSocketQueryMutation = <
}
const res = await busterSocket.emitAndOnce({
emitEvent: socketRequest,
emitEvent: compiledSocketRequest,
responseEvent: {
...socketResponse,
callback: (d: unknown) => {
@ -70,6 +81,7 @@ export const useSocketQueryMutation = <
} as BusterSocketResponse
});
if (res !== undefined) {
if (queryDataStrategy === 'replace') {
await queryClient.setQueryData<InferBusterSocketResponseData<TRoute>>(queryKey, () => {
return res as InferBusterSocketResponseData<TRoute>;
@ -99,32 +111,32 @@ export const useSocketQueryMutation = <
}
);
}
}
return res as InferBusterSocketResponseData<TRoute>;
});
return useMutation<InferBusterSocketResponseData<TRoute>, TError, TVariables>({
return useMutation({
...options,
mutationFn
mutationFn: mutationFn
});
};
const Example = () => {
const { mutate, data, ...rest } = useSocketQueryMutation(
// Example 1: Favorites mutation
const { mutate, data } = useSocketQueryMutation(
{
route: '/users/favorites/post',
payload: {
id: '1',
asset_type: ShareAssetType.DASHBOARD
}
route: '/users/favorites/post'
},
{
route: '/users/favorites/post:createFavorite'
},
{
preSetQueryData: (d) => {
return d || [];
}
}
);
mutate({
id: 'some-asset-id',
asset_type: ShareAssetType.DASHBOARD
});
return null;
};