This commit is contained in:
Nate Kelley 2025-02-13 10:47:02 -07:00
parent f32bbf0a75
commit 98892fdc5a
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
10 changed files with 161 additions and 14 deletions

View File

@ -2,7 +2,6 @@
description: Rules for the buster_rest API directory
globs: src/api/buster_rest/**/*
---
# Buster REST API Rules
- Follow RESTful design principles

View File

@ -14,7 +14,8 @@ export enum ChatsResponses {
'/chats/post:generatingTitle' = '/chats/post:generatingTitle',
'/chats/post:generatingResponseMessage' = '/chats/post:generatingResponseMessage',
'/chats/post:generatingReasoningMessage' = '/chats/post:generatingReasoningMessage',
'/chats/post:complete' = '/chats/post:complete'
'/chats/post:complete' = '/chats/post:complete',
'/chats/delete:deleteChat' = '/chats/delete:deleteChat'
}
export type ChatList_getChatsList = {
@ -42,6 +43,12 @@ export type Chat_unsubscribe = {
onError?: (d: unknown | RustApiError) => void;
};
export type Chat_deleteChat = {
route: '/chats/delete:deleteChat';
callback: (d: { id: string }[]) => void;
onError?: (d: unknown | RustApiError) => void;
};
/***** CHAT PROGRESS EVENTS START ******/
export type ChatPost_initializeChat = {
@ -84,4 +91,5 @@ export type ChatResponseTypes =
| ChatPost_generatingTitle
| ChatPost_generatingResponseMessage
| ChatPost_generatingReasoningMessage
| ChatPost_complete;
| ChatPost_complete
| Chat_deleteChat;

View File

@ -5,7 +5,7 @@ import React, { PropsWithChildren } from 'react';
import { BusterWebSocketProvider } from './BusterWebSocket';
import { SupabaseContextProvider } from './Supabase/SupabaseContextProvider';
import { UseSupabaseContextType } from './Supabase/useSupabaseContext';
import { BusterReactQueryProvider } from './BusterApi/BusterReactQueryAndApi';
import { BusterReactQueryProvider } from './BusterReactQuery/BusterReactQueryAndApi';
import { useMount } from 'ahooks';
import { DatasetProviders } from './Datasets';
import { AppHotKeysProvider } from './AppHotKeys';

View File

@ -1,11 +1,12 @@
import { BusterSocketRequest, BusterSocketResponseRoute } from '@/api/buster_socket';
import { BusterSocketResponseConfig } from './types';
import { BusterSocketResponseConfig, InferBusterSocketResponseData } from './types';
import { QueryKey } from '@tanstack/react-query';
export const createQueryKey: <TRoute extends BusterSocketResponseRoute>(
socketResponse: BusterSocketResponseConfig<TRoute>,
socketResponse: BusterSocketResponseConfig<TRoute>['route'],
callbackResult: InferBusterSocketResponseData<TRoute>,
socketRequest?: BusterSocketRequest
) => QueryKey = (socketResponse, socketRequest) => {
if (socketRequest) return [socketResponse.route, socketRequest.route, socketRequest.payload];
return [socketResponse.route];
) => QueryKey = (socketResponse, callbackResult, socketRequest) => {
if (socketRequest) return [socketResponse, socketRequest.route, socketRequest.payload];
return [socketResponse];
};

View File

@ -18,15 +18,17 @@ import { useMemo } from 'react';
export const useSockeQueryOn = <TRoute extends BusterSocketResponseRoute, TError = unknown>(
socketResponse: BusterSocketResponseConfig<TRoute>,
options?: Partial<UseQueryOptions<InferBusterSocketResponseData<TRoute>, TError>>
options?: {
queryKey?: QueryKey;
}
): UseBusterSocketQueryResult<InferBusterSocketResponseData<TRoute>, TError> => {
const busterSocket = useBusterWebSocket();
const queryClient = useQueryClient();
const queryKey = useMemo(
() => options?.queryKey || createQueryKey(socketResponse),
[options?.queryKey, socketResponse?.route]
);
// const queryKey = useMemo(
// () => options?.queryKey || createQueryKey(socketResponse),
// [options?.queryKey, socketResponse?.route]
// );
useMount(() => {
busterSocket.on({

View File

@ -0,0 +1,56 @@
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';
const chatsGetChat = (chatId: string) =>
queryOptions({
queryKey: ['chats', 'get', chatId] as const,
queryFn: () => {
return Promise.resolve({ id: chatId } as BusterChat);
},
staleTime: 10 * 1000
});
const chatsGetList = (filters?: ChatListEmitPayload) =>
queryOptions({
queryKey: ['chats', 'list', filters] as const,
queryFn: () => {
return Promise.resolve([] as BusterChatListItem[]);
}
});
const deleteChat = (chatId: string) =>
queryOptions({
queryKey: ['chats', 'get', chatId] as const,
queryFn: () => {
return [chatId];
}
});
export const queryOptionsConfig = {
'/chats/get:getChat': chatsGetChat,
'/chats/list:getChatsList': chatsGetList,
'/chats/delete:deleteChat': deleteChat
};
const ExampleComponent = () => {
const queryClient = useQueryClient();
const options = queryOptionsConfig['/chats/get:getChat']!('123');
const queryKey = options.queryKey;
const data = queryClient.getQueryData(queryKey);
const { data: data2 } = useQuery(options);
queryClient.setQueryData(queryKey, (d) => {
return d;
});
const options2 = queryOptionsConfig['/chats/delete:deleteChat']!('123');
const queryKey2 = options2.queryKey;
const data3 = queryClient.getQueryData(queryKey2);
//
};

View File

@ -0,0 +1,16 @@
import type { BusterSocketResponse, BusterSocketResponseRoute } from '@/api/buster_socket';
export type BusterSocketResponseConfig<TRoute extends BusterSocketResponseRoute> = {
route: TRoute;
onError?: (d: unknown) => void;
};
export type BusterSocketResponseConfigRoute =
BusterSocketResponseConfig<BusterSocketResponseRoute>['route'];
export type InferBusterSocketResponseData<TRoute extends BusterSocketResponseRoute> = Extract<
BusterSocketResponse,
{ route: TRoute }
>['callback'] extends (d: infer D) => void
? D
: never;

View File

@ -0,0 +1,65 @@
'use client';
import {
QueryKey,
useQuery,
useQueryClient,
UseQueryOptions,
UseQueryResult
} from '@tanstack/react-query';
import type {
BusterSocketRequest,
BusterSocketResponse,
BusterSocketResponseRoute
} from '@/api/buster_socket';
import { useBusterWebSocket } from '@/context/BusterWebSocket';
import { useEffect } from 'react';
import {
BusterSocketResponseConfig,
BusterSocketResponseConfigRoute,
InferBusterSocketResponseData
} from './types';
import { useMount } from 'ahooks';
import { queryOptionsConfig } from './queryKeyConfig';
export const useSocketQueryOn = <
TRoute extends BusterSocketResponseRoute,
TError = unknown,
TData = InferBusterSocketResponseData<TRoute>,
TQueryKey extends QueryKey = QueryKey
>(
socketResponse: TRoute,
options: UseQueryOptions<InferBusterSocketResponseData<TRoute>, TError, TData, TQueryKey>,
callback?: (d: InferBusterSocketResponseData<TRoute>) => TData
): UseQueryResult<TData, TError> => {
const busterSocket = useBusterWebSocket();
const queryClient = useQueryClient();
const queryKey = options.queryKey;
useMount(() => {
busterSocket.on({
route: socketResponse,
callback: (d: unknown) => {
const transformer = callback || ((d: InferBusterSocketResponseData<TRoute>) => d as TData);
const transformedData: TData = transformer(d as InferBusterSocketResponseData<TRoute>);
queryClient.setQueryData<TData>(queryKey, transformedData);
}
} as BusterSocketResponse);
});
return useQuery({
...options,
enabled: false
});
};
const ExampleComponent = () => {
const options = queryOptionsConfig['/chats/get:getChat']('123');
const { data } = useSocketQueryOn('/chats/get:getChat', options);
const options2 = queryOptionsConfig['/chats/list:getChatsList']();
const { data: data2 } = useSocketQueryOn('/chats/list:getChatsList', options2);
const options3 = queryOptionsConfig['/chats/delete:deleteChat']('123');
const { data: data3 } = useSocketQueryOn('/chats/delete:deleteChat', options3);
};