From ba80aaf41dfcc4998041d667c67d34c6ae398521 Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Thu, 13 Feb 2025 12:59:50 -0700 Subject: [PATCH] request queries --- .../asset_interfaces/chat/chatQueryKeys.ts} | 17 ++- .../chat/chatRequiredInterfaces.ts | 2 - .../collection/collectionQueryKeys.ts | 11 ++ web/src/api/asset_interfaces/index.ts | 1 + web/src/api/asset_interfaces/queryKeys.ts | 7 + web/src/api/buster_rest/chats/requests.ts | 6 +- .../api/buster_socket/chats/chatRequests.ts | 21 +-- web/src/api/buster_socket_query/index.ts | 3 + .../buster_socket_query}/types.ts | 0 .../buster_socket_query}/useSocketEmitOn.tsx | 0 .../useSocketQueryEmitAndOnce.tsx | 0 .../useSocketQueryMutation.tsx} | 4 +- .../buster_socket_query}/useSocketQueryOn.tsx | 0 web/src/api/index.ts | 1 - web/src/api/request_interfaces/chats/index.ts | 1 + .../chats/interfaces.ts | 2 +- .../useCollectionCreate.ts | 25 ++-- web/src/hooks/useSocketQuery/config.ts | 0 web/src/hooks/useSocketQuery/helpers.ts | 12 -- web/src/hooks/useSocketQuery/index.ts | 9 -- web/src/hooks/useSocketQuery/mutationTypes.ts | 59 --------- .../useSocketQuery/queryDataStrategies.ts | 48 ------- web/src/hooks/useSocketQuery/types.ts | 40 ------ .../useSocketQueryEmitAndOnce.tsx | 57 -------- .../useSocketQuery/useSocketQueryEmitOn.tsx | 66 ---------- .../useSocketQuery/useSocketQueryMutation.tsx | 123 ------------------ .../hooks/useSocketQuery/useSocketQueryOn.tsx | 48 ------- 27 files changed, 54 insertions(+), 509 deletions(-) rename web/src/{hooks/useSocketQueryNew/queryKeyConfig.ts => api/asset_interfaces/chat/chatQueryKeys.ts} (61%) delete mode 100644 web/src/api/asset_interfaces/chat/chatRequiredInterfaces.ts create mode 100644 web/src/api/asset_interfaces/collection/collectionQueryKeys.ts create mode 100644 web/src/api/asset_interfaces/queryKeys.ts create mode 100644 web/src/api/buster_socket_query/index.ts rename web/src/{hooks/useSocketQueryNew => api/buster_socket_query}/types.ts (100%) rename web/src/{hooks/useSocketQueryNew => api/buster_socket_query}/useSocketEmitOn.tsx (100%) rename web/src/{hooks/useSocketQueryNew => api/buster_socket_query}/useSocketQueryEmitAndOnce.tsx (100%) rename web/src/{hooks/useSocketQueryNew/useSocketMutation.tsx => api/buster_socket_query/useSocketQueryMutation.tsx} (97%) rename web/src/{hooks/useSocketQueryNew => api/buster_socket_query}/useSocketQueryOn.tsx (100%) delete mode 100644 web/src/api/index.ts create mode 100644 web/src/api/request_interfaces/chats/index.ts rename web/src/api/{buster_rest => request_interfaces}/chats/interfaces.ts (90%) delete mode 100644 web/src/hooks/useSocketQuery/config.ts delete mode 100644 web/src/hooks/useSocketQuery/helpers.ts delete mode 100644 web/src/hooks/useSocketQuery/index.ts delete mode 100644 web/src/hooks/useSocketQuery/mutationTypes.ts delete mode 100644 web/src/hooks/useSocketQuery/queryDataStrategies.ts delete mode 100644 web/src/hooks/useSocketQuery/types.ts delete mode 100644 web/src/hooks/useSocketQuery/useSocketQueryEmitAndOnce.tsx delete mode 100644 web/src/hooks/useSocketQuery/useSocketQueryEmitOn.tsx delete mode 100644 web/src/hooks/useSocketQuery/useSocketQueryMutation.tsx delete mode 100644 web/src/hooks/useSocketQuery/useSocketQueryOn.tsx diff --git a/web/src/hooks/useSocketQueryNew/queryKeyConfig.ts b/web/src/api/asset_interfaces/chat/chatQueryKeys.ts similarity index 61% rename from web/src/hooks/useSocketQueryNew/queryKeyConfig.ts rename to web/src/api/asset_interfaces/chat/chatQueryKeys.ts index 42167d8a5..a0e09a80b 100644 --- a/web/src/hooks/useSocketQueryNew/queryKeyConfig.ts +++ b/web/src/api/asset_interfaces/chat/chatQueryKeys.ts @@ -1,7 +1,6 @@ -import { useQuery, useQueryClient } from '@tanstack/react-query'; -import { BusterChat, BusterChatListItem } from '@/api/asset_interfaces/chat'; -import { queryOptions } from '@tanstack/react-query'; -import { ChatListEmitPayload } from '@/api/buster_socket/chats'; +import { queryOptions, useQuery, useQueryClient } from '@tanstack/react-query'; +import type { BusterChat, BusterChatListItem } from './chatInterfaces'; +import type { GetChatListParams } from '@/api/request_interfaces/chats'; const chatsGetChat = (chatId: string) => queryOptions({ @@ -9,19 +8,19 @@ const chatsGetChat = (chatId: string) => staleTime: 10 * 1000 }); -const chatsGetList = (filters?: ChatListEmitPayload) => +const chatsGetList = (filters?: GetChatListParams) => queryOptions({ queryKey: ['chats', 'list', filters] as const }); -const deleteChat = (chatId: string) => { +const deleteChat = () => { const queryKey = ['chats', 'list'] as const; return queryOptions({ queryKey }); }; -export const queryOptionsConfig = { +export const chatQueryKeys = { '/chats/get:getChat': chatsGetChat, '/chats/list:getChatsList': chatsGetList, '/chats/delete:deleteChat': deleteChat @@ -29,7 +28,7 @@ export const queryOptionsConfig = { const ExampleComponent = () => { const queryClient = useQueryClient(); - const options = queryOptionsConfig['/chats/get:getChat']!('123'); + const options = chatQueryKeys['/chats/get:getChat']!('123'); const queryKey = options.queryKey; const data = queryClient.getQueryData(queryKey); @@ -40,7 +39,7 @@ const ExampleComponent = () => { return d; }); - const options2 = queryOptionsConfig['/chats/delete:deleteChat']!('123'); + const options2 = chatQueryKeys['/chats/delete:deleteChat']!(); const queryKey2 = options2.queryKey; const data3 = queryClient.getQueryData(queryKey2); diff --git a/web/src/api/asset_interfaces/chat/chatRequiredInterfaces.ts b/web/src/api/asset_interfaces/chat/chatRequiredInterfaces.ts deleted file mode 100644 index eda3403d6..000000000 --- a/web/src/api/asset_interfaces/chat/chatRequiredInterfaces.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { BusterChat } from './chatInterfaces'; -import type { BusterChatMessage } from './chatMessageInterfaces'; diff --git a/web/src/api/asset_interfaces/collection/collectionQueryKeys.ts b/web/src/api/asset_interfaces/collection/collectionQueryKeys.ts new file mode 100644 index 000000000..7df89b359 --- /dev/null +++ b/web/src/api/asset_interfaces/collection/collectionQueryKeys.ts @@ -0,0 +1,11 @@ +import { queryOptions, useQuery, useQueryClient } from '@tanstack/react-query'; +import { BusterCollectionListItem } from './interfaces'; + +const collectionsGetList = (filters?: GetCollectionListParams) => + queryOptions({ + queryKey: ['collections', 'list', filters] as const + }); + +export const collectionQueryKeys = { + '/collections/list:getCollectionsList': collectionsGetList +}; diff --git a/web/src/api/asset_interfaces/index.ts b/web/src/api/asset_interfaces/index.ts index 95497ba9c..ca5e86136 100644 --- a/web/src/api/asset_interfaces/index.ts +++ b/web/src/api/asset_interfaces/index.ts @@ -14,3 +14,4 @@ export * from './sql'; export * from './permission_groups'; export * from './dataset_groups'; export * from './api_keys'; +export * from './queryKeys'; diff --git a/web/src/api/asset_interfaces/queryKeys.ts b/web/src/api/asset_interfaces/queryKeys.ts new file mode 100644 index 000000000..9a15817d2 --- /dev/null +++ b/web/src/api/asset_interfaces/queryKeys.ts @@ -0,0 +1,7 @@ +import { chatQueryKeys } from './chat/chatQueryKeys'; +import { collectionQueryKeys } from './collection/collectionQueryKeys'; + +export const queryKeys = { + ...chatQueryKeys, + ...collectionQueryKeys +}; diff --git a/web/src/api/buster_rest/chats/requests.ts b/web/src/api/buster_rest/chats/requests.ts index e8998c2ec..52286cfc4 100644 --- a/web/src/api/buster_rest/chats/requests.ts +++ b/web/src/api/buster_rest/chats/requests.ts @@ -1,12 +1,12 @@ import { mainApi } from '../instances'; import { serverFetch } from '../../createServerInstance'; import type { BusterChatListItem, BusterChat } from '@/api/asset_interfaces'; -import type { ChatListParams, GetChatParams } from './interfaces'; +import type { GetChatListParams, GetChatParams } from '../../request_interfaces/chats'; const CHATS_BASE = '/chats'; // Client-side fetch version -export const getListChats = async (params?: ChatListParams): Promise => { +export const getListChats = async (params?: GetChatListParams): Promise => { const { page_token = 0, page_size = 1000, admin_view = false } = params || {}; return mainApi .get(`${CHATS_BASE}/list`, { @@ -17,7 +17,7 @@ export const getListChats = async (params?: ChatListParams): Promise => { const { page_token = 0, page_size = 1000, admin_view = false } = params || {}; return await serverFetch(`${CHATS_BASE}/list`, { diff --git a/web/src/api/buster_socket/chats/chatRequests.ts b/web/src/api/buster_socket/chats/chatRequests.ts index 36997da30..00409b618 100644 --- a/web/src/api/buster_socket/chats/chatRequests.ts +++ b/web/src/api/buster_socket/chats/chatRequests.ts @@ -1,3 +1,4 @@ +import { GetChatParams, GetChatListParams } from '../../request_interfaces/chats'; import type { BusterSocketRequestBase } from '../base_interfaces'; /** @@ -45,13 +46,7 @@ export type ChatStopChat = BusterSocketRequestBase< * @interface ChatGetChat * @extends BusterSocketRequestBase */ -export type ChatGetChat = BusterSocketRequestBase< - '/chats/get', - { - /** The unique identifier of the chat to retrieve */ - id: string; - } ->; +export type ChatGetChat = BusterSocketRequestBase<'/chats/get', GetChatParams>; /** * Request type for unsubscribing from real-time updates of a specific chat. @@ -71,17 +66,7 @@ export type ChatUnsubscribeFromChat = BusterSocketRequestBase< * @interface ChatListEmitPayload * @extends BusterSocketRequestBase */ -export type ChatListEmitPayload = BusterSocketRequestBase< - '/chats/list', - { - /** Pagination token indicating the page number */ - page_token: number; - /** Number of chat items to return per page */ - page_size: number; - /** When true, shows all organization chats (admin only). When false, shows only user's chats */ - admin_view: boolean; - } ->; +export type ChatListEmitPayload = BusterSocketRequestBase<'/chats/list', GetChatListParams>; /** * Request type for deleting a specific chat. diff --git a/web/src/api/buster_socket_query/index.ts b/web/src/api/buster_socket_query/index.ts new file mode 100644 index 000000000..34a0cf655 --- /dev/null +++ b/web/src/api/buster_socket_query/index.ts @@ -0,0 +1,3 @@ +export * from './useSocketQueryMutation'; +export * from './useSocketQueryOn'; +export * from './useSocketQueryEmitAndOnce'; diff --git a/web/src/hooks/useSocketQueryNew/types.ts b/web/src/api/buster_socket_query/types.ts similarity index 100% rename from web/src/hooks/useSocketQueryNew/types.ts rename to web/src/api/buster_socket_query/types.ts diff --git a/web/src/hooks/useSocketQueryNew/useSocketEmitOn.tsx b/web/src/api/buster_socket_query/useSocketEmitOn.tsx similarity index 100% rename from web/src/hooks/useSocketQueryNew/useSocketEmitOn.tsx rename to web/src/api/buster_socket_query/useSocketEmitOn.tsx diff --git a/web/src/hooks/useSocketQueryNew/useSocketQueryEmitAndOnce.tsx b/web/src/api/buster_socket_query/useSocketQueryEmitAndOnce.tsx similarity index 100% rename from web/src/hooks/useSocketQueryNew/useSocketQueryEmitAndOnce.tsx rename to web/src/api/buster_socket_query/useSocketQueryEmitAndOnce.tsx diff --git a/web/src/hooks/useSocketQueryNew/useSocketMutation.tsx b/web/src/api/buster_socket_query/useSocketQueryMutation.tsx similarity index 97% rename from web/src/hooks/useSocketQueryNew/useSocketMutation.tsx rename to web/src/api/buster_socket_query/useSocketQueryMutation.tsx index 9e63e857e..1aeb45397 100644 --- a/web/src/hooks/useSocketQueryNew/useSocketMutation.tsx +++ b/web/src/api/buster_socket_query/useSocketQueryMutation.tsx @@ -25,7 +25,7 @@ import type { } from './types'; import type { BusterChatListItem } from '@/api/asset_interfaces/chat'; -export function useSocketMutation< +export function useSocketQueryMutation< TRequestRoute extends BusterSocketRequestRoute, TRoute extends BusterSocketResponseRoute, TError = unknown, @@ -92,7 +92,7 @@ const ExampleComponent = () => { const data = queryClient.getQueryData(options.queryKey); data?.[0].created_by_avatar; - const { mutate } = useSocketMutation< + const { mutate } = useSocketQueryMutation< '/chats/delete', '/chats/delete:deleteChat', unknown, diff --git a/web/src/hooks/useSocketQueryNew/useSocketQueryOn.tsx b/web/src/api/buster_socket_query/useSocketQueryOn.tsx similarity index 100% rename from web/src/hooks/useSocketQueryNew/useSocketQueryOn.tsx rename to web/src/api/buster_socket_query/useSocketQueryOn.tsx diff --git a/web/src/api/index.ts b/web/src/api/index.ts deleted file mode 100644 index 263956b46..000000000 --- a/web/src/api/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './buster_rest'; diff --git a/web/src/api/request_interfaces/chats/index.ts b/web/src/api/request_interfaces/chats/index.ts new file mode 100644 index 000000000..957860982 --- /dev/null +++ b/web/src/api/request_interfaces/chats/index.ts @@ -0,0 +1 @@ +export * from './interfaces'; diff --git a/web/src/api/buster_rest/chats/interfaces.ts b/web/src/api/request_interfaces/chats/interfaces.ts similarity index 90% rename from web/src/api/buster_rest/chats/interfaces.ts rename to web/src/api/request_interfaces/chats/interfaces.ts index b7da2d88e..57282e986 100644 --- a/web/src/api/buster_rest/chats/interfaces.ts +++ b/web/src/api/request_interfaces/chats/interfaces.ts @@ -1,4 +1,4 @@ -export interface ChatListParams { +export interface GetChatListParams { /** Pagination token indicating the page number */ page_token: number; /** Number of chat items to return per page */ diff --git a/web/src/context/Collections/CollectionIndividualProvider/useCollectionCreate.ts b/web/src/context/Collections/CollectionIndividualProvider/useCollectionCreate.ts index d2afd6219..ad5e7f8e6 100644 --- a/web/src/context/Collections/CollectionIndividualProvider/useCollectionCreate.ts +++ b/web/src/context/Collections/CollectionIndividualProvider/useCollectionCreate.ts @@ -1,7 +1,8 @@ import { useBusterNotifications } from '@/context/BusterNotifications'; -import { useSocketQueryMutation } from '@/hooks'; +import { useSocketQueryMutation } from '@/api/buster_socket_query'; import { timeout } from '@/utils'; import { useMemoizedFn } from 'ahooks'; +import { queryKeys } from '@/api/asset_interfaces'; export const useCollectionCreate = () => { const { openConfirmModal } = useBusterNotifications(); @@ -30,16 +31,18 @@ export const useCollectionCreate = () => { useSocketQueryMutation( { route: '/collections/delete' }, { route: '/collections/delete:deleteCollections' }, - { - preSetQueryData: [ - { - responseRoute: '/collections/list:listCollections', - callback: (data, variables) => { - return data?.filter((collection) => !variables.ids.includes(collection.id)) || []; - } - } - ] - } + queryKeys + + // { + // preSetQueryData: [ + // { + // responseRoute: '/collections/list:listCollections', + // callback: (data, variables) => { + // return data?.filter((collection) => !variables.ids.includes(collection.id)) || []; + // } + // } + // ] + // } ); const deleteCollection = useMemoizedFn(async (id: string | string[], useConfirmModal = true) => { diff --git a/web/src/hooks/useSocketQuery/config.ts b/web/src/hooks/useSocketQuery/config.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/web/src/hooks/useSocketQuery/helpers.ts b/web/src/hooks/useSocketQuery/helpers.ts deleted file mode 100644 index 890ddea59..000000000 --- a/web/src/hooks/useSocketQuery/helpers.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { BusterSocketRequest, BusterSocketResponseRoute } from '@/api/buster_socket'; -import { BusterSocketResponseConfig, InferBusterSocketResponseData } from './types'; -import { QueryKey } from '@tanstack/react-query'; - -export const createQueryKey: ( - socketResponse: BusterSocketResponseConfig['route'], - callbackResult: InferBusterSocketResponseData, - socketRequest?: BusterSocketRequest -) => QueryKey = (socketResponse, callbackResult, socketRequest) => { - if (socketRequest) return [socketResponse, socketRequest.route, socketRequest.payload]; - return [socketResponse]; -}; diff --git a/web/src/hooks/useSocketQuery/index.ts b/web/src/hooks/useSocketQuery/index.ts deleted file mode 100644 index 6c90e103b..000000000 --- a/web/src/hooks/useSocketQuery/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { createQueryKey } from './helpers'; -import { BusterSocketResponseConfig } from './types'; - -export * from './useSocketQueryEmitAndOnce'; -export * from './useSocketQueryEmitOn'; -export * from './useSocketQueryOn'; -export * from './useSocketQueryMutation'; - -export { createQueryKey, type BusterSocketResponseConfig }; diff --git a/web/src/hooks/useSocketQuery/mutationTypes.ts b/web/src/hooks/useSocketQuery/mutationTypes.ts deleted file mode 100644 index 34b0cd336..000000000 --- a/web/src/hooks/useSocketQuery/mutationTypes.ts +++ /dev/null @@ -1,59 +0,0 @@ -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 = { - [Route in BusterSocketResponseRoute]: { - responseRoute: Route; - requestRoute?: BusterSocketRequestRoute; - callback: ( - data: InferBusterSocketResponseData, - variables: TVariables - ) => InferBusterSocketResponseData; - }; -}[BusterSocketResponseRoute]; - -export type SinglePreSetQueryDataItem = { - requestRoute?: BusterSocketRequestRoute; - callback: ( - data: InferBusterSocketResponseData, - variables: TVariables - ) => InferBusterSocketResponseData; -}; - -export type SocketQueryMutationOptions< - TRoute extends BusterSocketResponseRoute, - TError, - TVariables -> = Omit< - UseMutationOptions, 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> - | SinglePreSetQueryDataItem; - - /** - * 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; -}; diff --git a/web/src/hooks/useSocketQuery/queryDataStrategies.ts b/web/src/hooks/useSocketQuery/queryDataStrategies.ts deleted file mode 100644 index 732a75de5..000000000 --- a/web/src/hooks/useSocketQuery/queryDataStrategies.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { QueryClient } from '@tanstack/react-query'; -import { QueryDataStrategy } from './mutationTypes'; -import { BusterSocketResponseRoute } from '@/api/buster_socket'; -import { InferBusterSocketResponseData } from './types'; - -export const executeQueryDataStrategy = async ( - queryClient: QueryClient, - queryKey: unknown[], - data: InferBusterSocketResponseData, - strategy: QueryDataStrategy -) => { - if (strategy === 'ignore') return; - - const strategies: Record, () => Promise> = { - replace: async () => { - await queryClient.setQueryData(queryKey, data); - }, - append: async () => { - await queryClient.setQueryData[]>(queryKey, (prev) => [ - ...(Array.isArray(prev) ? prev : []), - data - ]); - }, - prepend: async () => { - await queryClient.setQueryData[]>(queryKey, (prev) => [ - data, - ...(Array.isArray(prev) ? prev : []) - ]); - }, - merge: async () => { - if (typeof data === 'object' && data !== null && 'id' in data) { - await queryClient.setQueryData>>( - queryKey, - (prev) => ({ - ...(prev || {}), - [(data as { id: string }).id]: data - }) - ); - } - } - }; - - const updateStrategy = strategies[strategy as Exclude]; - - if (updateStrategy) { - await updateStrategy(); - } -}; diff --git a/web/src/hooks/useSocketQuery/types.ts b/web/src/hooks/useSocketQuery/types.ts deleted file mode 100644 index a8f9eca71..000000000 --- a/web/src/hooks/useSocketQuery/types.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { - BusterSocketRequest, - BusterSocketResponse, - BusterSocketResponseRoute -} from '@/api/buster_socket'; -import { UseQueryResult } from '@tanstack/react-query'; - -/** - * Infers the response data type from a BusterSocket route - */ -export type InferBusterSocketResponseData = Extract< - BusterSocketResponse, - { route: TRoute } ->['callback'] extends (d: infer D) => void - ? D - : never; - -/** - * Socket response configuration with optional error handler - */ -export type BusterSocketResponseConfig = { - route: TRoute; - onError?: (d: unknown) => void; -}; - -export type UseBusterSocketQueryResult = UseQueryResult; - -/** - * Extract the route type from BusterSocketRequest - */ -export type BusterSocketRequestRoute = BusterSocketRequest['route']; - -export type BusterSocketRequestConfig = { - route: TRoute; -}; - -export type InferBusterSocketRequestPayload = Extract< - BusterSocketRequest, - { route: TRoute } ->['payload']; diff --git a/web/src/hooks/useSocketQuery/useSocketQueryEmitAndOnce.tsx b/web/src/hooks/useSocketQuery/useSocketQueryEmitAndOnce.tsx deleted file mode 100644 index 5e750af9e..000000000 --- a/web/src/hooks/useSocketQuery/useSocketQueryEmitAndOnce.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { QueryKey, UseQueryOptions } from '@tanstack/react-query'; -import type { - BusterSocketRequest, - BusterSocketResponse, - BusterSocketResponseRoute -} from '@/api/buster_socket'; -import { useBusterWebSocket } from '@/context/BusterWebSocket'; -import type { - UseBusterSocketQueryResult, - InferBusterSocketResponseData, - BusterSocketResponseConfig -} from './types'; -import { useCreateReactQuery } from '@/api/createReactQuery'; -import { createQueryKey } from './helpers'; -import { useMemo } from 'react'; - -export function useSocketQueryEmitAndOnce< - TRoute extends BusterSocketResponseRoute, - TError = unknown ->( - socketRequest: BusterSocketRequest, - socketResponse: BusterSocketResponseConfig, - options?: Partial, TError>, 'queryFn'>> -): UseBusterSocketQueryResult, TError> { - const busterSocket = useBusterWebSocket(); - - const queryKey = useMemo( - () => options?.queryKey || createQueryKey(socketResponse, socketRequest), - [options?.queryKey, socketResponse?.route, socketRequest?.route] - ); - - const queryFn = async (): Promise> => { - try { - const result = await busterSocket.emitAndOnce({ - emitEvent: socketRequest, - responseEvent: { - route: socketResponse.route, - onError: socketResponse.onError, - callback: (d: unknown) => d - } as BusterSocketResponse - }); - - return result as InferBusterSocketResponseData; - } catch (error) { - throw error; - } - }; - - return useCreateReactQuery, TError>({ - queryKey, - queryFn, - isUseSession: false, - refetchOnMount: false, - refetchOnWindowFocus: false, - options - }); -} diff --git a/web/src/hooks/useSocketQuery/useSocketQueryEmitOn.tsx b/web/src/hooks/useSocketQuery/useSocketQueryEmitOn.tsx deleted file mode 100644 index a3e459963..000000000 --- a/web/src/hooks/useSocketQuery/useSocketQueryEmitOn.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { - BusterSocketRequest, - BusterSocketResponse, - BusterSocketResponseRoute -} from '@/api/buster_socket'; -import { useQueryClient, UseQueryOptions } from '@tanstack/react-query'; -import { - BusterSocketResponseConfig, - InferBusterSocketResponseData, - UseBusterSocketQueryResult -} from './types'; -import { useSockeQueryOn } from './useSocketQueryOn'; -import { useBusterWebSocket } from '@/context/BusterWebSocket'; -import { useMemoizedFn, useMount } from 'ahooks'; -import { createQueryKey } from './helpers'; -import { useEffect } from 'react'; - -/** - * A hook that emits a socket request on mount and listens for responses. - * - * @template TRoute - The type of socket response route - * @template TError - The type of error that can occur - * - * @param socketRequest - The socket request to emit - * @param socketResponse - Configuration for the socket response including route and error handler - * @param options - Additional options for the React Query hook - * - * @returns A React Query result containing the response data and status - */ -export const useSocketQueryEmitOn = ( - socketRequest: BusterSocketRequest, - socketResponse: BusterSocketResponseConfig, - optionsProps?: Omit< - UseQueryOptions, TError>, - 'queryKey' | 'queryFn' - > & { enabled?: boolean | string } -): UseBusterSocketQueryResult, TError> => { - const busterSocket = useBusterWebSocket(); - const { enabled = true, ...options } = optionsProps || {}; - - const queryKey = createQueryKey(socketResponse, socketRequest); - - const queryFn = useMemoizedFn(async () => { - const res = await busterSocket.emitAndOnce({ - emitEvent: socketRequest, - responseEvent: { - ...socketResponse, - callback: (d: unknown) => d - } as BusterSocketResponse - }); - - return res; - }) as () => Promise>; - - useEffect(() => { - if (enabled) { - queryFn(); - } - }, [enabled]); - - return useSockeQueryOn(socketResponse, { - ...options, - queryKey, - queryFn - }); -}; diff --git a/web/src/hooks/useSocketQuery/useSocketQueryMutation.tsx b/web/src/hooks/useSocketQuery/useSocketQueryMutation.tsx deleted file mode 100644 index 5bbe86ffe..000000000 --- a/web/src/hooks/useSocketQuery/useSocketQueryMutation.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import { - BusterSocketRequest, - BusterSocketResponse, - BusterSocketResponseRoute -} from '@/api/buster_socket'; -import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { useBusterWebSocket } from '@/context/BusterWebSocket'; -import { useMemoizedFn } from 'ahooks'; -import { - BusterSocketResponseConfig, - InferBusterSocketResponseData, - InferBusterSocketRequestPayload, - BusterSocketRequestConfig, - BusterSocketRequestRoute -} from './types'; -import { SocketQueryMutationOptions } from './mutationTypes'; -import { executeQueryDataStrategy } from './queryDataStrategies'; -import { createQueryKey } from './helpers'; - -/** - * 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 TRequestRoute - The socket request route type - * @template TRoute - The socket response route type - * @template TError - The error type that can occur - * @template TVariables - The variables type passed to the mutation function - * - * @param socketRequest - The base socket request configuration - * @param socketResponse - The socket response configuration with optional error handler - * @param options - Additional options for configuring the mutation behavior - * - * @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 = < - TRequestRoute extends BusterSocketRequestRoute, - TRoute extends BusterSocketResponseRoute, - TError = unknown, - TVariables = InferBusterSocketRequestPayload ->( - socketRequest: BusterSocketRequestConfig, - socketResponse: BusterSocketResponseConfig & { - callback?: (data: unknown) => InferBusterSocketResponseData; - }, - options?: SocketQueryMutationOptions -) => { - const busterSocket = useBusterWebSocket(); - const queryClient = useQueryClient(); - const { preSetQueryData, queryDataStrategy = 'ignore', ...mutationOptions } = options || {}; - - const handlePreSetQueryData = useMemoizedFn(async (variables: TVariables) => { - if (!preSetQueryData) return; - - if (options?.awaitPrefetchQueryData) { - await new Promise((resolve) => requestAnimationFrame(resolve)); - } - - 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 request = { - ...socketRequest, - payload: variables - } as BusterSocketRequest; - - const queryKey = createQueryKey(socketResponse, request); - await handlePreSetQueryData(variables); - - const response = await busterSocket.emitAndOnce({ - emitEvent: request, - responseEvent: { - ...socketResponse, - callback: (data: unknown) => { - socketResponse.callback?.(data); - return data; - } - } as BusterSocketResponse - }); - - if (response !== undefined) { - await executeQueryDataStrategy( - queryClient, - queryKey as unknown[], - response as InferBusterSocketResponseData, - queryDataStrategy - ); - } - - return response as InferBusterSocketResponseData; - }); - - return useMutation({ - ...mutationOptions, - mutationFn - }); -}; diff --git a/web/src/hooks/useSocketQuery/useSocketQueryOn.tsx b/web/src/hooks/useSocketQuery/useSocketQueryOn.tsx deleted file mode 100644 index 9062cec92..000000000 --- a/web/src/hooks/useSocketQuery/useSocketQueryOn.tsx +++ /dev/null @@ -1,48 +0,0 @@ -'use client'; - -import { QueryKey, useQuery, useQueryClient, UseQueryOptions } from '@tanstack/react-query'; -import type { - BusterSocketRequest, - BusterSocketResponse, - BusterSocketResponseRoute -} from '@/api/buster_socket'; -import { useBusterWebSocket } from '@/context/BusterWebSocket'; -import type { - UseBusterSocketQueryResult, - InferBusterSocketResponseData, - BusterSocketResponseConfig -} from './types'; -import { useMount } from 'ahooks'; -import { createQueryKey } from './helpers'; -import { useMemo } from 'react'; - -export const useSockeQueryOn = ( - socketResponse: BusterSocketResponseConfig, - options?: { - queryKey?: QueryKey; - } -): UseBusterSocketQueryResult, TError> => { - const busterSocket = useBusterWebSocket(); - const queryClient = useQueryClient(); - - // const queryKey = useMemo( - // () => options?.queryKey || createQueryKey(socketResponse), - // [options?.queryKey, socketResponse?.route] - // ); - - useMount(() => { - busterSocket.on({ - route: socketResponse.route, - onError: socketResponse.onError, - callback: (d: unknown) => { - queryClient.setQueryData(queryKey, d as InferBusterSocketResponseData); - } - } as BusterSocketResponse); - }); - - return useQuery({ - queryKey, - ...options, - enabled: false //must be disabled to prevent automatic fetching - }); -};