{"version":3,"file":"useSuspenseQueries.cjs","names":["useQueries","skipToken","defaultThrowOnError"],"sources":["../../src/useSuspenseQueries.ts"],"sourcesContent":["'use client'\nimport { skipToken } from '@tanstack/query-core'\nimport { useQueries } from './useQueries'\nimport { defaultThrowOnError } from './suspense'\nimport type { UseSuspenseQueryOptions, UseSuspenseQueryResult } from './types'\nimport type {\n  DefaultError,\n  QueryClient,\n  QueryFunction,\n  ThrowOnError,\n} from '@tanstack/query-core'\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\n// Widen the type of the symbol to enable type inference even if skipToken is not immutable.\ntype SkipTokenForUseQueries = symbol\n\ntype GetUseSuspenseQueryOptions<T> =\n  // Part 1: responsible for applying explicit type parameter to function arguments, if object { queryFnData: TQueryFnData, error: TError, data: TData }\n  T extends {\n    queryFnData: infer TQueryFnData\n    error?: infer TError\n    data: infer TData\n  }\n    ? UseSuspenseQueryOptions<TQueryFnData, TError, TData>\n    : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n      ? UseSuspenseQueryOptions<TQueryFnData, TError>\n      : T extends { data: infer TData; error?: infer TError }\n        ? UseSuspenseQueryOptions<unknown, TError, TData>\n        : // Part 2: responsible for applying explicit type parameter to function arguments, if tuple [TQueryFnData, TError, TData]\n          T extends [infer TQueryFnData, infer TError, infer TData]\n          ? UseSuspenseQueryOptions<TQueryFnData, TError, TData>\n          : T extends [infer TQueryFnData, infer TError]\n            ? UseSuspenseQueryOptions<TQueryFnData, TError>\n            : T extends [infer TQueryFnData]\n              ? UseSuspenseQueryOptions<TQueryFnData>\n              : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n                T extends {\n                    queryFn?:\n                      | QueryFunction<infer TQueryFnData, infer TQueryKey>\n                      | SkipTokenForUseQueries\n                    select?: (data: any) => infer TData\n                    throwOnError?: ThrowOnError<any, infer TError, any, any>\n                  }\n                ? UseSuspenseQueryOptions<\n                    TQueryFnData,\n                    TError,\n                    TData,\n                    TQueryKey\n                  >\n                : T extends {\n                      queryFn?:\n                        | QueryFunction<infer TQueryFnData, infer TQueryKey>\n                        | SkipTokenForUseQueries\n                      throwOnError?: ThrowOnError<any, infer TError, any, any>\n                    }\n                  ? UseSuspenseQueryOptions<\n                      TQueryFnData,\n                      TError,\n                      TQueryFnData,\n                      TQueryKey\n                    >\n                  : // Fallback\n                    UseSuspenseQueryOptions\n\ntype GetUseSuspenseQueryResult<T> =\n  // Part 1: responsible for mapping explicit type parameter to function result, if object\n  T extends { queryFnData: any; error?: infer TError; data: infer TData }\n    ? UseSuspenseQueryResult<TData, TError>\n    : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n      ? UseSuspenseQueryResult<TQueryFnData, TError>\n      : T extends { data: infer TData; error?: infer TError }\n        ? UseSuspenseQueryResult<TData, TError>\n        : // Part 2: responsible for mapping explicit type parameter to function result, if tuple\n          T extends [any, infer TError, infer TData]\n          ? UseSuspenseQueryResult<TData, TError>\n          : T extends [infer TQueryFnData, infer TError]\n            ? UseSuspenseQueryResult<TQueryFnData, TError>\n            : T extends [infer TQueryFnData]\n              ? UseSuspenseQueryResult<TQueryFnData>\n              : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n                T extends {\n                    queryFn?:\n                      | QueryFunction<infer TQueryFnData, any>\n                      | SkipTokenForUseQueries\n                    select?: (data: any) => infer TData\n                    throwOnError?: ThrowOnError<any, infer TError, any, any>\n                  }\n                ? UseSuspenseQueryResult<\n                    unknown extends TData ? TQueryFnData : TData,\n                    unknown extends TError ? DefaultError : TError\n                  >\n                : T extends {\n                      queryFn?:\n                        | QueryFunction<infer TQueryFnData, any>\n                        | SkipTokenForUseQueries\n                      throwOnError?: ThrowOnError<any, infer TError, any, any>\n                    }\n                  ? UseSuspenseQueryResult<\n                      TQueryFnData,\n                      unknown extends TError ? DefaultError : TError\n                    >\n                  : // Fallback\n                    UseSuspenseQueryResult\n\n/**\n * The `queries` array accepted by `useSuspenseQueries`. Recursively unwraps each tuple element so every\n * entry's `queryFn`/`select` are inferred individually, up to 20 elements — past that, a tuple falls back to\n * a single homogeneous {@link UseSuspenseQueryOptions} type.\n *\n * An opaque array (e.g. `unknown[]`) is returned as-is; a non-tuple array whose element type structurally\n * matches a query options object is mapped per-element instead, still inferring each entry individually; any\n * other non-tuple array — one whose element type doesn't match the expected options shape — falls back to\n * that same homogeneous options type too.\n *\n * @template T - The type of the `queries` array as written at the call site.\n * @template TResults - The internal accumulator that this type builds during recursion. It is not meant\n * to be set explicitly.\n * @template TDepth - The internal recursion-depth counter, checked against the 20-element limit. It is not\n * meant to be set explicitly.\n */\nexport type SuspenseQueriesOptions<\n  T extends Array<any>,\n  TResults extends Array<any> = [],\n  TDepth extends ReadonlyArray<number> = [],\n> = TDepth['length'] extends MAXIMUM_DEPTH\n  ? Array<UseSuspenseQueryOptions>\n  : T extends []\n    ? []\n    : T extends [infer Head]\n      ? [...TResults, GetUseSuspenseQueryOptions<Head>]\n      : T extends [infer Head, ...infer Tails]\n        ? SuspenseQueriesOptions<\n            [...Tails],\n            [...TResults, GetUseSuspenseQueryOptions<Head>],\n            [...TDepth, 1]\n          >\n        : Array<unknown> extends T\n          ? T\n          : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogeneous type!\n            // use this to infer the param types in the case of Array.map() argument\n            T extends Array<\n                UseSuspenseQueryOptions<\n                  infer TQueryFnData,\n                  infer TError,\n                  infer TData,\n                  infer TQueryKey\n                >\n              >\n            ? Array<\n                UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>\n              >\n            : // Fallback\n              Array<UseSuspenseQueryOptions>\n\n/**\n * The result type returned by `useSuspenseQueries`, when no `combine` is provided. Mirrors\n * {@link SuspenseQueriesOptions}: each tuple element's result type is inferred individually, up to 20 elements.\n * A non-tuple array is mapped per-element instead, still inferring each entry individually; only past 20\n * elements does this fall back to a single homogeneous {@link UseSuspenseQueryResult} type.\n *\n * @template T - The type of the `queries` array, as inferred by {@link SuspenseQueriesOptions}.\n * @template TResults - The internal accumulator that this type builds during recursion. It is not meant\n * to be set explicitly.\n * @template TDepth - The internal recursion-depth counter, checked against the 20-element limit. It is not\n * meant to be set explicitly.\n */\nexport type SuspenseQueriesResults<\n  T extends Array<any>,\n  TResults extends Array<any> = [],\n  TDepth extends ReadonlyArray<number> = [],\n> = TDepth['length'] extends MAXIMUM_DEPTH\n  ? Array<UseSuspenseQueryResult>\n  : T extends []\n    ? []\n    : T extends [infer Head]\n      ? [...TResults, GetUseSuspenseQueryResult<Head>]\n      : T extends [infer Head, ...infer Tails]\n        ? SuspenseQueriesResults<\n            [...Tails],\n            [...TResults, GetUseSuspenseQueryResult<Head>],\n            [...TDepth, 1]\n          >\n        : { [K in keyof T]: GetUseSuspenseQueryResult<T[K]> }\n\n/**\n * The options for `useSuspenseQueries` are the same as for `useQueries`, except that the top-level `subscribed`\n * option isn't supported, and each `query` can't have `throwOnError`, `enabled`, or `placeholderData`.\n *\n * @param options - The `queries` array to run in Suspense, and an optional `combine` function.\n * @param queryClient - Use this to provide a custom `QueryClient`. Otherwise, the one from the nearest context\n * will be used.\n * @returns The same structure as `useQueries`, except that for each `query`, `data` is guaranteed to be\n * defined, `isPlaceholderData` is missing, and `status` is either `success` or `error` (with the derived\n * flags set accordingly).\n *\n * Caveat: the component will only re-mount after all queries have finished loading. Hence, if a query has gone\n * stale in the time it took for all the queries to complete, it will be fetched again at re-mount. To avoid\n * this, make sure to set a high enough `staleTime`. Cancellation does not work.\n *\n * @example\n * The query error is thrown if a fetch fails and no cached data exists yet, so an error boundary is\n * required around `<Suspense>`. A failed background refetch instead continues to render the cached data.\n * Use {@link QueryErrorResetBoundary} to let the user retry after such an error:\n * ```tsx\n * import { Suspense } from 'react'\n * import { ErrorBoundary } from 'react-error-boundary'\n * import {\n *   QueryErrorResetBoundary,\n *   useSuspenseQueries,\n * } from '@tanstack/react-query'\n *\n * function Posts({ ids }: { ids: Array<number> }) {\n *   // Every result is guaranteed to be defined — no per-query `isPending` check needed.\n *   const postQueries = useSuspenseQueries({\n *     queries: ids.map((id) => ({\n *       queryKey: ['post', id],\n *       queryFn: () => fetchPost(id),\n *     })),\n *   })\n *\n *   return (\n *     <ul>\n *       {postQueries.map((query) => (\n *         <li key={query.data.id}>{query.data.title}</li>\n *       ))}\n *     </ul>\n *   )\n * }\n *\n * function App() {\n *   return (\n *     <QueryErrorResetBoundary>\n *       {({ reset }) => (\n *         <ErrorBoundary\n *           onReset={reset}\n *           fallbackRender={({ resetErrorBoundary }) => (\n *             <div>\n *               There was an error!\n *               <button onClick={() => resetErrorBoundary()}>Try again</button>\n *             </div>\n *           )}\n *         >\n *           <Suspense fallback={<h1>Loading posts...</h1>}>\n *             <Posts ids={[1, 2, 3]} />\n *           </Suspense>\n *         </ErrorBoundary>\n *       )}\n *     </QueryErrorResetBoundary>\n *   )\n * }\n * ```\n *\n * @example\n * Several different queries — use `useSuspenseQueries` instead of multiple `useSuspenseQuery` calls, so\n * they fetch in parallel rather than suspending one after another:\n * ```tsx\n * import { Suspense } from 'react'\n * import { ErrorBoundary } from 'react-error-boundary'\n * import {\n *   QueryErrorResetBoundary,\n *   useSuspenseQueries,\n * } from '@tanstack/react-query'\n *\n * function Dashboard() {\n *   const [usersQuery, teamsQuery, projectsQuery] = useSuspenseQueries({\n *     queries: [\n *       { queryKey: ['users'], queryFn: fetchUsers },\n *       { queryKey: ['teams'], queryFn: fetchTeams },\n *       { queryKey: ['projects'], queryFn: fetchProjects },\n *     ],\n *   })\n *\n *   return (\n *     <div>\n *       <UserList users={usersQuery.data} />\n *       <TeamList teams={teamsQuery.data} />\n *       <ProjectList projects={projectsQuery.data} />\n *     </div>\n *   )\n * }\n *\n * function App() {\n *   return (\n *     <QueryErrorResetBoundary>\n *       {({ reset }) => (\n *         <ErrorBoundary\n *           onReset={reset}\n *           fallbackRender={({ resetErrorBoundary }) => (\n *             <div>\n *               There was an error!\n *               <button onClick={() => resetErrorBoundary()}>Try again</button>\n *             </div>\n *           )}\n *         >\n *           <Suspense fallback={<h1>Loading dashboard...</h1>}>\n *             <Dashboard />\n *           </Suspense>\n *         </ErrorBoundary>\n *       )}\n *     </QueryErrorResetBoundary>\n *   )\n * }\n * ```\n *\n * @example\n * `combine`s the results into a single boolean, so `Refresh` only re-renders when that boolean changes,\n * not on every individual query update. This overload is the only one that accepts `combine`:\n * ```tsx\n * import { Suspense } from 'react'\n * import { ErrorBoundary } from 'react-error-boundary'\n * import {\n *   QueryErrorResetBoundary,\n *   useSuspenseQueries,\n * } from '@tanstack/react-query'\n *\n * function Refresh() {\n *   const anyFetching = useSuspenseQueries({\n *     queries: [\n *       { queryKey: ['users'], queryFn: fetchUsers },\n *       { queryKey: ['teams'], queryFn: fetchTeams },\n *     ],\n *     combine: (results) => results.some((result) => result.isFetching),\n *   })\n *\n *   return anyFetching ? <span>Refreshing…</span> : null\n * }\n *\n * function App() {\n *   return (\n *     <QueryErrorResetBoundary>\n *       {({ reset }) => (\n *         <ErrorBoundary\n *           onReset={reset}\n *           fallbackRender={({ resetErrorBoundary }) => (\n *             <div>\n *               There was an error!\n *               <button onClick={() => resetErrorBoundary()}>Try again</button>\n *             </div>\n *           )}\n *         >\n *           <Suspense fallback={<h1>Loading dashboard...</h1>}>\n *             <Refresh />\n *           </Suspense>\n *         </ErrorBoundary>\n *       )}\n *     </QueryErrorResetBoundary>\n *   )\n * }\n * ```\n */\nexport function useSuspenseQueries<\n  T extends Array<any>,\n  TCombinedResult = SuspenseQueriesResults<T>,\n>(\n  options: {\n    /**\n     * An array with query option objects identical to `useSuspenseQuery`.\n     */\n    queries:\n      | readonly [...SuspenseQueriesOptions<T>]\n      | readonly [...{ [K in keyof T]: GetUseSuspenseQueryOptions<T[K]> }]\n    /**\n     * Use this to combine the results of the queries into a single value. The result will be structurally\n     * shared to be as referentially stable as possible.\n     */\n    combine?: (result: SuspenseQueriesResults<T>) => TCombinedResult\n  },\n  queryClient?: QueryClient,\n): TCombinedResult\n\n/**\n * The options for `useSuspenseQueries` are the same as for `useQueries`, except that the top-level `subscribed`\n * option isn't supported, and each `query` can't have `throwOnError`, `enabled`, or `placeholderData`.\n *\n * @param options - The `queries` array to run in Suspense, and an optional `combine` function.\n * @param queryClient - Use this to provide a custom `QueryClient`. Otherwise, the one from the nearest context\n * will be used.\n * @returns The same structure as `useQueries`, except that for each `query`, `data` is guaranteed to be\n * defined, `isPlaceholderData` is missing, and `status` is either `success` or `error` (with the derived\n * flags set accordingly).\n *\n * Caveat: the component will only re-mount after all queries have finished loading. Hence, if a query has gone\n * stale in the time it took for all the queries to complete, it will be fetched again at re-mount. To avoid\n * this, make sure to set a high enough `staleTime`. Cancellation does not work.\n *\n * @example\n * The query error is thrown if a fetch fails and no cached data exists yet, so an error boundary is\n * required around `<Suspense>`. A failed background refetch instead continues to render the cached data.\n * Use {@link QueryErrorResetBoundary} to let the user retry after such an error:\n * ```tsx\n * import { Suspense } from 'react'\n * import { ErrorBoundary } from 'react-error-boundary'\n * import {\n *   QueryErrorResetBoundary,\n *   useSuspenseQueries,\n * } from '@tanstack/react-query'\n *\n * function Posts({ ids }: { ids: Array<number> }) {\n *   // Every result is guaranteed to be defined — no per-query `isPending` check needed.\n *   const postQueries = useSuspenseQueries({\n *     queries: ids.map((id) => ({\n *       queryKey: ['post', id],\n *       queryFn: () => fetchPost(id),\n *     })),\n *   })\n *\n *   return (\n *     <ul>\n *       {postQueries.map((query) => (\n *         <li key={query.data.id}>{query.data.title}</li>\n *       ))}\n *     </ul>\n *   )\n * }\n *\n * function App() {\n *   return (\n *     <QueryErrorResetBoundary>\n *       {({ reset }) => (\n *         <ErrorBoundary\n *           onReset={reset}\n *           fallbackRender={({ resetErrorBoundary }) => (\n *             <div>\n *               There was an error!\n *               <button onClick={() => resetErrorBoundary()}>Try again</button>\n *             </div>\n *           )}\n *         >\n *           <Suspense fallback={<h1>Loading posts...</h1>}>\n *             <Posts ids={[1, 2, 3]} />\n *           </Suspense>\n *         </ErrorBoundary>\n *       )}\n *     </QueryErrorResetBoundary>\n *   )\n * }\n * ```\n *\n * @example\n * Several different queries — use `useSuspenseQueries` instead of multiple `useSuspenseQuery` calls, so\n * they fetch in parallel rather than suspending one after another:\n * ```tsx\n * import { Suspense } from 'react'\n * import { ErrorBoundary } from 'react-error-boundary'\n * import {\n *   QueryErrorResetBoundary,\n *   useSuspenseQueries,\n * } from '@tanstack/react-query'\n *\n * function Dashboard() {\n *   const [usersQuery, teamsQuery, projectsQuery] = useSuspenseQueries({\n *     queries: [\n *       { queryKey: ['users'], queryFn: fetchUsers },\n *       { queryKey: ['teams'], queryFn: fetchTeams },\n *       { queryKey: ['projects'], queryFn: fetchProjects },\n *     ],\n *   })\n *\n *   return (\n *     <div>\n *       <UserList users={usersQuery.data} />\n *       <TeamList teams={teamsQuery.data} />\n *       <ProjectList projects={projectsQuery.data} />\n *     </div>\n *   )\n * }\n *\n * function App() {\n *   return (\n *     <QueryErrorResetBoundary>\n *       {({ reset }) => (\n *         <ErrorBoundary\n *           onReset={reset}\n *           fallbackRender={({ resetErrorBoundary }) => (\n *             <div>\n *               There was an error!\n *               <button onClick={() => resetErrorBoundary()}>Try again</button>\n *             </div>\n *           )}\n *         >\n *           <Suspense fallback={<h1>Loading dashboard...</h1>}>\n *             <Dashboard />\n *           </Suspense>\n *         </ErrorBoundary>\n *       )}\n *     </QueryErrorResetBoundary>\n *   )\n * }\n * ```\n */\nexport function useSuspenseQueries<\n  T extends Array<any>,\n  TCombinedResult = SuspenseQueriesResults<T>,\n>(\n  options: {\n    /**\n     * An array with query option objects identical to `useSuspenseQuery`.\n     */\n    queries: readonly [...SuspenseQueriesOptions<T>]\n    /**\n     * Use this to combine the results of the queries into a single value. The result will be structurally\n     * shared to be as referentially stable as possible.\n     */\n    combine?: (result: SuspenseQueriesResults<T>) => TCombinedResult\n  },\n  queryClient?: QueryClient,\n): TCombinedResult\n\nexport function useSuspenseQueries(options: any, queryClient?: QueryClient) {\n  return useQueries(\n    {\n      ...options,\n      queries: options.queries.map((query: any) => {\n        if (process.env.NODE_ENV !== 'production') {\n          if (query.queryFn === skipToken) {\n            console.error('skipToken is not allowed for useSuspenseQueries')\n          }\n        }\n\n        return {\n          ...query,\n          suspense: true,\n          throwOnError: defaultThrowOnError,\n          enabled: true,\n          placeholderData: undefined,\n        }\n      }),\n    },\n    queryClient,\n  )\n}\n"],"mappings":";;;;;;AA8fA,SAAgB,mBAAmB,SAAc,aAA2B;CAC1E,OAAOA,mBAAAA,WACL;EACE,GAAG;EACH,SAAS,QAAQ,QAAQ,KAAK,UAAe;GAC3C,IAAI,QAAQ,IAAI,aAAa,cACvB;QAAA,MAAM,YAAYC,qBAAAA,WACpB,QAAQ,MAAM,iDAAiD;GAAA;GAInE,OAAO;IACL,GAAG;IACH,UAAU;IACV,cAAcC,iBAAAA;IACd,SAAS;IACT,iBAAiB,KAAA;GACnB;EACF,CAAC;CACH,GACA,WACF;AACF"}