import { InfiniteData, useQueryClient } from '@tanstack/react-query' import { ApiCollection, ApiResource, ConversationResource } from '../types' import { deleteRecordInPagesData, updateRecordInPagesData, updateAllRecordsInPagesData, updateOrCreateRecordInPagesData, } from '../utils' import { ConversationRequestArgs, getConversationsRequestArgs } from '../utils/request/conversation' import { useApiClient } from './use_api_client' import { getRequestQueryKey } from './use_suspense_api' type QueryData = InfiniteData> export function useConversationsCache(args?: Partial) { const apiClient = useApiClient() const queryClient = useQueryClient() const conversationsRequestArgs = getConversationsRequestArgs(args) const conversationQueryKey = getRequestQueryKey(conversationsRequestArgs) const fetchConversation = async (id: number) => { if (!id) return const { data: argsData } = conversationsRequestArgs const { data } = await apiClient.chat.get>({ url: `/me/conversations/${id}`, data: { fields: argsData.fields, include: argsData.include, }, }) return data } const updateOrCreate = async (conversation: ConversationResource) => { if (!conversation.id) return queryClient.setQueryData(conversationQueryKey, prev => updateOrCreateRecordInPagesData({ data: prev, record: conversation, processRecord: (record, current) => { return { ...current, ...record } }, }) ) } const updateOnly = async (conversation: ConversationResource) => { if (!conversation.id) return queryClient.setQueryData(conversationQueryKey, prev => updateRecordInPagesData({ data: prev, record: conversation, processRecord: (record, current) => { return { ...current, ...record } }, }) ) } const updateAll = async (update: Partial) => { queryClient.setQueryData(conversationQueryKey, prev => updateAllRecordsInPagesData({ data: prev, processRecord: record => ({ ...record, ...update }), }) ) } const fetchAndUpdate = async ({ id }: { id: number }) => { const conversation: ConversationResource = await fetchConversation(id).catch(c => c) if (!conversation.id) return updateOnly(conversation) } const fetchAndUpdateOrCreate = async ({ id }: { id: number }) => { const conversation: ConversationResource = await fetchConversation(id).catch(c => c) if (!conversation.id) return updateOrCreate(conversation) } const handleConversationDestroy = ({ id }: { id: number }) => { if (!id) return queryClient.setQueryData(conversationQueryKey, prev => deleteRecordInPagesData({ data: prev, record: { id }, }) ) } return { create: updateOrCreate, destroy: handleConversationDestroy, fetchCreate: fetchAndUpdateOrCreate, fetchUpdate: fetchAndUpdate, invalidate: () => queryClient.invalidateQueries({ queryKey: conversationQueryKey }), update: updateOrCreate, updateAll, } }