import { InfiniteData, keepPreviousData, Query, useInfiniteQuery, useQuery, } from '@tanstack/react-query' import { useContext } from 'react' import { ChatContext } from '../contexts/chat_context' import { ApiCollection, ApiResource, ResourceObject } from '../types' import { GetRequest, RequestData } from '../utils/client' import { ResponseError, throwResponseError } from '../utils/response_error' import { getNextPageParamFromMeta } from './paginator_meta' import { App, useApiClient } from './use_api_client' import { getRequestQueryKey, RequestQueryKey } from './use_suspense_api' interface ApiGetOptions extends GetRequest { app?: App } export type ApiGetQueryOptions = { staleTime?: number gcTime?: number enabled?: boolean throwOnError?: boolean | ((error: ResponseError, query: Query) => boolean) placeholderData?: typeof keepPreviousData } export const useApiGet = ( args: ApiGetOptions, opts?: ApiGetQueryOptions ) => { type Resource = ApiResource const { session } = useContext(ChatContext) const apiClient = useApiClient() const enabled = !!session.token?.access_token && (opts?.enabled ?? true) const { data, ...query } = useQuery({ queryKey: getRequestQueryKey(args), queryFn: ({ queryKey }) => { const [url, d, headers, app = 'chat'] = queryKey as RequestQueryKey return (apiClient[app].get({ url, data: d, headers }) as Promise).catch( throwResponseError ) }, ...opts, enabled, }) return { ...data, ...query } } export const useApiPaginator = ( args: ApiGetOptions, opts?: ApiGetQueryOptions ) => { const { session } = useContext(ChatContext) const apiClient = useApiClient() const enabled = !!session.token?.access_token && (opts?.enabled ?? true) const query = useInfiniteQuery< ApiCollection, ResponseError, InfiniteData>, any, Partial | undefined >({ queryKey: getRequestQueryKey(args), queryFn: ({ pageParam }) => { const pageParmWhere = pageParam?.where || {} const argsWhere = args.data.where || {} const where = { ...argsWhere, ...pageParmWhere } const app = args.app || 'chat' const offset = pageParam?.offset || args.data.offset const data = { ...args.data, where, offset } return apiClient[app].get>({ url: args.url, data }).catch(throwResponseError) }, initialPageParam: {} as Partial, getNextPageParam: lastPage => getNextPageParamFromMeta(lastPage.meta?.next), ...(opts || {}), enabled, }) const data: T[] = query.data?.pages?.flatMap(page => page.data) || [] return { ...query, data } }