UNPKG

@trpc/tanstack-react-query

Version:

TanStack React Query Integration for tRPC

299 lines (283 loc) 8.15 kB
import type { DataTag, DefinedInitialDataInfiniteOptions, QueryClient, QueryFunction, SkipToken, UndefinedInitialDataInfiniteOptions, UnusedSkipTokenInfiniteOptions, } from '@tanstack/react-query'; import { infiniteQueryOptions, skipToken } from '@tanstack/react-query'; import type { TRPCClientErrorLike, TRPCUntypedClient } from '@trpc/client'; import type { DistributiveOmit } from '@trpc/server/unstable-core-do-not-import'; import type { ExtractCursorType, FeatureFlags, ResolverDef, TRPCInfiniteData, TRPCQueryBaseOptions, TRPCQueryKey, TRPCQueryOptionsResult, } from './types'; import { createTRPCOptionsResult, getClientArgs } from './utils'; type ReservedOptions = | 'queryKey' | 'queryFn' | 'queryHashFn' | 'queryHash' | 'initialPageParam'; interface UndefinedTRPCInfiniteQueryOptionsIn< TInput, TQueryFnData, TData, TError, TFeatureFlags extends FeatureFlags, > extends DistributiveOmit< UndefinedInitialDataInfiniteOptions< TQueryFnData, TError, TRPCInfiniteData<TInput, TData>, TRPCQueryKey<TFeatureFlags['keyPrefix']>, NonNullable<ExtractCursorType<TInput>> | null >, ReservedOptions >, TRPCQueryBaseOptions { initialCursor?: NonNullable<ExtractCursorType<TInput>> | null; } interface UndefinedTRPCInfiniteQueryOptionsOut< TInput, TQueryFnData, TData, TError, TFeatureFlags extends FeatureFlags, > extends DistributiveOmit< UndefinedInitialDataInfiniteOptions< TQueryFnData, TError, TRPCInfiniteData<TInput, TData>, TRPCQueryKey<TFeatureFlags['keyPrefix']>, NonNullable<ExtractCursorType<TInput>> | null >, 'initialPageParam' >, TRPCQueryOptionsResult { queryKey: DataTag< TRPCQueryKey<TFeatureFlags['keyPrefix']>, TRPCInfiniteData<TInput, TData>, TError >; initialPageParam: NonNullable<ExtractCursorType<TInput>> | null; } interface DefinedTRPCInfiniteQueryOptionsIn< TInput, TQueryFnData, TData, TError, TFeatureFlags extends FeatureFlags, > extends DistributiveOmit< DefinedInitialDataInfiniteOptions< TQueryFnData, TError, TRPCInfiniteData<TInput, TData>, TRPCQueryKey<TFeatureFlags['keyPrefix']>, NonNullable<ExtractCursorType<TInput>> | null >, ReservedOptions >, TRPCQueryBaseOptions { initialCursor?: NonNullable<ExtractCursorType<TInput>> | null; } interface DefinedTRPCInfiniteQueryOptionsOut< TInput, TQueryFnData, TData, TError, TFeatureFlags extends FeatureFlags, > extends DistributiveOmit< DefinedInitialDataInfiniteOptions< TQueryFnData, TError, TRPCInfiniteData<TInput, TData>, TRPCQueryKey<TFeatureFlags['keyPrefix']>, NonNullable<ExtractCursorType<TInput>> | null >, 'initialPageParam' >, TRPCQueryOptionsResult { queryKey: DataTag< TRPCQueryKey<TFeatureFlags['keyPrefix']>, TRPCInfiniteData<TInput, TData>, TError >; initialPageParam: NonNullable<ExtractCursorType<TInput>> | null; } interface UnusedSkipTokenTRPCInfiniteQueryOptionsIn< TInput, TQueryFnData, TData, TError, TFeatureFlags extends FeatureFlags, > extends DistributiveOmit< UnusedSkipTokenInfiniteOptions< TQueryFnData, TError, TRPCInfiniteData<TInput, TData>, TRPCQueryKey<TFeatureFlags['keyPrefix']>, NonNullable<ExtractCursorType<TInput>> | null >, ReservedOptions >, TRPCQueryBaseOptions { initialCursor?: NonNullable<ExtractCursorType<TInput>> | null; } interface UnusedSkipTokenTRPCInfiniteQueryOptionsOut< TInput, TQueryFnData, TData, TError, TFeatureFlags extends FeatureFlags, > extends DistributiveOmit< UnusedSkipTokenInfiniteOptions< TQueryFnData, TError, TRPCInfiniteData<TInput, TData>, TRPCQueryKey<TFeatureFlags['keyPrefix']>, NonNullable<ExtractCursorType<TInput>> | null >, 'initialPageParam' >, TRPCQueryOptionsResult { queryKey: DataTag< TRPCQueryKey<TFeatureFlags['keyPrefix']>, TRPCInfiniteData<TInput, TData>, TError >; initialPageParam: NonNullable<ExtractCursorType<TInput>> | null; } export interface TRPCInfiniteQueryOptions<TDef extends ResolverDef> { <TQueryFnData extends TDef['output'], TData = TQueryFnData>( input: TDef['input'] | SkipToken, opts: DefinedTRPCInfiniteQueryOptionsIn< TDef['input'], TQueryFnData, TData, TRPCClientErrorLike<{ transformer: TDef['transformer']; errorShape: TDef['errorShape']; }>, TDef['featureFlags'] >, ): DefinedTRPCInfiniteQueryOptionsOut< TDef['input'], TQueryFnData, TData, TRPCClientErrorLike<{ transformer: TDef['transformer']; errorShape: TDef['errorShape']; }>, TDef['featureFlags'] >; <TQueryFnData extends TDef['output'], TData = TQueryFnData>( input: TDef['input'], opts: UnusedSkipTokenTRPCInfiniteQueryOptionsIn< TDef['input'], TQueryFnData, TData, TRPCClientErrorLike<{ transformer: TDef['transformer']; errorShape: TDef['errorShape']; }>, TDef['featureFlags'] >, ): UnusedSkipTokenTRPCInfiniteQueryOptionsOut< TDef['input'], TQueryFnData, TData, TRPCClientErrorLike<{ transformer: TDef['transformer']; errorShape: TDef['errorShape']; }>, TDef['featureFlags'] >; <TQueryFnData extends TDef['output'], TData = TQueryFnData>( input: TDef['input'] | SkipToken, opts: UndefinedTRPCInfiniteQueryOptionsIn< TDef['input'], TQueryFnData, TData, TRPCClientErrorLike<{ transformer: TDef['transformer']; errorShape: TDef['errorShape']; }>, TDef['featureFlags'] >, ): UndefinedTRPCInfiniteQueryOptionsOut< TDef['input'], TQueryFnData, TData, TRPCClientErrorLike<{ transformer: TDef['transformer']; errorShape: TDef['errorShape']; }>, TDef['featureFlags'] >; } type AnyTRPCInfiniteQueryOptionsIn<TFeatureFlags extends FeatureFlags> = | DefinedTRPCInfiniteQueryOptionsIn<any, any, any, any, TFeatureFlags> | UnusedSkipTokenTRPCInfiniteQueryOptionsIn<any, any, any, any, TFeatureFlags> | UndefinedTRPCInfiniteQueryOptionsIn<any, any, any, any, TFeatureFlags>; type AnyTRPCInfiniteQueryOptionsOut<TFeatureFlags extends FeatureFlags> = | DefinedTRPCInfiniteQueryOptionsOut<any, any, any, any, TFeatureFlags> | UnusedSkipTokenTRPCInfiniteQueryOptionsOut< any, any, any, any, TFeatureFlags > | UndefinedTRPCInfiniteQueryOptionsOut<any, any, any, any, TFeatureFlags>; export function trpcInfiniteQueryOptions< TFeatureFlags extends FeatureFlags, >(args: { input: unknown; query: typeof TRPCUntypedClient.prototype.query; queryClient: QueryClient | (() => QueryClient); path: string[]; queryKey: TRPCQueryKey<TFeatureFlags['keyPrefix']>; opts: AnyTRPCInfiniteQueryOptionsIn<TFeatureFlags> | undefined; }): AnyTRPCInfiniteQueryOptionsOut<TFeatureFlags> { const { input, query, path, queryKey, opts } = args; const inputIsSkipToken = input === skipToken; const queryFn: QueryFunction< unknown, TRPCQueryKey<TFeatureFlags['keyPrefix']>, unknown > = async (queryFnContext) => { const actualOpts = { ...opts, trpc: { ...opts?.trpc, ...(opts?.trpc?.abortOnUnmount ? { signal: queryFnContext.signal } : { signal: null }), }, }; const result = await query( ...getClientArgs(queryKey, actualOpts, { direction: queryFnContext.direction, pageParam: queryFnContext.pageParam, }), ); return result; }; return Object.assign( infiniteQueryOptions({ ...(opts ?? ({} as AnyTRPCInfiniteQueryOptionsIn<TFeatureFlags>)), queryKey, queryFn: inputIsSkipToken ? skipToken : queryFn, initialPageParam: opts?.initialCursor ?? (input as any)?.cursor, }), { trpc: createTRPCOptionsResult({ path }) }, ); }