import { InfiniteData, InfiniteQuery, Query, QueryClient } from '../vanilla' import { suspenseOptions } from './suspense' import { useQueries } from './useQueries' import { UseSuspenseInfiniteQueryOptions, UseSuspenseInfiniteQueryResult, UseSuspenseQueryOptions, UseSuspenseQueryResult, } from './useSuspenseQuery' // Avoid TS depth-limit error in case of large array literal type MAXIMUM_DEPTH = 20 type GetSuspenseOptions = T extends { query: InfiniteQuery select: (data: any) => infer TData } ? UseSuspenseInfiniteQueryOptions : T extends { query: InfiniteQuery } ? UseSuspenseInfiniteQueryOptions : T extends { query: Query select: (data: any) => infer TData } ? UseSuspenseQueryOptions : T extends { query: Query } ? UseSuspenseQueryOptions : UseSuspenseQueryOptions type GetSuspenseResults = T extends { query: InfiniteQuery select: (data: any) => infer TData } ? UseSuspenseInfiniteQueryResult : T extends { query: InfiniteQuery } ? UseSuspenseInfiniteQueryResult, TError> : T extends { query: Query select: (data: any) => infer TData } ? UseSuspenseQueryResult : T extends { query: Query } ? UseSuspenseQueryResult : UseSuspenseQueryResult /** * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param */ export type SuspenseQueriesOptions< T extends any[], Result extends any[] = [], Depth extends ReadonlyArray = [] > = Depth['length'] extends MAXIMUM_DEPTH ? UseSuspenseQueryOptions[] : T extends [] ? [] : T extends [infer Head] ? [...Result, GetSuspenseOptions] : T extends [infer Head, ...infer Tail] ? SuspenseQueriesOptions< [...Tail], [...Result, GetSuspenseOptions], [...Depth, 1] > : unknown[] extends T ? T : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogenous type! // use this to infer the param types in the case of Array.map() argument T extends UseSuspenseQueryOptions< infer TFetcherData, infer TVars, infer TError >[] ? UseSuspenseQueryOptions[] : // Fallback UseSuspenseQueryOptions[] /** * QueriesResults reducer recursively maps type param to results */ export type SuspenseQueriesResults< T extends any[], Result extends any[] = [], Depth extends ReadonlyArray = [] > = Depth['length'] extends MAXIMUM_DEPTH ? UseSuspenseQueryOptions[] : T extends [] ? [] : T extends [infer Head] ? [...Result, GetSuspenseResults] : T extends [infer Head, ...infer Tail] ? SuspenseQueriesResults< [...Tail], [...Result, GetSuspenseResults], [...Depth, 1] > : T extends UseSuspenseQueryOptions< infer TFetcherData, any, infer TError, any >[] ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results UseSuspenseQueryResult[] : // Fallback UseSuspenseQueryResult[] export function useSuspenseQueries< T extends any[], TCombinedResult = SuspenseQueriesResults >( options: { queries: readonly [...SuspenseQueriesOptions] combine?: (result: SuspenseQueriesResults) => TCombinedResult }, queryClient?: QueryClient ): TCombinedResult { return useQueries( { ...options, queries: options.queries.map(query => ({ ...query, ...suspenseOptions, })), } as any, queryClient ) }