@tanstack/react-query 5.4.3 → 5.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/build/codemods/coverage/clover.xml +2 -2
  2. package/build/codemods/coverage/index.html +1 -1
  3. package/build/codemods/src/utils/index.js +8 -5
  4. package/build/codemods/src/utils/transformers/query-cache-transformer.js +10 -2
  5. package/build/codemods/src/utils/transformers/query-client-transformer.js +7 -2
  6. package/build/codemods/src/utils/transformers/use-query-like-transformer.js +10 -4
  7. package/build/codemods/src/v4/key-transformation.js +57 -9
  8. package/build/codemods/src/v5/keep-previous-data/README.md +32 -0
  9. package/build/codemods/src/v5/keep-previous-data/keep-previous-data.js +275 -0
  10. package/build/codemods/src/v5/keep-previous-data/utils/already-has-placeholder-data-property.js +26 -0
  11. package/build/legacy/useBaseQuery.cjs +7 -0
  12. package/build/legacy/useBaseQuery.cjs.map +1 -1
  13. package/build/legacy/useBaseQuery.js +7 -0
  14. package/build/legacy/useBaseQuery.js.map +1 -1
  15. package/build/legacy/useQueries.cjs +2 -2
  16. package/build/legacy/useQueries.cjs.map +1 -1
  17. package/build/legacy/useQueries.js +7 -3
  18. package/build/legacy/useQueries.js.map +1 -1
  19. package/build/modern/useBaseQuery.cjs +7 -0
  20. package/build/modern/useBaseQuery.cjs.map +1 -1
  21. package/build/modern/useBaseQuery.js +7 -0
  22. package/build/modern/useBaseQuery.js.map +1 -1
  23. package/build/modern/useQueries.cjs +2 -2
  24. package/build/modern/useQueries.cjs.map +1 -1
  25. package/build/modern/useQueries.js +7 -3
  26. package/build/modern/useQueries.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/__tests__/useQuery.test.tsx +21 -0
  29. package/src/__tests__/useSuspenseQueries.test.tsx +144 -0
  30. package/src/useBaseQuery.ts +8 -0
  31. package/src/useQueries.ts +7 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { QueriesObserver, notifyManager } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n fetchOptimistic,\n shouldSuspend,\n willFetch,\n} from './suspense'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport type {\n DefaultError,\n QueriesObserverOptions,\n QueriesPlaceholderDataFunction,\n QueryClient,\n QueryFunction,\n QueryKey,\n ThrowOnError,\n} from '@tanstack/query-core'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function always gets undefined passed\ntype UseQueryOptionsForUseQueries<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> = Omit<\n UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'placeholderData' | 'suspense'\n> & {\n placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>\n}\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetOptions<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryOptionsForUseQueries<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TQueryFnData,\n TQueryKey\n >\n : // Fallback\n UseQueryOptionsForUseQueries\n\ntype GetResults<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 ? UseQueryResult<TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryResult<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryResult<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 ? UseQueryResult<TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryResult<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryResult<TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<unknown, any>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<TData, unknown extends TError ? DefaultError : TError>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<\n TQueryFnData,\n unknown extends TError ? DefaultError : TError\n >\n : // Fallback\n UseQueryResult\n\n/**\n * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param\n */\nexport type QueriesOptions<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryOptionsForUseQueries>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetOptions<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>\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/homogenous type!\n // use this to infer the param types in the case of Array.map() argument\n T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >\n >\n ? Array<UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>>\n : // Fallback\n Array<UseQueryOptionsForUseQueries>\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryResult>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetResults<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>\n : T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >\n >\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n Array<\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n >\n : // Fallback\n Array<UseQueryResult>\n\nexport function useQueries<\n T extends Array<any>,\n TCombinedResult = QueriesResults<T>,\n>(\n {\n queries,\n ...options\n }: {\n queries: readonly [...QueriesOptions<T>]\n combine?: (result: QueriesResults<T>) => TCombinedResult\n },\n queryClient?: QueryClient,\n): TCombinedResult {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((opts) => {\n const defaultedOptions = client.defaultQueryOptions(opts)\n\n // Make sure the results are already in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n return defaultedOptions\n }),\n [queries, client, isRestoring],\n )\n\n defaultedQueries.forEach((query) => {\n ensureStaleTime(query)\n ensurePreventErrorBoundaryRetry(query, errorResetBoundary)\n })\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new QueriesObserver<TCombinedResult>(\n client,\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n ),\n )\n\n const [optimisticResult, getCombinedResult, trackResult] =\n observer.getOptimisticResult(defaultedQueries)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) =>\n isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\n }, [defaultedQueries, options, observer])\n\n const shouldAtLeastOneSuspend = optimisticResult.some((result, index) =>\n shouldSuspend(defaultedQueries[index], result, isRestoring),\n )\n\n const suspensePromises = shouldAtLeastOneSuspend\n ? optimisticResult.flatMap((result, index) => {\n const opts = defaultedQueries[index]\n const queryObserver = observer.getObservers()[index]\n\n if (opts && queryObserver) {\n if (shouldSuspend(opts, result, isRestoring)) {\n return fetchOptimistic(opts, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(opts, queryObserver, errorResetBoundary)\n }\n }\n return []\n })\n : []\n\n if (suspensePromises.length > 0) {\n throw Promise.all(suspensePromises)\n }\n const observerQueries = observer.getQueries()\n const firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) =>\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedQueries[index]?.throwOnError ?? false,\n query: observerQueries[index]!,\n }),\n )\n\n if (firstSingleResultWhichShouldThrow?.error) {\n throw firstSingleResultWhichShouldThrow.error\n }\n\n return getCombinedResult(trackResult())\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAEvB,wBAA+C;AAC/C,iCAA+B;AAC/B,yBAA+B;AAC/B,qCAA2C;AAC3C,gCAIO;AACP,sBAKO;AAqKA,SAAS,WAId;AAAA,EACE;AAAA,EACA,GAAG;AACL,GAIA,aACiB;AACjB,QAAM,aAAS,2CAAe,WAAW;AACzC,QAAM,kBAAc,mCAAe;AACnC,QAAM,yBAAqB,2DAA2B;AAEtD,QAAM,mBAAyB;AAAA,IAC7B,MACE,QAAQ,IAAI,CAAC,SAAS;AACpB,YAAM,mBAAmB,OAAO,oBAAoB,IAAI;AAGxD,uBAAiB,qBAAqB,cAClC,gBACA;AAEJ,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,SAAS,QAAQ,WAAW;AAAA,EAC/B;AAEA,mBAAiB,QAAQ,CAAC,UAAU;AAClC,yCAAgB,KAAK;AACrB,mEAAgC,OAAO,kBAAkB;AAAA,EAC3D,CAAC;AAED,4DAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,CAAC,kBAAkB,mBAAmB,WAAW,IACrD,SAAS,oBAAoB,gBAAgB;AAE/C,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBACC,cACI,MAAM,SACN,SAAS,UAAU,gCAAc,WAAW,aAAa,CAAC;AAAA,MAChE,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,GAAG,CAAC,kBAAkB,SAAS,QAAQ,CAAC;AAExC,QAAM,0BAA0B,iBAAiB;AAAA,IAAK,CAAC,QAAQ,cAC7D,+BAAc,iBAAiB,KAAK,GAAG,QAAQ,WAAW;AAAA,EAC5D;AAEA,QAAM,mBAAmB,0BACrB,iBAAiB,QAAQ,CAAC,QAAQ,UAAU;AAC1C,UAAM,OAAO,iBAAiB,KAAK;AACnC,UAAM,gBAAgB,SAAS,aAAa,EAAE,KAAK;AAEnD,QAAI,QAAQ,eAAe;AACzB,cAAI,+BAAc,MAAM,QAAQ,WAAW,GAAG;AAC5C,mBAAO,iCAAgB,MAAM,eAAe,kBAAkB;AAAA,MAChE,eAAW,2BAAU,QAAQ,WAAW,GAAG;AACzC,iBAAK,iCAAgB,MAAM,eAAe,kBAAkB;AAAA,MAC9D;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV,CAAC,IACD,CAAC;AAEL,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,QAAQ,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UAAO;AA1RpB;AA2RM,wDAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA,gBAAc,sBAAiB,KAAK,MAAtB,mBAAyB,iBAAgB;AAAA,QACvD,OAAO,gBAAgB,KAAK;AAAA,MAC9B,CAAC;AAAA;AAAA,EACL;AAEA,MAAI,uFAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
1
+ {"version":3,"sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport {\n QueriesObserver,\n QueryObserver,\n notifyManager,\n} from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n fetchOptimistic,\n shouldSuspend,\n willFetch,\n} from './suspense'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport type {\n DefaultError,\n QueriesObserverOptions,\n QueriesPlaceholderDataFunction,\n QueryClient,\n QueryFunction,\n QueryKey,\n ThrowOnError,\n} from '@tanstack/query-core'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function always gets undefined passed\ntype UseQueryOptionsForUseQueries<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> = Omit<\n UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'placeholderData' | 'suspense'\n> & {\n placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>\n}\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetOptions<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryOptionsForUseQueries<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TQueryFnData,\n TQueryKey\n >\n : // Fallback\n UseQueryOptionsForUseQueries\n\ntype GetResults<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 ? UseQueryResult<TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryResult<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryResult<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 ? UseQueryResult<TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryResult<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryResult<TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<unknown, any>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<TData, unknown extends TError ? DefaultError : TError>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<\n TQueryFnData,\n unknown extends TError ? DefaultError : TError\n >\n : // Fallback\n UseQueryResult\n\n/**\n * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param\n */\nexport type QueriesOptions<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryOptionsForUseQueries>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetOptions<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>\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/homogenous type!\n // use this to infer the param types in the case of Array.map() argument\n T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >\n >\n ? Array<UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>>\n : // Fallback\n Array<UseQueryOptionsForUseQueries>\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryResult>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetResults<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>\n : T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >\n >\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n Array<\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n >\n : // Fallback\n Array<UseQueryResult>\n\nexport function useQueries<\n T extends Array<any>,\n TCombinedResult = QueriesResults<T>,\n>(\n {\n queries,\n ...options\n }: {\n queries: readonly [...QueriesOptions<T>]\n combine?: (result: QueriesResults<T>) => TCombinedResult\n },\n queryClient?: QueryClient,\n): TCombinedResult {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((opts) => {\n const defaultedOptions = client.defaultQueryOptions(opts)\n\n // Make sure the results are already in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n return defaultedOptions\n }),\n [queries, client, isRestoring],\n )\n\n defaultedQueries.forEach((query) => {\n ensureStaleTime(query)\n ensurePreventErrorBoundaryRetry(query, errorResetBoundary)\n })\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new QueriesObserver<TCombinedResult>(\n client,\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n ),\n )\n\n const [optimisticResult, getCombinedResult, trackResult] =\n observer.getOptimisticResult(defaultedQueries)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) =>\n isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\n }, [defaultedQueries, options, observer])\n\n const shouldAtLeastOneSuspend = optimisticResult.some((result, index) =>\n shouldSuspend(defaultedQueries[index], result, isRestoring),\n )\n\n const suspensePromises = shouldAtLeastOneSuspend\n ? optimisticResult.flatMap((result, index) => {\n const opts = defaultedQueries[index]\n\n if (opts) {\n const queryObserver = new QueryObserver(client, opts)\n if (shouldSuspend(opts, result, isRestoring)) {\n return fetchOptimistic(opts, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(opts, queryObserver, errorResetBoundary)\n }\n }\n return []\n })\n : []\n\n if (suspensePromises.length > 0) {\n throw Promise.all(suspensePromises)\n }\n const observerQueries = observer.getQueries()\n const firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) =>\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedQueries[index]?.throwOnError ?? false,\n query: observerQueries[index]!,\n }),\n )\n\n if (firstSingleResultWhichShouldThrow?.error) {\n throw firstSingleResultWhichShouldThrow.error\n }\n\n return getCombinedResult(trackResult())\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAEvB,wBAIO;AACP,iCAA+B;AAC/B,yBAA+B;AAC/B,qCAA2C;AAC3C,gCAIO;AACP,sBAKO;AAqKA,SAAS,WAId;AAAA,EACE;AAAA,EACA,GAAG;AACL,GAIA,aACiB;AACjB,QAAM,aAAS,2CAAe,WAAW;AACzC,QAAM,kBAAc,mCAAe;AACnC,QAAM,yBAAqB,2DAA2B;AAEtD,QAAM,mBAAyB;AAAA,IAC7B,MACE,QAAQ,IAAI,CAAC,SAAS;AACpB,YAAM,mBAAmB,OAAO,oBAAoB,IAAI;AAGxD,uBAAiB,qBAAqB,cAClC,gBACA;AAEJ,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,SAAS,QAAQ,WAAW;AAAA,EAC/B;AAEA,mBAAiB,QAAQ,CAAC,UAAU;AAClC,yCAAgB,KAAK;AACrB,mEAAgC,OAAO,kBAAkB;AAAA,EAC3D,CAAC;AAED,4DAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,CAAC,kBAAkB,mBAAmB,WAAW,IACrD,SAAS,oBAAoB,gBAAgB;AAE/C,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBACC,cACI,MAAM,SACN,SAAS,UAAU,gCAAc,WAAW,aAAa,CAAC;AAAA,MAChE,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,GAAG,CAAC,kBAAkB,SAAS,QAAQ,CAAC;AAExC,QAAM,0BAA0B,iBAAiB;AAAA,IAAK,CAAC,QAAQ,cAC7D,+BAAc,iBAAiB,KAAK,GAAG,QAAQ,WAAW;AAAA,EAC5D;AAEA,QAAM,mBAAmB,0BACrB,iBAAiB,QAAQ,CAAC,QAAQ,UAAU;AAC1C,UAAM,OAAO,iBAAiB,KAAK;AAEnC,QAAI,MAAM;AACR,YAAM,gBAAgB,IAAI,gCAAc,QAAQ,IAAI;AACpD,cAAI,+BAAc,MAAM,QAAQ,WAAW,GAAG;AAC5C,mBAAO,iCAAgB,MAAM,eAAe,kBAAkB;AAAA,MAChE,eAAW,2BAAU,QAAQ,WAAW,GAAG;AACzC,iBAAK,iCAAgB,MAAM,eAAe,kBAAkB;AAAA,MAC9D;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV,CAAC,IACD,CAAC;AAEL,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,QAAQ,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UAAO;AA9RpB;AA+RM,wDAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA,gBAAc,sBAAiB,KAAK,MAAtB,mBAAyB,iBAAgB;AAAA,QACvD,OAAO,gBAAgB,KAAK;AAAA,MAC9B,CAAC;AAAA;AAAA,EACL;AAEA,MAAI,uFAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
@@ -2,7 +2,11 @@
2
2
 
3
3
  // src/useQueries.ts
4
4
  import * as React from "react";
5
- import { QueriesObserver, notifyManager } from "@tanstack/query-core";
5
+ import {
6
+ QueriesObserver,
7
+ QueryObserver,
8
+ notifyManager
9
+ } from "@tanstack/query-core";
6
10
  import { useQueryClient } from "./QueryClientProvider.js";
7
11
  import { useIsRestoring } from "./isRestoring.js";
8
12
  import { useQueryErrorResetBoundary } from "./QueryErrorResetBoundary.js";
@@ -67,8 +71,8 @@ function useQueries({
67
71
  );
68
72
  const suspensePromises = shouldAtLeastOneSuspend ? optimisticResult.flatMap((result, index) => {
69
73
  const opts = defaultedQueries[index];
70
- const queryObserver = observer.getObservers()[index];
71
- if (opts && queryObserver) {
74
+ if (opts) {
75
+ const queryObserver = new QueryObserver(client, opts);
72
76
  if (shouldSuspend(opts, result, isRestoring)) {
73
77
  return fetchOptimistic(opts, queryObserver, errorResetBoundary);
74
78
  } else if (willFetch(result, isRestoring)) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { QueriesObserver, notifyManager } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n fetchOptimistic,\n shouldSuspend,\n willFetch,\n} from './suspense'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport type {\n DefaultError,\n QueriesObserverOptions,\n QueriesPlaceholderDataFunction,\n QueryClient,\n QueryFunction,\n QueryKey,\n ThrowOnError,\n} from '@tanstack/query-core'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function always gets undefined passed\ntype UseQueryOptionsForUseQueries<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> = Omit<\n UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'placeholderData' | 'suspense'\n> & {\n placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>\n}\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetOptions<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryOptionsForUseQueries<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TQueryFnData,\n TQueryKey\n >\n : // Fallback\n UseQueryOptionsForUseQueries\n\ntype GetResults<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 ? UseQueryResult<TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryResult<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryResult<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 ? UseQueryResult<TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryResult<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryResult<TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<unknown, any>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<TData, unknown extends TError ? DefaultError : TError>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<\n TQueryFnData,\n unknown extends TError ? DefaultError : TError\n >\n : // Fallback\n UseQueryResult\n\n/**\n * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param\n */\nexport type QueriesOptions<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryOptionsForUseQueries>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetOptions<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>\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/homogenous type!\n // use this to infer the param types in the case of Array.map() argument\n T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >\n >\n ? Array<UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>>\n : // Fallback\n Array<UseQueryOptionsForUseQueries>\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryResult>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetResults<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>\n : T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >\n >\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n Array<\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n >\n : // Fallback\n Array<UseQueryResult>\n\nexport function useQueries<\n T extends Array<any>,\n TCombinedResult = QueriesResults<T>,\n>(\n {\n queries,\n ...options\n }: {\n queries: readonly [...QueriesOptions<T>]\n combine?: (result: QueriesResults<T>) => TCombinedResult\n },\n queryClient?: QueryClient,\n): TCombinedResult {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((opts) => {\n const defaultedOptions = client.defaultQueryOptions(opts)\n\n // Make sure the results are already in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n return defaultedOptions\n }),\n [queries, client, isRestoring],\n )\n\n defaultedQueries.forEach((query) => {\n ensureStaleTime(query)\n ensurePreventErrorBoundaryRetry(query, errorResetBoundary)\n })\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new QueriesObserver<TCombinedResult>(\n client,\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n ),\n )\n\n const [optimisticResult, getCombinedResult, trackResult] =\n observer.getOptimisticResult(defaultedQueries)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) =>\n isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\n }, [defaultedQueries, options, observer])\n\n const shouldAtLeastOneSuspend = optimisticResult.some((result, index) =>\n shouldSuspend(defaultedQueries[index], result, isRestoring),\n )\n\n const suspensePromises = shouldAtLeastOneSuspend\n ? optimisticResult.flatMap((result, index) => {\n const opts = defaultedQueries[index]\n const queryObserver = observer.getObservers()[index]\n\n if (opts && queryObserver) {\n if (shouldSuspend(opts, result, isRestoring)) {\n return fetchOptimistic(opts, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(opts, queryObserver, errorResetBoundary)\n }\n }\n return []\n })\n : []\n\n if (suspensePromises.length > 0) {\n throw Promise.all(suspensePromises)\n }\n const observerQueries = observer.getQueries()\n const firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) =>\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedQueries[index]?.throwOnError ?? false,\n query: observerQueries[index]!,\n }),\n )\n\n if (firstSingleResultWhichShouldThrow?.error) {\n throw firstSingleResultWhichShouldThrow.error\n }\n\n return getCombinedResult(trackResult())\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB,SAAS,iBAAiB,qBAAqB;AAC/C,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,kCAAkC;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAqKA,SAAS,WAId;AAAA,EACE;AAAA,EACA,GAAG;AACL,GAIA,aACiB;AACjB,QAAM,SAAS,eAAe,WAAW;AACzC,QAAM,cAAc,eAAe;AACnC,QAAM,qBAAqB,2BAA2B;AAEtD,QAAM,mBAAyB;AAAA,IAC7B,MACE,QAAQ,IAAI,CAAC,SAAS;AACpB,YAAM,mBAAmB,OAAO,oBAAoB,IAAI;AAGxD,uBAAiB,qBAAqB,cAClC,gBACA;AAEJ,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,SAAS,QAAQ,WAAW;AAAA,EAC/B;AAEA,mBAAiB,QAAQ,CAAC,UAAU;AAClC,oBAAgB,KAAK;AACrB,oCAAgC,OAAO,kBAAkB;AAAA,EAC3D,CAAC;AAED,6BAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,CAAC,kBAAkB,mBAAmB,WAAW,IACrD,SAAS,oBAAoB,gBAAgB;AAE/C,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBACC,cACI,MAAM,SACN,SAAS,UAAU,cAAc,WAAW,aAAa,CAAC;AAAA,MAChE,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,GAAG,CAAC,kBAAkB,SAAS,QAAQ,CAAC;AAExC,QAAM,0BAA0B,iBAAiB;AAAA,IAAK,CAAC,QAAQ,UAC7D,cAAc,iBAAiB,KAAK,GAAG,QAAQ,WAAW;AAAA,EAC5D;AAEA,QAAM,mBAAmB,0BACrB,iBAAiB,QAAQ,CAAC,QAAQ,UAAU;AAC1C,UAAM,OAAO,iBAAiB,KAAK;AACnC,UAAM,gBAAgB,SAAS,aAAa,EAAE,KAAK;AAEnD,QAAI,QAAQ,eAAe;AACzB,UAAI,cAAc,MAAM,QAAQ,WAAW,GAAG;AAC5C,eAAO,gBAAgB,MAAM,eAAe,kBAAkB;AAAA,MAChE,WAAW,UAAU,QAAQ,WAAW,GAAG;AACzC,aAAK,gBAAgB,MAAM,eAAe,kBAAkB;AAAA,MAC9D;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV,CAAC,IACD,CAAC;AAEL,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,QAAQ,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UAAO;AA1RpB;AA2RM,yBAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA,gBAAc,sBAAiB,KAAK,MAAtB,mBAAyB,iBAAgB;AAAA,QACvD,OAAO,gBAAgB,KAAK;AAAA,MAC9B,CAAC;AAAA;AAAA,EACL;AAEA,MAAI,uFAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
1
+ {"version":3,"sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport {\n QueriesObserver,\n QueryObserver,\n notifyManager,\n} from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n fetchOptimistic,\n shouldSuspend,\n willFetch,\n} from './suspense'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport type {\n DefaultError,\n QueriesObserverOptions,\n QueriesPlaceholderDataFunction,\n QueryClient,\n QueryFunction,\n QueryKey,\n ThrowOnError,\n} from '@tanstack/query-core'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function always gets undefined passed\ntype UseQueryOptionsForUseQueries<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> = Omit<\n UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'placeholderData' | 'suspense'\n> & {\n placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>\n}\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetOptions<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryOptionsForUseQueries<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TQueryFnData,\n TQueryKey\n >\n : // Fallback\n UseQueryOptionsForUseQueries\n\ntype GetResults<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 ? UseQueryResult<TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryResult<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryResult<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 ? UseQueryResult<TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryResult<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryResult<TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<unknown, any>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<TData, unknown extends TError ? DefaultError : TError>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<\n TQueryFnData,\n unknown extends TError ? DefaultError : TError\n >\n : // Fallback\n UseQueryResult\n\n/**\n * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param\n */\nexport type QueriesOptions<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryOptionsForUseQueries>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetOptions<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>\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/homogenous type!\n // use this to infer the param types in the case of Array.map() argument\n T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >\n >\n ? Array<UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>>\n : // Fallback\n Array<UseQueryOptionsForUseQueries>\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryResult>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetResults<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>\n : T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >\n >\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n Array<\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n >\n : // Fallback\n Array<UseQueryResult>\n\nexport function useQueries<\n T extends Array<any>,\n TCombinedResult = QueriesResults<T>,\n>(\n {\n queries,\n ...options\n }: {\n queries: readonly [...QueriesOptions<T>]\n combine?: (result: QueriesResults<T>) => TCombinedResult\n },\n queryClient?: QueryClient,\n): TCombinedResult {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((opts) => {\n const defaultedOptions = client.defaultQueryOptions(opts)\n\n // Make sure the results are already in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n return defaultedOptions\n }),\n [queries, client, isRestoring],\n )\n\n defaultedQueries.forEach((query) => {\n ensureStaleTime(query)\n ensurePreventErrorBoundaryRetry(query, errorResetBoundary)\n })\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new QueriesObserver<TCombinedResult>(\n client,\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n ),\n )\n\n const [optimisticResult, getCombinedResult, trackResult] =\n observer.getOptimisticResult(defaultedQueries)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) =>\n isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\n }, [defaultedQueries, options, observer])\n\n const shouldAtLeastOneSuspend = optimisticResult.some((result, index) =>\n shouldSuspend(defaultedQueries[index], result, isRestoring),\n )\n\n const suspensePromises = shouldAtLeastOneSuspend\n ? optimisticResult.flatMap((result, index) => {\n const opts = defaultedQueries[index]\n\n if (opts) {\n const queryObserver = new QueryObserver(client, opts)\n if (shouldSuspend(opts, result, isRestoring)) {\n return fetchOptimistic(opts, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(opts, queryObserver, errorResetBoundary)\n }\n }\n return []\n })\n : []\n\n if (suspensePromises.length > 0) {\n throw Promise.all(suspensePromises)\n }\n const observerQueries = observer.getQueries()\n const firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) =>\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedQueries[index]?.throwOnError ?? false,\n query: observerQueries[index]!,\n }),\n )\n\n if (firstSingleResultWhichShouldThrow?.error) {\n throw firstSingleResultWhichShouldThrow.error\n }\n\n return getCombinedResult(trackResult())\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,kCAAkC;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAqKA,SAAS,WAId;AAAA,EACE;AAAA,EACA,GAAG;AACL,GAIA,aACiB;AACjB,QAAM,SAAS,eAAe,WAAW;AACzC,QAAM,cAAc,eAAe;AACnC,QAAM,qBAAqB,2BAA2B;AAEtD,QAAM,mBAAyB;AAAA,IAC7B,MACE,QAAQ,IAAI,CAAC,SAAS;AACpB,YAAM,mBAAmB,OAAO,oBAAoB,IAAI;AAGxD,uBAAiB,qBAAqB,cAClC,gBACA;AAEJ,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,SAAS,QAAQ,WAAW;AAAA,EAC/B;AAEA,mBAAiB,QAAQ,CAAC,UAAU;AAClC,oBAAgB,KAAK;AACrB,oCAAgC,OAAO,kBAAkB;AAAA,EAC3D,CAAC;AAED,6BAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,CAAC,kBAAkB,mBAAmB,WAAW,IACrD,SAAS,oBAAoB,gBAAgB;AAE/C,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBACC,cACI,MAAM,SACN,SAAS,UAAU,cAAc,WAAW,aAAa,CAAC;AAAA,MAChE,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,GAAG,CAAC,kBAAkB,SAAS,QAAQ,CAAC;AAExC,QAAM,0BAA0B,iBAAiB;AAAA,IAAK,CAAC,QAAQ,UAC7D,cAAc,iBAAiB,KAAK,GAAG,QAAQ,WAAW;AAAA,EAC5D;AAEA,QAAM,mBAAmB,0BACrB,iBAAiB,QAAQ,CAAC,QAAQ,UAAU;AAC1C,UAAM,OAAO,iBAAiB,KAAK;AAEnC,QAAI,MAAM;AACR,YAAM,gBAAgB,IAAI,cAAc,QAAQ,IAAI;AACpD,UAAI,cAAc,MAAM,QAAQ,WAAW,GAAG;AAC5C,eAAO,gBAAgB,MAAM,eAAe,kBAAkB;AAAA,MAChE,WAAW,UAAU,QAAQ,WAAW,GAAG;AACzC,aAAK,gBAAgB,MAAM,eAAe,kBAAkB;AAAA,MAC9D;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV,CAAC,IACD,CAAC;AAEL,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,QAAQ,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UAAO;AA9RpB;AA+RM,yBAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA,gBAAc,sBAAiB,KAAK,MAAtB,mBAAyB,iBAAgB;AAAA,QACvD,OAAO,gBAAgB,KAAK;AAAA,MAC9B,CAAC;AAAA;AAAA,EACL;AAEA,MAAI,uFAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
@@ -42,6 +42,13 @@ var import_isRestoring = require("./isRestoring.cjs");
42
42
  var import_errorBoundaryUtils = require("./errorBoundaryUtils.cjs");
43
43
  var import_suspense = require("./suspense.cjs");
44
44
  function useBaseQuery(options, Observer, queryClient) {
45
+ if (process.env.NODE_ENV !== "production") {
46
+ if (typeof options !== "object" || Array.isArray(options)) {
47
+ throw new Error(
48
+ 'Bad argument type. Starting with v5, only the "Object" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object'
49
+ );
50
+ }
51
+ }
45
52
  const client = (0, import_QueryClientProvider.useQueryClient)(queryClient);
46
53
  const isRestoring = (0, import_isRestoring.useIsRestoring)();
47
54
  const errorResetBoundary = (0, import_QueryErrorResetBoundary.useQueryErrorResetBoundary)();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/useBaseQuery.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { notifyManager } from '@tanstack/query-core'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'\nimport type { UseBaseQueryOptions } from './types'\nimport type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n) {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const defaultedOptions = client.defaultQueryOptions(options)\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureStaleTime(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n const result = observer.getOptimisticResult(defaultedOptions)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange))\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setOptions(defaultedOptions, { listeners: false })\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result, isRestoring)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query: observer.getCurrentQuery(),\n })\n ) {\n throw result.error\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAEvB,wBAA8B;AAC9B,qCAA2C;AAC3C,iCAA+B;AAC/B,yBAA+B;AAC/B,gCAIO;AACP,sBAAgE;AAIzD,SAAS,aAOd,SAOA,UACA,aACA;AACA,QAAM,aAAS,2CAAe,WAAW;AACzC,QAAM,kBAAc,mCAAe;AACnC,QAAM,yBAAqB,2DAA2B;AACtD,QAAM,mBAAmB,OAAO,oBAAoB,OAAO;AAG3D,mBAAiB,qBAAqB,cAClC,gBACA;AAEJ,uCAAgB,gBAAgB;AAChC,iEAAgC,kBAAkB,kBAAkB;AAEpE,4DAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,SAAS,SAAS,oBAAoB,gBAAgB;AAE5D,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBAAkB;AACjB,cAAM,cAAc,cAChB,MAAM,SACN,SAAS,UAAU,gCAAc,WAAW,aAAa,CAAC;AAI9D,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5D,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAG/B,UAAI,+BAAc,kBAAkB,QAAQ,WAAW,GAAG;AACxD,cAAM,iCAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,UACE,uCAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,SAAS,gBAAgB;AAAA,EAClC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
1
+ {"version":3,"sources":["../../src/useBaseQuery.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { notifyManager } from '@tanstack/query-core'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'\nimport type { UseBaseQueryOptions } from './types'\nimport type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n) {\n if (process.env.NODE_ENV !== 'production') {\n if (typeof options !== 'object' || Array.isArray(options)) {\n throw new Error(\n 'Bad argument type. Starting with v5, only the \"Object\" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object',\n )\n }\n }\n\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const defaultedOptions = client.defaultQueryOptions(options)\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureStaleTime(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n const result = observer.getOptimisticResult(defaultedOptions)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange))\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setOptions(defaultedOptions, { listeners: false })\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result, isRestoring)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query: observer.getCurrentQuery(),\n })\n ) {\n throw result.error\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAEvB,wBAA8B;AAC9B,qCAA2C;AAC3C,iCAA+B;AAC/B,yBAA+B;AAC/B,gCAIO;AACP,sBAAgE;AAIzD,SAAS,aAOd,SAOA,UACA,aACA;AACA,MAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,QAAI,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAAG;AACzD,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAS,2CAAe,WAAW;AACzC,QAAM,kBAAc,mCAAe;AACnC,QAAM,yBAAqB,2DAA2B;AACtD,QAAM,mBAAmB,OAAO,oBAAoB,OAAO;AAG3D,mBAAiB,qBAAqB,cAClC,gBACA;AAEJ,uCAAgB,gBAAgB;AAChC,iEAAgC,kBAAkB,kBAAkB;AAEpE,4DAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,SAAS,SAAS,oBAAoB,gBAAgB;AAE5D,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBAAkB;AACjB,cAAM,cAAc,cAChB,MAAM,SACN,SAAS,UAAU,gCAAc,WAAW,aAAa,CAAC;AAI9D,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5D,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAG/B,UAAI,+BAAc,kBAAkB,QAAQ,WAAW,GAAG;AACxD,cAAM,iCAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,UACE,uCAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,SAAS,gBAAgB;AAAA,EAClC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
@@ -13,6 +13,13 @@ import {
13
13
  } from "./errorBoundaryUtils.js";
14
14
  import { ensureStaleTime, fetchOptimistic, shouldSuspend } from "./suspense.js";
15
15
  function useBaseQuery(options, Observer, queryClient) {
16
+ if (process.env.NODE_ENV !== "production") {
17
+ if (typeof options !== "object" || Array.isArray(options)) {
18
+ throw new Error(
19
+ 'Bad argument type. Starting with v5, only the "Object" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object'
20
+ );
21
+ }
22
+ }
16
23
  const client = useQueryClient(queryClient);
17
24
  const isRestoring = useIsRestoring();
18
25
  const errorResetBoundary = useQueryErrorResetBoundary();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/useBaseQuery.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { notifyManager } from '@tanstack/query-core'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'\nimport type { UseBaseQueryOptions } from './types'\nimport type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n) {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const defaultedOptions = client.defaultQueryOptions(options)\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureStaleTime(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n const result = observer.getOptimisticResult(defaultedOptions)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange))\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setOptions(defaultedOptions, { listeners: false })\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result, isRestoring)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query: observer.getCurrentQuery(),\n })\n ) {\n throw result.error\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB,SAAS,qBAAqB;AAC9B,SAAS,kCAAkC;AAC3C,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB,iBAAiB,qBAAqB;AAIzD,SAAS,aAOd,SAOA,UACA,aACA;AACA,QAAM,SAAS,eAAe,WAAW;AACzC,QAAM,cAAc,eAAe;AACnC,QAAM,qBAAqB,2BAA2B;AACtD,QAAM,mBAAmB,OAAO,oBAAoB,OAAO;AAG3D,mBAAiB,qBAAqB,cAClC,gBACA;AAEJ,kBAAgB,gBAAgB;AAChC,kCAAgC,kBAAkB,kBAAkB;AAEpE,6BAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,SAAS,SAAS,oBAAoB,gBAAgB;AAE5D,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBAAkB;AACjB,cAAM,cAAc,cAChB,MAAM,SACN,SAAS,UAAU,cAAc,WAAW,aAAa,CAAC;AAI9D,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5D,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAG/B,MAAI,cAAc,kBAAkB,QAAQ,WAAW,GAAG;AACxD,UAAM,gBAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,MACE,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,SAAS,gBAAgB;AAAA,EAClC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
1
+ {"version":3,"sources":["../../src/useBaseQuery.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { notifyManager } from '@tanstack/query-core'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'\nimport type { UseBaseQueryOptions } from './types'\nimport type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n) {\n if (process.env.NODE_ENV !== 'production') {\n if (typeof options !== 'object' || Array.isArray(options)) {\n throw new Error(\n 'Bad argument type. Starting with v5, only the \"Object\" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object',\n )\n }\n }\n\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const defaultedOptions = client.defaultQueryOptions(options)\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureStaleTime(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n const result = observer.getOptimisticResult(defaultedOptions)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange))\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setOptions(defaultedOptions, { listeners: false })\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result, isRestoring)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query: observer.getCurrentQuery(),\n })\n ) {\n throw result.error\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB,SAAS,qBAAqB;AAC9B,SAAS,kCAAkC;AAC3C,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB,iBAAiB,qBAAqB;AAIzD,SAAS,aAOd,SAOA,UACA,aACA;AACA,MAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,QAAI,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAAG;AACzD,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,eAAe,WAAW;AACzC,QAAM,cAAc,eAAe;AACnC,QAAM,qBAAqB,2BAA2B;AACtD,QAAM,mBAAmB,OAAO,oBAAoB,OAAO;AAG3D,mBAAiB,qBAAqB,cAClC,gBACA;AAEJ,kBAAgB,gBAAgB;AAChC,kCAAgC,kBAAkB,kBAAkB;AAEpE,6BAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,SAAS,SAAS,oBAAoB,gBAAgB;AAE5D,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBAAkB;AACjB,cAAM,cAAc,cAChB,MAAM,SACN,SAAS,UAAU,cAAc,WAAW,aAAa,CAAC;AAI9D,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5D,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAG/B,MAAI,cAAc,kBAAkB,QAAQ,WAAW,GAAG;AACxD,UAAM,gBAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,MACE,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,SAAS,gBAAgB;AAAA,EAClC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
@@ -91,8 +91,8 @@ function useQueries({
91
91
  );
92
92
  const suspensePromises = shouldAtLeastOneSuspend ? optimisticResult.flatMap((result, index) => {
93
93
  const opts = defaultedQueries[index];
94
- const queryObserver = observer.getObservers()[index];
95
- if (opts && queryObserver) {
94
+ if (opts) {
95
+ const queryObserver = new import_query_core.QueryObserver(client, opts);
96
96
  if ((0, import_suspense.shouldSuspend)(opts, result, isRestoring)) {
97
97
  return (0, import_suspense.fetchOptimistic)(opts, queryObserver, errorResetBoundary);
98
98
  } else if ((0, import_suspense.willFetch)(result, isRestoring)) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { QueriesObserver, notifyManager } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n fetchOptimistic,\n shouldSuspend,\n willFetch,\n} from './suspense'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport type {\n DefaultError,\n QueriesObserverOptions,\n QueriesPlaceholderDataFunction,\n QueryClient,\n QueryFunction,\n QueryKey,\n ThrowOnError,\n} from '@tanstack/query-core'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function always gets undefined passed\ntype UseQueryOptionsForUseQueries<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> = Omit<\n UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'placeholderData' | 'suspense'\n> & {\n placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>\n}\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetOptions<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryOptionsForUseQueries<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TQueryFnData,\n TQueryKey\n >\n : // Fallback\n UseQueryOptionsForUseQueries\n\ntype GetResults<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 ? UseQueryResult<TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryResult<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryResult<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 ? UseQueryResult<TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryResult<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryResult<TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<unknown, any>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<TData, unknown extends TError ? DefaultError : TError>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<\n TQueryFnData,\n unknown extends TError ? DefaultError : TError\n >\n : // Fallback\n UseQueryResult\n\n/**\n * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param\n */\nexport type QueriesOptions<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryOptionsForUseQueries>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetOptions<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>\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/homogenous type!\n // use this to infer the param types in the case of Array.map() argument\n T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >\n >\n ? Array<UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>>\n : // Fallback\n Array<UseQueryOptionsForUseQueries>\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryResult>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetResults<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>\n : T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >\n >\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n Array<\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n >\n : // Fallback\n Array<UseQueryResult>\n\nexport function useQueries<\n T extends Array<any>,\n TCombinedResult = QueriesResults<T>,\n>(\n {\n queries,\n ...options\n }: {\n queries: readonly [...QueriesOptions<T>]\n combine?: (result: QueriesResults<T>) => TCombinedResult\n },\n queryClient?: QueryClient,\n): TCombinedResult {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((opts) => {\n const defaultedOptions = client.defaultQueryOptions(opts)\n\n // Make sure the results are already in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n return defaultedOptions\n }),\n [queries, client, isRestoring],\n )\n\n defaultedQueries.forEach((query) => {\n ensureStaleTime(query)\n ensurePreventErrorBoundaryRetry(query, errorResetBoundary)\n })\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new QueriesObserver<TCombinedResult>(\n client,\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n ),\n )\n\n const [optimisticResult, getCombinedResult, trackResult] =\n observer.getOptimisticResult(defaultedQueries)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) =>\n isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\n }, [defaultedQueries, options, observer])\n\n const shouldAtLeastOneSuspend = optimisticResult.some((result, index) =>\n shouldSuspend(defaultedQueries[index], result, isRestoring),\n )\n\n const suspensePromises = shouldAtLeastOneSuspend\n ? optimisticResult.flatMap((result, index) => {\n const opts = defaultedQueries[index]\n const queryObserver = observer.getObservers()[index]\n\n if (opts && queryObserver) {\n if (shouldSuspend(opts, result, isRestoring)) {\n return fetchOptimistic(opts, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(opts, queryObserver, errorResetBoundary)\n }\n }\n return []\n })\n : []\n\n if (suspensePromises.length > 0) {\n throw Promise.all(suspensePromises)\n }\n const observerQueries = observer.getQueries()\n const firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) =>\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedQueries[index]?.throwOnError ?? false,\n query: observerQueries[index]!,\n }),\n )\n\n if (firstSingleResultWhichShouldThrow?.error) {\n throw firstSingleResultWhichShouldThrow.error\n }\n\n return getCombinedResult(trackResult())\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAEvB,wBAA+C;AAC/C,iCAA+B;AAC/B,yBAA+B;AAC/B,qCAA2C;AAC3C,gCAIO;AACP,sBAKO;AAqKA,SAAS,WAId;AAAA,EACE;AAAA,EACA,GAAG;AACL,GAIA,aACiB;AACjB,QAAM,aAAS,2CAAe,WAAW;AACzC,QAAM,kBAAc,mCAAe;AACnC,QAAM,yBAAqB,2DAA2B;AAEtD,QAAM,mBAAyB;AAAA,IAC7B,MACE,QAAQ,IAAI,CAAC,SAAS;AACpB,YAAM,mBAAmB,OAAO,oBAAoB,IAAI;AAGxD,uBAAiB,qBAAqB,cAClC,gBACA;AAEJ,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,SAAS,QAAQ,WAAW;AAAA,EAC/B;AAEA,mBAAiB,QAAQ,CAAC,UAAU;AAClC,yCAAgB,KAAK;AACrB,mEAAgC,OAAO,kBAAkB;AAAA,EAC3D,CAAC;AAED,4DAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,CAAC,kBAAkB,mBAAmB,WAAW,IACrD,SAAS,oBAAoB,gBAAgB;AAE/C,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBACC,cACI,MAAM,SACN,SAAS,UAAU,gCAAc,WAAW,aAAa,CAAC;AAAA,MAChE,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,GAAG,CAAC,kBAAkB,SAAS,QAAQ,CAAC;AAExC,QAAM,0BAA0B,iBAAiB;AAAA,IAAK,CAAC,QAAQ,cAC7D,+BAAc,iBAAiB,KAAK,GAAG,QAAQ,WAAW;AAAA,EAC5D;AAEA,QAAM,mBAAmB,0BACrB,iBAAiB,QAAQ,CAAC,QAAQ,UAAU;AAC1C,UAAM,OAAO,iBAAiB,KAAK;AACnC,UAAM,gBAAgB,SAAS,aAAa,EAAE,KAAK;AAEnD,QAAI,QAAQ,eAAe;AACzB,cAAI,+BAAc,MAAM,QAAQ,WAAW,GAAG;AAC5C,mBAAO,iCAAgB,MAAM,eAAe,kBAAkB;AAAA,MAChE,eAAW,2BAAU,QAAQ,WAAW,GAAG;AACzC,iBAAK,iCAAgB,MAAM,eAAe,kBAAkB;AAAA,MAC9D;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV,CAAC,IACD,CAAC;AAEL,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,QAAQ,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,cACP,uCAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA,cAAc,iBAAiB,KAAK,GAAG,gBAAgB;AAAA,MACvD,OAAO,gBAAgB,KAAK;AAAA,IAC9B,CAAC;AAAA,EACL;AAEA,MAAI,mCAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
1
+ {"version":3,"sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport {\n QueriesObserver,\n QueryObserver,\n notifyManager,\n} from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n fetchOptimistic,\n shouldSuspend,\n willFetch,\n} from './suspense'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport type {\n DefaultError,\n QueriesObserverOptions,\n QueriesPlaceholderDataFunction,\n QueryClient,\n QueryFunction,\n QueryKey,\n ThrowOnError,\n} from '@tanstack/query-core'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function always gets undefined passed\ntype UseQueryOptionsForUseQueries<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> = Omit<\n UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'placeholderData' | 'suspense'\n> & {\n placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>\n}\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetOptions<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryOptionsForUseQueries<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TQueryFnData,\n TQueryKey\n >\n : // Fallback\n UseQueryOptionsForUseQueries\n\ntype GetResults<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 ? UseQueryResult<TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryResult<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryResult<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 ? UseQueryResult<TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryResult<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryResult<TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<unknown, any>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<TData, unknown extends TError ? DefaultError : TError>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<\n TQueryFnData,\n unknown extends TError ? DefaultError : TError\n >\n : // Fallback\n UseQueryResult\n\n/**\n * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param\n */\nexport type QueriesOptions<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryOptionsForUseQueries>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetOptions<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>\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/homogenous type!\n // use this to infer the param types in the case of Array.map() argument\n T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >\n >\n ? Array<UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>>\n : // Fallback\n Array<UseQueryOptionsForUseQueries>\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryResult>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetResults<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>\n : T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >\n >\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n Array<\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n >\n : // Fallback\n Array<UseQueryResult>\n\nexport function useQueries<\n T extends Array<any>,\n TCombinedResult = QueriesResults<T>,\n>(\n {\n queries,\n ...options\n }: {\n queries: readonly [...QueriesOptions<T>]\n combine?: (result: QueriesResults<T>) => TCombinedResult\n },\n queryClient?: QueryClient,\n): TCombinedResult {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((opts) => {\n const defaultedOptions = client.defaultQueryOptions(opts)\n\n // Make sure the results are already in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n return defaultedOptions\n }),\n [queries, client, isRestoring],\n )\n\n defaultedQueries.forEach((query) => {\n ensureStaleTime(query)\n ensurePreventErrorBoundaryRetry(query, errorResetBoundary)\n })\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new QueriesObserver<TCombinedResult>(\n client,\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n ),\n )\n\n const [optimisticResult, getCombinedResult, trackResult] =\n observer.getOptimisticResult(defaultedQueries)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) =>\n isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\n }, [defaultedQueries, options, observer])\n\n const shouldAtLeastOneSuspend = optimisticResult.some((result, index) =>\n shouldSuspend(defaultedQueries[index], result, isRestoring),\n )\n\n const suspensePromises = shouldAtLeastOneSuspend\n ? optimisticResult.flatMap((result, index) => {\n const opts = defaultedQueries[index]\n\n if (opts) {\n const queryObserver = new QueryObserver(client, opts)\n if (shouldSuspend(opts, result, isRestoring)) {\n return fetchOptimistic(opts, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(opts, queryObserver, errorResetBoundary)\n }\n }\n return []\n })\n : []\n\n if (suspensePromises.length > 0) {\n throw Promise.all(suspensePromises)\n }\n const observerQueries = observer.getQueries()\n const firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) =>\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedQueries[index]?.throwOnError ?? false,\n query: observerQueries[index]!,\n }),\n )\n\n if (firstSingleResultWhichShouldThrow?.error) {\n throw firstSingleResultWhichShouldThrow.error\n }\n\n return getCombinedResult(trackResult())\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAEvB,wBAIO;AACP,iCAA+B;AAC/B,yBAA+B;AAC/B,qCAA2C;AAC3C,gCAIO;AACP,sBAKO;AAqKA,SAAS,WAId;AAAA,EACE;AAAA,EACA,GAAG;AACL,GAIA,aACiB;AACjB,QAAM,aAAS,2CAAe,WAAW;AACzC,QAAM,kBAAc,mCAAe;AACnC,QAAM,yBAAqB,2DAA2B;AAEtD,QAAM,mBAAyB;AAAA,IAC7B,MACE,QAAQ,IAAI,CAAC,SAAS;AACpB,YAAM,mBAAmB,OAAO,oBAAoB,IAAI;AAGxD,uBAAiB,qBAAqB,cAClC,gBACA;AAEJ,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,SAAS,QAAQ,WAAW;AAAA,EAC/B;AAEA,mBAAiB,QAAQ,CAAC,UAAU;AAClC,yCAAgB,KAAK;AACrB,mEAAgC,OAAO,kBAAkB;AAAA,EAC3D,CAAC;AAED,4DAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,CAAC,kBAAkB,mBAAmB,WAAW,IACrD,SAAS,oBAAoB,gBAAgB;AAE/C,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBACC,cACI,MAAM,SACN,SAAS,UAAU,gCAAc,WAAW,aAAa,CAAC;AAAA,MAChE,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,GAAG,CAAC,kBAAkB,SAAS,QAAQ,CAAC;AAExC,QAAM,0BAA0B,iBAAiB;AAAA,IAAK,CAAC,QAAQ,cAC7D,+BAAc,iBAAiB,KAAK,GAAG,QAAQ,WAAW;AAAA,EAC5D;AAEA,QAAM,mBAAmB,0BACrB,iBAAiB,QAAQ,CAAC,QAAQ,UAAU;AAC1C,UAAM,OAAO,iBAAiB,KAAK;AAEnC,QAAI,MAAM;AACR,YAAM,gBAAgB,IAAI,gCAAc,QAAQ,IAAI;AACpD,cAAI,+BAAc,MAAM,QAAQ,WAAW,GAAG;AAC5C,mBAAO,iCAAgB,MAAM,eAAe,kBAAkB;AAAA,MAChE,eAAW,2BAAU,QAAQ,WAAW,GAAG;AACzC,iBAAK,iCAAgB,MAAM,eAAe,kBAAkB;AAAA,MAC9D;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV,CAAC,IACD,CAAC;AAEL,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,QAAQ,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,cACP,uCAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA,cAAc,iBAAiB,KAAK,GAAG,gBAAgB;AAAA,MACvD,OAAO,gBAAgB,KAAK;AAAA,IAC9B,CAAC;AAAA,EACL;AAEA,MAAI,mCAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
@@ -2,7 +2,11 @@
2
2
 
3
3
  // src/useQueries.ts
4
4
  import * as React from "react";
5
- import { QueriesObserver, notifyManager } from "@tanstack/query-core";
5
+ import {
6
+ QueriesObserver,
7
+ QueryObserver,
8
+ notifyManager
9
+ } from "@tanstack/query-core";
6
10
  import { useQueryClient } from "./QueryClientProvider.js";
7
11
  import { useIsRestoring } from "./isRestoring.js";
8
12
  import { useQueryErrorResetBoundary } from "./QueryErrorResetBoundary.js";
@@ -67,8 +71,8 @@ function useQueries({
67
71
  );
68
72
  const suspensePromises = shouldAtLeastOneSuspend ? optimisticResult.flatMap((result, index) => {
69
73
  const opts = defaultedQueries[index];
70
- const queryObserver = observer.getObservers()[index];
71
- if (opts && queryObserver) {
74
+ if (opts) {
75
+ const queryObserver = new QueryObserver(client, opts);
72
76
  if (shouldSuspend(opts, result, isRestoring)) {
73
77
  return fetchOptimistic(opts, queryObserver, errorResetBoundary);
74
78
  } else if (willFetch(result, isRestoring)) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { QueriesObserver, notifyManager } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n fetchOptimistic,\n shouldSuspend,\n willFetch,\n} from './suspense'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport type {\n DefaultError,\n QueriesObserverOptions,\n QueriesPlaceholderDataFunction,\n QueryClient,\n QueryFunction,\n QueryKey,\n ThrowOnError,\n} from '@tanstack/query-core'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function always gets undefined passed\ntype UseQueryOptionsForUseQueries<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> = Omit<\n UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'placeholderData' | 'suspense'\n> & {\n placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>\n}\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetOptions<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryOptionsForUseQueries<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TQueryFnData,\n TQueryKey\n >\n : // Fallback\n UseQueryOptionsForUseQueries\n\ntype GetResults<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 ? UseQueryResult<TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryResult<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryResult<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 ? UseQueryResult<TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryResult<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryResult<TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<unknown, any>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<TData, unknown extends TError ? DefaultError : TError>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<\n TQueryFnData,\n unknown extends TError ? DefaultError : TError\n >\n : // Fallback\n UseQueryResult\n\n/**\n * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param\n */\nexport type QueriesOptions<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryOptionsForUseQueries>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetOptions<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>\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/homogenous type!\n // use this to infer the param types in the case of Array.map() argument\n T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >\n >\n ? Array<UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>>\n : // Fallback\n Array<UseQueryOptionsForUseQueries>\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryResult>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetResults<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>\n : T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >\n >\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n Array<\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n >\n : // Fallback\n Array<UseQueryResult>\n\nexport function useQueries<\n T extends Array<any>,\n TCombinedResult = QueriesResults<T>,\n>(\n {\n queries,\n ...options\n }: {\n queries: readonly [...QueriesOptions<T>]\n combine?: (result: QueriesResults<T>) => TCombinedResult\n },\n queryClient?: QueryClient,\n): TCombinedResult {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((opts) => {\n const defaultedOptions = client.defaultQueryOptions(opts)\n\n // Make sure the results are already in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n return defaultedOptions\n }),\n [queries, client, isRestoring],\n )\n\n defaultedQueries.forEach((query) => {\n ensureStaleTime(query)\n ensurePreventErrorBoundaryRetry(query, errorResetBoundary)\n })\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new QueriesObserver<TCombinedResult>(\n client,\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n ),\n )\n\n const [optimisticResult, getCombinedResult, trackResult] =\n observer.getOptimisticResult(defaultedQueries)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) =>\n isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\n }, [defaultedQueries, options, observer])\n\n const shouldAtLeastOneSuspend = optimisticResult.some((result, index) =>\n shouldSuspend(defaultedQueries[index], result, isRestoring),\n )\n\n const suspensePromises = shouldAtLeastOneSuspend\n ? optimisticResult.flatMap((result, index) => {\n const opts = defaultedQueries[index]\n const queryObserver = observer.getObservers()[index]\n\n if (opts && queryObserver) {\n if (shouldSuspend(opts, result, isRestoring)) {\n return fetchOptimistic(opts, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(opts, queryObserver, errorResetBoundary)\n }\n }\n return []\n })\n : []\n\n if (suspensePromises.length > 0) {\n throw Promise.all(suspensePromises)\n }\n const observerQueries = observer.getQueries()\n const firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) =>\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedQueries[index]?.throwOnError ?? false,\n query: observerQueries[index]!,\n }),\n )\n\n if (firstSingleResultWhichShouldThrow?.error) {\n throw firstSingleResultWhichShouldThrow.error\n }\n\n return getCombinedResult(trackResult())\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB,SAAS,iBAAiB,qBAAqB;AAC/C,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,kCAAkC;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAqKA,SAAS,WAId;AAAA,EACE;AAAA,EACA,GAAG;AACL,GAIA,aACiB;AACjB,QAAM,SAAS,eAAe,WAAW;AACzC,QAAM,cAAc,eAAe;AACnC,QAAM,qBAAqB,2BAA2B;AAEtD,QAAM,mBAAyB;AAAA,IAC7B,MACE,QAAQ,IAAI,CAAC,SAAS;AACpB,YAAM,mBAAmB,OAAO,oBAAoB,IAAI;AAGxD,uBAAiB,qBAAqB,cAClC,gBACA;AAEJ,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,SAAS,QAAQ,WAAW;AAAA,EAC/B;AAEA,mBAAiB,QAAQ,CAAC,UAAU;AAClC,oBAAgB,KAAK;AACrB,oCAAgC,OAAO,kBAAkB;AAAA,EAC3D,CAAC;AAED,6BAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,CAAC,kBAAkB,mBAAmB,WAAW,IACrD,SAAS,oBAAoB,gBAAgB;AAE/C,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBACC,cACI,MAAM,SACN,SAAS,UAAU,cAAc,WAAW,aAAa,CAAC;AAAA,MAChE,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,GAAG,CAAC,kBAAkB,SAAS,QAAQ,CAAC;AAExC,QAAM,0BAA0B,iBAAiB;AAAA,IAAK,CAAC,QAAQ,UAC7D,cAAc,iBAAiB,KAAK,GAAG,QAAQ,WAAW;AAAA,EAC5D;AAEA,QAAM,mBAAmB,0BACrB,iBAAiB,QAAQ,CAAC,QAAQ,UAAU;AAC1C,UAAM,OAAO,iBAAiB,KAAK;AACnC,UAAM,gBAAgB,SAAS,aAAa,EAAE,KAAK;AAEnD,QAAI,QAAQ,eAAe;AACzB,UAAI,cAAc,MAAM,QAAQ,WAAW,GAAG;AAC5C,eAAO,gBAAgB,MAAM,eAAe,kBAAkB;AAAA,MAChE,WAAW,UAAU,QAAQ,WAAW,GAAG;AACzC,aAAK,gBAAgB,MAAM,eAAe,kBAAkB;AAAA,MAC9D;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV,CAAC,IACD,CAAC;AAEL,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,QAAQ,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UACP,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA,cAAc,iBAAiB,KAAK,GAAG,gBAAgB;AAAA,MACvD,OAAO,gBAAgB,KAAK;AAAA,IAC9B,CAAC;AAAA,EACL;AAEA,MAAI,mCAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
1
+ {"version":3,"sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport {\n QueriesObserver,\n QueryObserver,\n notifyManager,\n} from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n fetchOptimistic,\n shouldSuspend,\n willFetch,\n} from './suspense'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport type {\n DefaultError,\n QueriesObserverOptions,\n QueriesPlaceholderDataFunction,\n QueryClient,\n QueryFunction,\n QueryKey,\n ThrowOnError,\n} from '@tanstack/query-core'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function always gets undefined passed\ntype UseQueryOptionsForUseQueries<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> = Omit<\n UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'placeholderData' | 'suspense'\n> & {\n placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>\n}\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetOptions<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<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 ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryOptionsForUseQueries<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TQueryFnData,\n TQueryKey\n >\n : // Fallback\n UseQueryOptionsForUseQueries\n\ntype GetResults<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 ? UseQueryResult<TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryResult<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryResult<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 ? UseQueryResult<TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryResult<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryResult<TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<unknown, any>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<TData, unknown extends TError ? DefaultError : TError>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<\n TQueryFnData,\n unknown extends TError ? DefaultError : TError\n >\n : // Fallback\n UseQueryResult\n\n/**\n * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param\n */\nexport type QueriesOptions<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryOptionsForUseQueries>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetOptions<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>\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/homogenous type!\n // use this to infer the param types in the case of Array.map() argument\n T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >\n >\n ? Array<UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>>\n : // Fallback\n Array<UseQueryOptionsForUseQueries>\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryResult>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetResults<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>\n : T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >\n >\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n Array<\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n >\n : // Fallback\n Array<UseQueryResult>\n\nexport function useQueries<\n T extends Array<any>,\n TCombinedResult = QueriesResults<T>,\n>(\n {\n queries,\n ...options\n }: {\n queries: readonly [...QueriesOptions<T>]\n combine?: (result: QueriesResults<T>) => TCombinedResult\n },\n queryClient?: QueryClient,\n): TCombinedResult {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((opts) => {\n const defaultedOptions = client.defaultQueryOptions(opts)\n\n // Make sure the results are already in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n return defaultedOptions\n }),\n [queries, client, isRestoring],\n )\n\n defaultedQueries.forEach((query) => {\n ensureStaleTime(query)\n ensurePreventErrorBoundaryRetry(query, errorResetBoundary)\n })\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new QueriesObserver<TCombinedResult>(\n client,\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n ),\n )\n\n const [optimisticResult, getCombinedResult, trackResult] =\n observer.getOptimisticResult(defaultedQueries)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) =>\n isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\n }, [defaultedQueries, options, observer])\n\n const shouldAtLeastOneSuspend = optimisticResult.some((result, index) =>\n shouldSuspend(defaultedQueries[index], result, isRestoring),\n )\n\n const suspensePromises = shouldAtLeastOneSuspend\n ? optimisticResult.flatMap((result, index) => {\n const opts = defaultedQueries[index]\n\n if (opts) {\n const queryObserver = new QueryObserver(client, opts)\n if (shouldSuspend(opts, result, isRestoring)) {\n return fetchOptimistic(opts, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(opts, queryObserver, errorResetBoundary)\n }\n }\n return []\n })\n : []\n\n if (suspensePromises.length > 0) {\n throw Promise.all(suspensePromises)\n }\n const observerQueries = observer.getQueries()\n const firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) =>\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedQueries[index]?.throwOnError ?? false,\n query: observerQueries[index]!,\n }),\n )\n\n if (firstSingleResultWhichShouldThrow?.error) {\n throw firstSingleResultWhichShouldThrow.error\n }\n\n return getCombinedResult(trackResult())\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,kCAAkC;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAqKA,SAAS,WAId;AAAA,EACE;AAAA,EACA,GAAG;AACL,GAIA,aACiB;AACjB,QAAM,SAAS,eAAe,WAAW;AACzC,QAAM,cAAc,eAAe;AACnC,QAAM,qBAAqB,2BAA2B;AAEtD,QAAM,mBAAyB;AAAA,IAC7B,MACE,QAAQ,IAAI,CAAC,SAAS;AACpB,YAAM,mBAAmB,OAAO,oBAAoB,IAAI;AAGxD,uBAAiB,qBAAqB,cAClC,gBACA;AAEJ,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,SAAS,QAAQ,WAAW;AAAA,EAC/B;AAEA,mBAAiB,QAAQ,CAAC,UAAU;AAClC,oBAAgB,KAAK;AACrB,oCAAgC,OAAO,kBAAkB;AAAA,EAC3D,CAAC;AAED,6BAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,CAAC,kBAAkB,mBAAmB,WAAW,IACrD,SAAS,oBAAoB,gBAAgB;AAE/C,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBACC,cACI,MAAM,SACN,SAAS,UAAU,cAAc,WAAW,aAAa,CAAC;AAAA,MAChE,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,GAAG,CAAC,kBAAkB,SAAS,QAAQ,CAAC;AAExC,QAAM,0BAA0B,iBAAiB;AAAA,IAAK,CAAC,QAAQ,UAC7D,cAAc,iBAAiB,KAAK,GAAG,QAAQ,WAAW;AAAA,EAC5D;AAEA,QAAM,mBAAmB,0BACrB,iBAAiB,QAAQ,CAAC,QAAQ,UAAU;AAC1C,UAAM,OAAO,iBAAiB,KAAK;AAEnC,QAAI,MAAM;AACR,YAAM,gBAAgB,IAAI,cAAc,QAAQ,IAAI;AACpD,UAAI,cAAc,MAAM,QAAQ,WAAW,GAAG;AAC5C,eAAO,gBAAgB,MAAM,eAAe,kBAAkB;AAAA,MAChE,WAAW,UAAU,QAAQ,WAAW,GAAG;AACzC,aAAK,gBAAgB,MAAM,eAAe,kBAAkB;AAAA,MAC9D;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV,CAAC,IACD,CAAC;AAEL,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,QAAQ,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UACP,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA,cAAc,iBAAiB,KAAK,GAAG,gBAAgB;AAAA,MACvD,OAAO,gBAAgB,KAAK;AAAA,IAC9B,CAAC;AAAA,EACL;AAEA,MAAI,mCAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-query",
3
- "version": "5.4.3",
3
+ "version": "5.7.1",
4
4
  "description": "Hooks for managing, caching and syncing asynchronous and remote data in React",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -6225,4 +6225,25 @@ describe('useQuery', () => {
6225
6225
 
6226
6226
  await waitFor(() => rendered.getByText('Works'))
6227
6227
  })
6228
+
6229
+ // For Project without TS, when migrating from v4 to v5, make sure invalid calls due to bad parameters are tracked.
6230
+ it('should throw in case of bad arguments to enhance DevX', async () => {
6231
+ // Mock console error to avoid noise when test is run
6232
+ const consoleMock = vi
6233
+ .spyOn(console, 'error')
6234
+ .mockImplementation(() => undefined)
6235
+
6236
+ const key = queryKey()
6237
+ const queryFn = () => 'data'
6238
+
6239
+ function Page() {
6240
+ // Invalid call on purpose
6241
+ // @ts-expect-error
6242
+ useQuery(key, { queryFn })
6243
+ return <div>Does not matter</div>
6244
+ }
6245
+
6246
+ expect(() => render(<Page />)).toThrow('Bad argument type')
6247
+ consoleMock.mockRestore()
6248
+ })
6228
6249
  })
@@ -0,0 +1,144 @@
1
+ import {
2
+ afterAll,
3
+ afterEach,
4
+ beforeAll,
5
+ describe,
6
+ expect,
7
+ it,
8
+ vi,
9
+ } from 'vitest'
10
+ import { act, render } from '@testing-library/react'
11
+ import React from 'react'
12
+ import { useSuspenseQueries } from '..'
13
+ import { createQueryClient, sleep } from './utils'
14
+ import type { UseSuspenseQueryOptions } from '..'
15
+
16
+ type NumberQueryOptions = UseSuspenseQueryOptions<number>
17
+
18
+ const QUERY_DURATION = 1000
19
+
20
+ const createQuery: (id: number) => NumberQueryOptions = (id) => ({
21
+ queryKey: [id],
22
+ queryFn: async () => {
23
+ await sleep(QUERY_DURATION)
24
+ return id
25
+ },
26
+ })
27
+ const resolveQueries = () => vi.advanceTimersByTimeAsync(QUERY_DURATION)
28
+
29
+ const queryClient = createQueryClient()
30
+
31
+ describe('useSuspenseQueries', () => {
32
+ const onSuspend = vi.fn()
33
+ const onQueriesResolution = vi.fn()
34
+
35
+ beforeAll(() => {
36
+ vi.useFakeTimers()
37
+ })
38
+
39
+ afterAll(() => {
40
+ vi.useRealTimers()
41
+ })
42
+
43
+ afterEach(() => {
44
+ queryClient.clear()
45
+ onSuspend.mockClear()
46
+ onQueriesResolution.mockClear()
47
+ })
48
+
49
+ function SuspenseFallback() {
50
+ React.useEffect(() => {
51
+ onSuspend()
52
+ }, [])
53
+
54
+ return null
55
+ }
56
+
57
+ const withSuspenseWrapper = <T extends object>(Component: React.FC<T>) => {
58
+ function SuspendedComponent(props: T) {
59
+ return (
60
+ <React.Suspense fallback={<SuspenseFallback />}>
61
+ <Component {...props} />
62
+ </React.Suspense>
63
+ )
64
+ }
65
+
66
+ return SuspendedComponent
67
+ }
68
+
69
+ function QueriesContainer({
70
+ queries,
71
+ }: {
72
+ queries: Array<NumberQueryOptions>
73
+ }) {
74
+ const queriesResults = useSuspenseQueries(
75
+ { queries, combine: (results) => results.map((r) => r.data) },
76
+ queryClient,
77
+ )
78
+
79
+ React.useEffect(() => {
80
+ onQueriesResolution(queriesResults)
81
+ }, [queriesResults])
82
+
83
+ return null
84
+ }
85
+
86
+ const TestComponent = withSuspenseWrapper(QueriesContainer)
87
+
88
+ it('should suspend on mount', () => {
89
+ render(<TestComponent queries={[1, 2].map(createQuery)} />)
90
+
91
+ expect(onSuspend).toHaveBeenCalledOnce()
92
+ })
93
+
94
+ it('should resolve queries', async () => {
95
+ render(<TestComponent queries={[1, 2].map(createQuery)} />)
96
+
97
+ await act(resolveQueries)
98
+
99
+ expect(onQueriesResolution).toHaveBeenCalledTimes(1)
100
+ expect(onQueriesResolution).toHaveBeenLastCalledWith([1, 2])
101
+ })
102
+
103
+ it('should not suspend on mount if query has been already fetched', () => {
104
+ const query = createQuery(1)
105
+
106
+ queryClient.setQueryData(query.queryKey, query.queryFn)
107
+
108
+ render(<TestComponent queries={[query]} />)
109
+
110
+ expect(onSuspend).not.toHaveBeenCalled()
111
+ })
112
+
113
+ it('should not break suspense when queries change without resolving', async () => {
114
+ const initQueries = [1, 2].map(createQuery)
115
+ const nextQueries = [3, 4, 5, 6].map(createQuery)
116
+
117
+ const { rerender } = render(<TestComponent queries={initQueries} />)
118
+
119
+ rerender(<TestComponent queries={nextQueries} />)
120
+
121
+ await act(resolveQueries)
122
+
123
+ expect(onSuspend).toHaveBeenCalledTimes(1)
124
+ expect(onQueriesResolution).toHaveBeenCalledTimes(1)
125
+ expect(onQueriesResolution).toHaveBeenLastCalledWith([3, 4, 5, 6])
126
+ })
127
+
128
+ it('should suspend only once per queries change', async () => {
129
+ const initQueries = [1, 2].map(createQuery)
130
+ const nextQueries = [3, 4, 5, 6].map(createQuery)
131
+
132
+ const { rerender } = render(<TestComponent queries={initQueries} />)
133
+
134
+ await act(resolveQueries)
135
+
136
+ rerender(<TestComponent queries={nextQueries} />)
137
+
138
+ await act(resolveQueries)
139
+
140
+ expect(onSuspend).toHaveBeenCalledTimes(2)
141
+ expect(onQueriesResolution).toHaveBeenCalledTimes(2)
142
+ expect(onQueriesResolution).toHaveBeenLastCalledWith([3, 4, 5, 6])
143
+ })
144
+ })
@@ -31,6 +31,14 @@ export function useBaseQuery<
31
31
  Observer: typeof QueryObserver,
32
32
  queryClient?: QueryClient,
33
33
  ) {
34
+ if (process.env.NODE_ENV !== 'production') {
35
+ if (typeof options !== 'object' || Array.isArray(options)) {
36
+ throw new Error(
37
+ 'Bad argument type. Starting with v5, only the "Object" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object',
38
+ )
39
+ }
40
+ }
41
+
34
42
  const client = useQueryClient(queryClient)
35
43
  const isRestoring = useIsRestoring()
36
44
  const errorResetBoundary = useQueryErrorResetBoundary()
package/src/useQueries.ts CHANGED
@@ -1,7 +1,11 @@
1
1
  'use client'
2
2
  import * as React from 'react'
3
3
 
4
- import { QueriesObserver, notifyManager } from '@tanstack/query-core'
4
+ import {
5
+ QueriesObserver,
6
+ QueryObserver,
7
+ notifyManager,
8
+ } from '@tanstack/query-core'
5
9
  import { useQueryClient } from './QueryClientProvider'
6
10
  import { useIsRestoring } from './isRestoring'
7
11
  import { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'
@@ -262,9 +266,9 @@ export function useQueries<
262
266
  const suspensePromises = shouldAtLeastOneSuspend
263
267
  ? optimisticResult.flatMap((result, index) => {
264
268
  const opts = defaultedQueries[index]
265
- const queryObserver = observer.getObservers()[index]
266
269
 
267
- if (opts && queryObserver) {
270
+ if (opts) {
271
+ const queryObserver = new QueryObserver(client, opts)
268
272
  if (shouldSuspend(opts, result, isRestoring)) {
269
273
  return fetchOptimistic(opts, queryObserver, errorResetBoundary)
270
274
  } else if (willFetch(result, isRestoring)) {