@tanstack/react-query 5.0.0-alpha.31 → 5.0.0-alpha.33

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 (45) hide show
  1. package/build/lib/useQueries.d.ts +3 -2
  2. package/build/lib/useQueries.esm.js +14 -13
  3. package/build/lib/useQueries.esm.js.map +1 -1
  4. package/build/lib/useQueries.js +14 -13
  5. package/build/lib/useQueries.js.map +1 -1
  6. package/build/lib/useQueries.mjs +14 -13
  7. package/build/lib/useQueries.mjs.map +1 -1
  8. package/build/umd/index.development.js +56 -34
  9. package/build/umd/index.development.js.map +1 -1
  10. package/build/umd/index.production.js +1 -1
  11. package/build/umd/index.production.js.map +1 -1
  12. package/package.json +2 -2
  13. package/src/__tests__/useQueries.test.tsx +195 -1
  14. package/src/useQueries.ts +32 -14
  15. package/build/lib/HydrationBoundary.d.ts.map +0 -1
  16. package/build/lib/QueryClientProvider.d.ts.map +0 -1
  17. package/build/lib/QueryErrorResetBoundary.d.ts.map +0 -1
  18. package/build/lib/__tests__/HydrationBoundary.test.d.ts.map +0 -1
  19. package/build/lib/__tests__/QueryClientProvider.test.d.ts.map +0 -1
  20. package/build/lib/__tests__/QueryResetErrorBoundary.test.d.ts.map +0 -1
  21. package/build/lib/__tests__/ssr-hydration.test.d.ts.map +0 -1
  22. package/build/lib/__tests__/ssr.test.d.ts.map +0 -1
  23. package/build/lib/__tests__/suspense.test.d.ts.map +0 -1
  24. package/build/lib/__tests__/useInfiniteQuery.test.d.ts.map +0 -1
  25. package/build/lib/__tests__/useInfiniteQuery.type.test.d.ts.map +0 -1
  26. package/build/lib/__tests__/useIsFetching.test.d.ts.map +0 -1
  27. package/build/lib/__tests__/useMutation.test.d.ts.map +0 -1
  28. package/build/lib/__tests__/useMutationState.test.d.ts.map +0 -1
  29. package/build/lib/__tests__/useQueries.test.d.ts.map +0 -1
  30. package/build/lib/__tests__/useQuery.test.d.ts.map +0 -1
  31. package/build/lib/__tests__/useQuery.types.test.d.ts.map +0 -1
  32. package/build/lib/__tests__/utils.d.ts.map +0 -1
  33. package/build/lib/errorBoundaryUtils.d.ts.map +0 -1
  34. package/build/lib/index.d.ts.map +0 -1
  35. package/build/lib/isRestoring.d.ts.map +0 -1
  36. package/build/lib/suspense.d.ts.map +0 -1
  37. package/build/lib/types.d.ts.map +0 -1
  38. package/build/lib/useBaseQuery.d.ts.map +0 -1
  39. package/build/lib/useInfiniteQuery.d.ts.map +0 -1
  40. package/build/lib/useIsFetching.d.ts.map +0 -1
  41. package/build/lib/useMutation.d.ts.map +0 -1
  42. package/build/lib/useMutationState.d.ts.map +0 -1
  43. package/build/lib/useQueries.d.ts.map +0 -1
  44. package/build/lib/useQuery.d.ts.map +0 -1
  45. package/build/lib/utils.d.ts.map +0 -1
@@ -44,8 +44,9 @@ export declare type QueriesOptions<T extends any[], Result extends any[] = [], D
44
44
  * QueriesResults reducer recursively maps type param to results
45
45
  */
46
46
  export declare type QueriesResults<T extends any[], Result extends any[] = [], Depth extends ReadonlyArray<number> = []> = Depth['length'] extends MAXIMUM_DEPTH ? UseQueryResult[] : T extends [] ? [] : T extends [infer Head] ? [...Result, GetResults<Head>] : T extends [infer Head, ...infer Tail] ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]> : T extends UseQueryOptionsForUseQueries<infer TQueryFnData, infer TError, infer TData, any>[] ? UseQueryResult<unknown extends TData ? TQueryFnData : TData, unknown extends TError ? DefaultError : TError>[] : UseQueryResult[];
47
- export declare function useQueries<T extends any[]>({ queries, }: {
47
+ export declare function useQueries<T extends any[], TCombinedResult = QueriesResults<T>>({ queries, ...options }: {
48
48
  queries: readonly [...QueriesOptions<T>];
49
- }, queryClient?: QueryClient): QueriesResults<T>;
49
+ combine?: (result: QueriesResults<T>) => TCombinedResult;
50
+ }, queryClient?: QueryClient): TCombinedResult;
50
51
  export {};
51
52
  //# sourceMappingURL=useQueries.d.ts.map
@@ -11,13 +11,14 @@ import { ensureStaleTime, shouldSuspend, fetchOptimistic, willFetch } from './su
11
11
  // `placeholderData` function does not have a parameter
12
12
 
13
13
  function useQueries({
14
- queries
14
+ queries,
15
+ ...options
15
16
  }, queryClient) {
16
17
  const client = useQueryClient(queryClient);
17
18
  const isRestoring = useIsRestoring();
18
19
  const errorResetBoundary = useQueryErrorResetBoundary();
19
- const defaultedQueries = React.useMemo(() => queries.map(options => {
20
- const defaultedOptions = client.defaultQueryOptions(options);
20
+ const defaultedQueries = React.useMemo(() => queries.map(opts => {
21
+ const defaultedOptions = client.defaultQueryOptions(opts);
21
22
 
22
23
  // Make sure the results are already in fetching state before subscribing or updating options
23
24
  defaultedOptions._optimisticResults = isRestoring ? 'isRestoring' : 'optimistic';
@@ -28,25 +29,25 @@ function useQueries({
28
29
  ensurePreventErrorBoundaryRetry(query, errorResetBoundary);
29
30
  });
30
31
  useClearResetErrorBoundary(errorResetBoundary);
31
- const [observer] = React.useState(() => new QueriesObserver(client, defaultedQueries));
32
- const optimisticResult = observer.getOptimisticResult(defaultedQueries);
32
+ const [observer] = React.useState(() => new QueriesObserver(client, defaultedQueries, options));
33
+ const [optimisticResult, getCombinedResult, trackResult] = observer.getOptimisticResult(defaultedQueries);
33
34
  React.useSyncExternalStore(React.useCallback(onStoreChange => isRestoring ? () => undefined : observer.subscribe(notifyManager.batchCalls(onStoreChange)), [observer, isRestoring]), () => observer.getCurrentResult(), () => observer.getCurrentResult());
34
35
  React.useEffect(() => {
35
36
  // Do not notify on updates because of changes in the options because
36
37
  // these changes should already be reflected in the optimistic result.
37
- observer.setQueries(defaultedQueries, {
38
+ observer.setQueries(defaultedQueries, options, {
38
39
  listeners: false
39
40
  });
40
- }, [defaultedQueries, observer]);
41
+ }, [defaultedQueries, options, observer]);
41
42
  const shouldAtLeastOneSuspend = optimisticResult.some((result, index) => shouldSuspend(defaultedQueries[index], result, isRestoring));
42
43
  const suspensePromises = shouldAtLeastOneSuspend ? optimisticResult.flatMap((result, index) => {
43
- const options = defaultedQueries[index];
44
+ const opts = defaultedQueries[index];
44
45
  const queryObserver = observer.getObservers()[index];
45
- if (options && queryObserver) {
46
- if (shouldSuspend(options, result, isRestoring)) {
47
- return fetchOptimistic(options, queryObserver, errorResetBoundary);
46
+ if (opts && queryObserver) {
47
+ if (shouldSuspend(opts, result, isRestoring)) {
48
+ return fetchOptimistic(opts, queryObserver, errorResetBoundary);
48
49
  } else if (willFetch(result, isRestoring)) {
49
- void fetchOptimistic(options, queryObserver, errorResetBoundary);
50
+ void fetchOptimistic(opts, queryObserver, errorResetBoundary);
50
51
  }
51
52
  }
52
53
  return [];
@@ -67,7 +68,7 @@ function useQueries({
67
68
  if (firstSingleResultWhichShouldThrow != null && firstSingleResultWhichShouldThrow.error) {
68
69
  throw firstSingleResultWhichShouldThrow.error;
69
70
  }
70
- return optimisticResult;
71
+ return getCombinedResult(trackResult());
71
72
  }
72
73
 
73
74
  export { useQueries };
@@ -1 +1 @@
1
- {"version":3,"file":"useQueries.esm.js","sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport type {\n QueryKey,\n QueryFunction,\n QueriesPlaceholderDataFunction,\n QueryClient,\n DefaultError,\n} from '@tanstack/query-core'\nimport { notifyManager, QueriesObserver } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n shouldSuspend,\n fetchOptimistic,\n willFetch,\n} from './suspense'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function does not have a parameter\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'\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 }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TData, TQueryKey>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey> }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TQueryFnData, TQueryKey>\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 }\n ? UseQueryResult<TData>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, any> }\n ? UseQueryResult<TQueryFnData>\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 any[],\n Result extends any[] = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? 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 : 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 UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >[]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>[]\n : // Fallback\n UseQueryOptionsForUseQueries[]\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends any[],\n Result extends any[] = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? 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 UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >[]\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >[]\n : // Fallback\n UseQueryResult[]\n\nexport function useQueries<T extends any[]>(\n {\n queries,\n }: {\n queries: readonly [...QueriesOptions<T>]\n },\n queryClient?: QueryClient,\n): QueriesResults<T> {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((options) => {\n const defaultedOptions = client.defaultQueryOptions(options)\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 () => new QueriesObserver(client, defaultedQueries),\n )\n\n const optimisticResult = 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(defaultedQueries, { listeners: false })\n }, [defaultedQueries, 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 options = defaultedQueries[index]\n const queryObserver = observer.getObservers()[index]\n\n if (options && queryObserver) {\n if (shouldSuspend(options, result, isRestoring)) {\n return fetchOptimistic(options, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(options, 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 optimisticResult as QueriesResults<T>\n}\n"],"names":["queries","defaultedOptions","defaultedQueries","ensurePreventErrorBoundaryRetry","observer","listeners"],"mappings":";;;;;;;;;AA2BA;AACA;;AAkIO;AAEHA;AAGF;AAGA;;;AAIA;AAGM;;AAEA;AACAC;AAIA;;AAKNC;;AAEEC;AACF;;AAIA;AAIA;;;AAeE;AACA;AACAC;AAAwCC;AAAiB;AAC3D;;AAMA;AAEM;;;;AAKI;;AAEA;AACF;AACF;AACA;;AAIN;AACE;AACF;AACA;;AAEgB;AAAA;;;;;AAMZ;;AAGJ;;AAEA;AAEA;AACF;;"}
1
+ {"version":3,"file":"useQueries.esm.js","sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport type {\n QueryKey,\n QueryFunction,\n QueriesPlaceholderDataFunction,\n QueryClient,\n DefaultError,\n QueriesObserverOptions,\n} from '@tanstack/query-core'\nimport { notifyManager, QueriesObserver } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n shouldSuspend,\n fetchOptimistic,\n willFetch,\n} from './suspense'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function does not have a parameter\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'\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 }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TData, TQueryKey>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey> }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TQueryFnData, TQueryKey>\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 }\n ? UseQueryResult<TData>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, any> }\n ? UseQueryResult<TQueryFnData>\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 any[],\n Result extends any[] = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? 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 : 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 UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >[]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>[]\n : // Fallback\n UseQueryOptionsForUseQueries[]\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends any[],\n Result extends any[] = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? 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 UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >[]\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >[]\n : // Fallback\n UseQueryResult[]\n\nexport function useQueries<\n T extends 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"],"names":["defaultedOptions","defaultedQueries","ensurePreventErrorBoundaryRetry","observer","listeners"],"mappings":";;;;;;;;;AA4BA;AACA;;AAkIO;;;AAUL;AAGA;;;AAIA;AAGM;;AAEA;AACAA;AAIA;;AAKNC;;AAEEC;AACF;;AAIA;AASA;;;AAgBE;AACA;AACAC;AAIIC;AACF;;;AAQJ;AAEM;;;;AAKI;;AAEA;AACF;AACF;AACA;;AAIN;AACE;AACF;AACA;;AAEgB;AAAA;;;;;AAMZ;;AAGJ;;AAEA;AAEA;AACF;;"}
@@ -32,13 +32,14 @@ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
32
32
  // `placeholderData` function does not have a parameter
33
33
 
34
34
  function useQueries({
35
- queries
35
+ queries,
36
+ ...options
36
37
  }, queryClient) {
37
38
  const client = QueryClientProvider.useQueryClient(queryClient);
38
39
  const isRestoring$1 = isRestoring.useIsRestoring();
39
40
  const errorResetBoundary = QueryErrorResetBoundary.useQueryErrorResetBoundary();
40
- const defaultedQueries = React__namespace.useMemo(() => queries.map(options => {
41
- const defaultedOptions = client.defaultQueryOptions(options);
41
+ const defaultedQueries = React__namespace.useMemo(() => queries.map(opts => {
42
+ const defaultedOptions = client.defaultQueryOptions(opts);
42
43
 
43
44
  // Make sure the results are already in fetching state before subscribing or updating options
44
45
  defaultedOptions._optimisticResults = isRestoring$1 ? 'isRestoring' : 'optimistic';
@@ -49,25 +50,25 @@ function useQueries({
49
50
  errorBoundaryUtils.ensurePreventErrorBoundaryRetry(query, errorResetBoundary);
50
51
  });
51
52
  errorBoundaryUtils.useClearResetErrorBoundary(errorResetBoundary);
52
- const [observer] = React__namespace.useState(() => new queryCore.QueriesObserver(client, defaultedQueries));
53
- const optimisticResult = observer.getOptimisticResult(defaultedQueries);
53
+ const [observer] = React__namespace.useState(() => new queryCore.QueriesObserver(client, defaultedQueries, options));
54
+ const [optimisticResult, getCombinedResult, trackResult] = observer.getOptimisticResult(defaultedQueries);
54
55
  React__namespace.useSyncExternalStore(React__namespace.useCallback(onStoreChange => isRestoring$1 ? () => undefined : observer.subscribe(queryCore.notifyManager.batchCalls(onStoreChange)), [observer, isRestoring$1]), () => observer.getCurrentResult(), () => observer.getCurrentResult());
55
56
  React__namespace.useEffect(() => {
56
57
  // Do not notify on updates because of changes in the options because
57
58
  // these changes should already be reflected in the optimistic result.
58
- observer.setQueries(defaultedQueries, {
59
+ observer.setQueries(defaultedQueries, options, {
59
60
  listeners: false
60
61
  });
61
- }, [defaultedQueries, observer]);
62
+ }, [defaultedQueries, options, observer]);
62
63
  const shouldAtLeastOneSuspend = optimisticResult.some((result, index) => suspense.shouldSuspend(defaultedQueries[index], result, isRestoring$1));
63
64
  const suspensePromises = shouldAtLeastOneSuspend ? optimisticResult.flatMap((result, index) => {
64
- const options = defaultedQueries[index];
65
+ const opts = defaultedQueries[index];
65
66
  const queryObserver = observer.getObservers()[index];
66
- if (options && queryObserver) {
67
- if (suspense.shouldSuspend(options, result, isRestoring$1)) {
68
- return suspense.fetchOptimistic(options, queryObserver, errorResetBoundary);
67
+ if (opts && queryObserver) {
68
+ if (suspense.shouldSuspend(opts, result, isRestoring$1)) {
69
+ return suspense.fetchOptimistic(opts, queryObserver, errorResetBoundary);
69
70
  } else if (suspense.willFetch(result, isRestoring$1)) {
70
- void suspense.fetchOptimistic(options, queryObserver, errorResetBoundary);
71
+ void suspense.fetchOptimistic(opts, queryObserver, errorResetBoundary);
71
72
  }
72
73
  }
73
74
  return [];
@@ -88,7 +89,7 @@ function useQueries({
88
89
  if (firstSingleResultWhichShouldThrow != null && firstSingleResultWhichShouldThrow.error) {
89
90
  throw firstSingleResultWhichShouldThrow.error;
90
91
  }
91
- return optimisticResult;
92
+ return getCombinedResult(trackResult());
92
93
  }
93
94
 
94
95
  exports.useQueries = useQueries;
@@ -1 +1 @@
1
- {"version":3,"file":"useQueries.js","sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport type {\n QueryKey,\n QueryFunction,\n QueriesPlaceholderDataFunction,\n QueryClient,\n DefaultError,\n} from '@tanstack/query-core'\nimport { notifyManager, QueriesObserver } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n shouldSuspend,\n fetchOptimistic,\n willFetch,\n} from './suspense'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function does not have a parameter\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'\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 }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TData, TQueryKey>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey> }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TQueryFnData, TQueryKey>\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 }\n ? UseQueryResult<TData>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, any> }\n ? UseQueryResult<TQueryFnData>\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 any[],\n Result extends any[] = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? 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 : 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 UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >[]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>[]\n : // Fallback\n UseQueryOptionsForUseQueries[]\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends any[],\n Result extends any[] = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? 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 UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >[]\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >[]\n : // Fallback\n UseQueryResult[]\n\nexport function useQueries<T extends any[]>(\n {\n queries,\n }: {\n queries: readonly [...QueriesOptions<T>]\n },\n queryClient?: QueryClient,\n): QueriesResults<T> {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((options) => {\n const defaultedOptions = client.defaultQueryOptions(options)\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 () => new QueriesObserver(client, defaultedQueries),\n )\n\n const optimisticResult = 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(defaultedQueries, { listeners: false })\n }, [defaultedQueries, 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 options = defaultedQueries[index]\n const queryObserver = observer.getObservers()[index]\n\n if (options && queryObserver) {\n if (shouldSuspend(options, result, isRestoring)) {\n return fetchOptimistic(options, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(options, 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 optimisticResult as QueriesResults<T>\n}\n"],"names":["queries","defaultedOptions","defaultedQueries","ensurePreventErrorBoundaryRetry","observer","listeners"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA;AACA;;AAkIO;AAEHA;AAGF;AAGA;;;AAIA;AAGM;;AAEA;AACAC;AAIA;;AAKNC;;AAEEC;AACF;;AAIA;AAIA;;;AAeE;AACA;AACAC;AAAwCC;AAAiB;AAC3D;;AAMA;AAEM;;;;AAKI;;AAEA;AACF;AACF;AACA;;AAIN;AACE;AACF;AACA;;AAEgB;AAAA;;;;;AAMZ;;AAGJ;;AAEA;AAEA;AACF;;"}
1
+ {"version":3,"file":"useQueries.js","sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport type {\n QueryKey,\n QueryFunction,\n QueriesPlaceholderDataFunction,\n QueryClient,\n DefaultError,\n QueriesObserverOptions,\n} from '@tanstack/query-core'\nimport { notifyManager, QueriesObserver } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n shouldSuspend,\n fetchOptimistic,\n willFetch,\n} from './suspense'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function does not have a parameter\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'\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 }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TData, TQueryKey>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey> }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TQueryFnData, TQueryKey>\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 }\n ? UseQueryResult<TData>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, any> }\n ? UseQueryResult<TQueryFnData>\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 any[],\n Result extends any[] = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? 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 : 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 UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >[]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>[]\n : // Fallback\n UseQueryOptionsForUseQueries[]\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends any[],\n Result extends any[] = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? 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 UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >[]\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >[]\n : // Fallback\n UseQueryResult[]\n\nexport function useQueries<\n T extends 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"],"names":["defaultedOptions","defaultedQueries","ensurePreventErrorBoundaryRetry","observer","listeners"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA;AACA;;AAkIO;;;AAUL;AAGA;;;AAIA;AAGM;;AAEA;AACAA;AAIA;;AAKNC;;AAEEC;AACF;;AAIA;AASA;;;AAgBE;AACA;AACAC;AAIIC;AACF;;;AAQJ;AAEM;;;;AAKI;;AAEA;AACF;AACF;AACA;;AAIN;AACE;AACF;AACA;;AAEgB;AAAA;;;;;AAMZ;;AAGJ;;AAEA;AAEA;AACF;;"}
@@ -11,13 +11,14 @@ import { ensureStaleTime, shouldSuspend, fetchOptimistic, willFetch } from './su
11
11
  // `placeholderData` function does not have a parameter
12
12
 
13
13
  function useQueries({
14
- queries
14
+ queries,
15
+ ...options
15
16
  }, queryClient) {
16
17
  const client = useQueryClient(queryClient);
17
18
  const isRestoring = useIsRestoring();
18
19
  const errorResetBoundary = useQueryErrorResetBoundary();
19
- const defaultedQueries = React.useMemo(() => queries.map(options => {
20
- const defaultedOptions = client.defaultQueryOptions(options);
20
+ const defaultedQueries = React.useMemo(() => queries.map(opts => {
21
+ const defaultedOptions = client.defaultQueryOptions(opts);
21
22
 
22
23
  // Make sure the results are already in fetching state before subscribing or updating options
23
24
  defaultedOptions._optimisticResults = isRestoring ? 'isRestoring' : 'optimistic';
@@ -28,25 +29,25 @@ function useQueries({
28
29
  ensurePreventErrorBoundaryRetry(query, errorResetBoundary);
29
30
  });
30
31
  useClearResetErrorBoundary(errorResetBoundary);
31
- const [observer] = React.useState(() => new QueriesObserver(client, defaultedQueries));
32
- const optimisticResult = observer.getOptimisticResult(defaultedQueries);
32
+ const [observer] = React.useState(() => new QueriesObserver(client, defaultedQueries, options));
33
+ const [optimisticResult, getCombinedResult, trackResult] = observer.getOptimisticResult(defaultedQueries);
33
34
  React.useSyncExternalStore(React.useCallback(onStoreChange => isRestoring ? () => undefined : observer.subscribe(notifyManager.batchCalls(onStoreChange)), [observer, isRestoring]), () => observer.getCurrentResult(), () => observer.getCurrentResult());
34
35
  React.useEffect(() => {
35
36
  // Do not notify on updates because of changes in the options because
36
37
  // these changes should already be reflected in the optimistic result.
37
- observer.setQueries(defaultedQueries, {
38
+ observer.setQueries(defaultedQueries, options, {
38
39
  listeners: false
39
40
  });
40
- }, [defaultedQueries, observer]);
41
+ }, [defaultedQueries, options, observer]);
41
42
  const shouldAtLeastOneSuspend = optimisticResult.some((result, index) => shouldSuspend(defaultedQueries[index], result, isRestoring));
42
43
  const suspensePromises = shouldAtLeastOneSuspend ? optimisticResult.flatMap((result, index) => {
43
- const options = defaultedQueries[index];
44
+ const opts = defaultedQueries[index];
44
45
  const queryObserver = observer.getObservers()[index];
45
- if (options && queryObserver) {
46
- if (shouldSuspend(options, result, isRestoring)) {
47
- return fetchOptimistic(options, queryObserver, errorResetBoundary);
46
+ if (opts && queryObserver) {
47
+ if (shouldSuspend(opts, result, isRestoring)) {
48
+ return fetchOptimistic(opts, queryObserver, errorResetBoundary);
48
49
  } else if (willFetch(result, isRestoring)) {
49
- void fetchOptimistic(options, queryObserver, errorResetBoundary);
50
+ void fetchOptimistic(opts, queryObserver, errorResetBoundary);
50
51
  }
51
52
  }
52
53
  return [];
@@ -64,7 +65,7 @@ function useQueries({
64
65
  if (firstSingleResultWhichShouldThrow?.error) {
65
66
  throw firstSingleResultWhichShouldThrow.error;
66
67
  }
67
- return optimisticResult;
68
+ return getCombinedResult(trackResult());
68
69
  }
69
70
 
70
71
  export { useQueries };
@@ -1 +1 @@
1
- {"version":3,"file":"useQueries.mjs","sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport type {\n QueryKey,\n QueryFunction,\n QueriesPlaceholderDataFunction,\n QueryClient,\n DefaultError,\n} from '@tanstack/query-core'\nimport { notifyManager, QueriesObserver } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n shouldSuspend,\n fetchOptimistic,\n willFetch,\n} from './suspense'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function does not have a parameter\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'\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 }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TData, TQueryKey>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey> }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TQueryFnData, TQueryKey>\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 }\n ? UseQueryResult<TData>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, any> }\n ? UseQueryResult<TQueryFnData>\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 any[],\n Result extends any[] = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? 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 : 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 UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >[]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>[]\n : // Fallback\n UseQueryOptionsForUseQueries[]\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends any[],\n Result extends any[] = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? 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 UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >[]\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >[]\n : // Fallback\n UseQueryResult[]\n\nexport function useQueries<T extends any[]>(\n {\n queries,\n }: {\n queries: readonly [...QueriesOptions<T>]\n },\n queryClient?: QueryClient,\n): QueriesResults<T> {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((options) => {\n const defaultedOptions = client.defaultQueryOptions(options)\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 () => new QueriesObserver(client, defaultedQueries),\n )\n\n const optimisticResult = 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(defaultedQueries, { listeners: false })\n }, [defaultedQueries, 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 options = defaultedQueries[index]\n const queryObserver = observer.getObservers()[index]\n\n if (options && queryObserver) {\n if (shouldSuspend(options, result, isRestoring)) {\n return fetchOptimistic(options, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(options, 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 optimisticResult as QueriesResults<T>\n}\n"],"names":["queries","defaultedOptions","defaultedQueries","ensurePreventErrorBoundaryRetry","observer","listeners"],"mappings":";;;;;;;;;AA2BA;AACA;;AAkIO;AAEHA;AAGF;AAGA;;;AAIA;AAGM;;AAEA;AACAC;AAIA;;AAKNC;;AAEEC;AACF;;AAIA;AAIA;;;AAeE;AACA;AACAC;AAAwCC;AAAiB;AAC3D;;AAMA;AAEM;;;;AAKI;;AAEA;AACF;AACF;AACA;;AAIN;AACE;AACF;AACA;AACA;;;;;AAOI;;;AAKJ;AAEA;AACF;;"}
1
+ {"version":3,"file":"useQueries.mjs","sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport type {\n QueryKey,\n QueryFunction,\n QueriesPlaceholderDataFunction,\n QueryClient,\n DefaultError,\n QueriesObserverOptions,\n} from '@tanstack/query-core'\nimport { notifyManager, QueriesObserver } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n shouldSuspend,\n fetchOptimistic,\n willFetch,\n} from './suspense'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function does not have a parameter\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'\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 }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TData, TQueryKey>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey> }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TQueryFnData, TQueryKey>\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 }\n ? UseQueryResult<TData>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, any> }\n ? UseQueryResult<TQueryFnData>\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 any[],\n Result extends any[] = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? 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 : 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 UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >[]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>[]\n : // Fallback\n UseQueryOptionsForUseQueries[]\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends any[],\n Result extends any[] = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? 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 UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >[]\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >[]\n : // Fallback\n UseQueryResult[]\n\nexport function useQueries<\n T extends 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"],"names":["defaultedOptions","defaultedQueries","ensurePreventErrorBoundaryRetry","observer","listeners"],"mappings":";;;;;;;;;AA4BA;AACA;;AAkIO;;;AAUL;AAGA;;;AAIA;AAGM;;AAEA;AACAA;AAIA;;AAKNC;;AAEEC;AACF;;AAIA;AASA;;;AAgBE;AACA;AACAC;AAIIC;AACF;;;AAQJ;AAEM;;;;AAKI;;AAEA;AACF;AACF;AACA;;AAIN;AACE;AACF;AACA;AACA;;;;;AAOI;;;AAKJ;AAEA;AACF;;"}
@@ -25,19 +25,19 @@
25
25
 
26
26
  class Subscribable {
27
27
  constructor() {
28
- this.listeners = [];
28
+ this.listeners = new Set();
29
29
  this.subscribe = this.subscribe.bind(this);
30
30
  }
31
31
  subscribe(listener) {
32
- this.listeners.push(listener);
32
+ this.listeners.add(listener);
33
33
  this.onSubscribe();
34
34
  return () => {
35
- this.listeners = this.listeners.filter(x => x !== listener);
35
+ this.listeners.delete(listener);
36
36
  this.onUnsubscribe();
37
37
  };
38
38
  }
39
39
  hasListeners() {
40
- return this.listeners.length > 0;
40
+ return this.listeners.size > 0;
41
41
  }
42
42
  onSubscribe() {
43
43
  // Do nothing
@@ -1894,7 +1894,7 @@
1894
1894
  this.refetch = this.refetch.bind(this);
1895
1895
  }
1896
1896
  onSubscribe() {
1897
- if (this.listeners.length === 1) {
1897
+ if (this.listeners.size === 1) {
1898
1898
  this.#currentQuery.addObserver(this);
1899
1899
  if (shouldFetchOnMount(this.#currentQuery, this.options)) {
1900
1900
  this.#executeFetch();
@@ -1903,7 +1903,7 @@
1903
1903
  }
1904
1904
  }
1905
1905
  onUnsubscribe() {
1906
- if (!this.listeners.length) {
1906
+ if (!this.hasListeners()) {
1907
1907
  this.destroy();
1908
1908
  }
1909
1909
  }
@@ -1914,7 +1914,7 @@
1914
1914
  return shouldFetchOn(this.#currentQuery, this.options, this.options.refetchOnWindowFocus);
1915
1915
  }
1916
1916
  destroy() {
1917
- this.listeners = [];
1917
+ this.listeners = new Set();
1918
1918
  this.#clearStaleTimeout();
1919
1919
  this.#clearRefetchInterval();
1920
1920
  this.#currentQuery.removeObserver(this);
@@ -2298,18 +2298,22 @@
2298
2298
  #result;
2299
2299
  #queries;
2300
2300
  #observers;
2301
- constructor(client, queries) {
2301
+ #options;
2302
+ #combinedResult;
2303
+ constructor(client, queries, options) {
2302
2304
  super();
2303
2305
  this.#client = client;
2304
2306
  this.#queries = [];
2305
- this.#result = [];
2306
2307
  this.#observers = [];
2307
- if (queries) {
2308
- this.setQueries(queries);
2309
- }
2308
+ this.#setResult([]);
2309
+ this.setQueries(queries, options);
2310
+ }
2311
+ #setResult(value) {
2312
+ this.#result = value;
2313
+ this.#combinedResult = this.#combineResult(value);
2310
2314
  }
2311
2315
  onSubscribe() {
2312
- if (this.listeners.length === 1) {
2316
+ if (this.listeners.size === 1) {
2313
2317
  this.#observers.forEach(observer => {
2314
2318
  observer.subscribe(result => {
2315
2319
  this.#onUpdate(observer, result);
@@ -2318,18 +2322,19 @@
2318
2322
  }
2319
2323
  }
2320
2324
  onUnsubscribe() {
2321
- if (!this.listeners.length) {
2325
+ if (!this.listeners.size) {
2322
2326
  this.destroy();
2323
2327
  }
2324
2328
  }
2325
2329
  destroy() {
2326
- this.listeners = [];
2330
+ this.listeners = new Set();
2327
2331
  this.#observers.forEach(observer => {
2328
2332
  observer.destroy();
2329
2333
  });
2330
2334
  }
2331
- setQueries(queries, notifyOptions) {
2335
+ setQueries(queries, options, notifyOptions) {
2332
2336
  this.#queries = queries;
2337
+ this.#options = options;
2333
2338
  notifyManager.batch(() => {
2334
2339
  const prevObservers = this.#observers;
2335
2340
  const newObserverMatches = this.#findMatchingObservers(this.#queries);
@@ -2343,7 +2348,7 @@
2343
2348
  return;
2344
2349
  }
2345
2350
  this.#observers = newObservers;
2346
- this.#result = newResult;
2351
+ this.#setResult(newResult);
2347
2352
  if (!this.hasListeners()) {
2348
2353
  return;
2349
2354
  }
@@ -2359,7 +2364,7 @@
2359
2364
  });
2360
2365
  }
2361
2366
  getCurrentResult() {
2362
- return this.#result;
2367
+ return this.#combinedResult;
2363
2368
  }
2364
2369
  getQueries() {
2365
2370
  return this.#observers.map(observer => observer.getCurrentQuery());
@@ -2368,7 +2373,23 @@
2368
2373
  return this.#observers;
2369
2374
  }
2370
2375
  getOptimisticResult(queries) {
2371
- return this.#findMatchingObservers(queries).map(match => match.observer.getOptimisticResult(match.defaultedQueryOptions));
2376
+ const matches = this.#findMatchingObservers(queries);
2377
+ const result = matches.map(match => match.observer.getOptimisticResult(match.defaultedQueryOptions));
2378
+ return [result, r => {
2379
+ return this.#combineResult(r ?? result);
2380
+ }, () => {
2381
+ return matches.map((match, index) => {
2382
+ const observerResult = result[index];
2383
+ return !match.defaultedQueryOptions.notifyOnChangeProps ? match.observer.trackResult(observerResult) : observerResult;
2384
+ });
2385
+ }];
2386
+ }
2387
+ #combineResult(input) {
2388
+ const combine = this.#options?.combine;
2389
+ if (combine) {
2390
+ return replaceEqualDeep(this.#combinedResult, combine(input));
2391
+ }
2392
+ return input;
2372
2393
  }
2373
2394
  #findMatchingObservers(queries) {
2374
2395
  const prevObservers = this.#observers;
@@ -2403,7 +2424,7 @@
2403
2424
  #onUpdate(observer, result) {
2404
2425
  const index = this.#observers.indexOf(observer);
2405
2426
  if (index !== -1) {
2406
- this.#result = replaceAt(this.#result, index, result);
2427
+ this.#setResult(replaceAt(this.#result, index, result));
2407
2428
  this.#notify();
2408
2429
  }
2409
2430
  }
@@ -2519,7 +2540,7 @@
2519
2540
  this.#currentMutation?.setOptions(this.options);
2520
2541
  }
2521
2542
  onUnsubscribe() {
2522
- if (!this.listeners.length) {
2543
+ if (!this.hasListeners()) {
2523
2544
  this.#currentMutation?.removeObserver(this);
2524
2545
  }
2525
2546
  }
@@ -2769,13 +2790,14 @@
2769
2790
  // `placeholderData` function does not have a parameter
2770
2791
 
2771
2792
  function useQueries({
2772
- queries
2793
+ queries,
2794
+ ...options
2773
2795
  }, queryClient) {
2774
2796
  const client = useQueryClient(queryClient);
2775
2797
  const isRestoring = useIsRestoring();
2776
2798
  const errorResetBoundary = useQueryErrorResetBoundary();
2777
- const defaultedQueries = React__namespace.useMemo(() => queries.map(options => {
2778
- const defaultedOptions = client.defaultQueryOptions(options);
2799
+ const defaultedQueries = React__namespace.useMemo(() => queries.map(opts => {
2800
+ const defaultedOptions = client.defaultQueryOptions(opts);
2779
2801
 
2780
2802
  // Make sure the results are already in fetching state before subscribing or updating options
2781
2803
  defaultedOptions._optimisticResults = isRestoring ? 'isRestoring' : 'optimistic';
@@ -2786,25 +2808,25 @@
2786
2808
  ensurePreventErrorBoundaryRetry(query, errorResetBoundary);
2787
2809
  });
2788
2810
  useClearResetErrorBoundary(errorResetBoundary);
2789
- const [observer] = React__namespace.useState(() => new QueriesObserver(client, defaultedQueries));
2790
- const optimisticResult = observer.getOptimisticResult(defaultedQueries);
2811
+ const [observer] = React__namespace.useState(() => new QueriesObserver(client, defaultedQueries, options));
2812
+ const [optimisticResult, getCombinedResult, trackResult] = observer.getOptimisticResult(defaultedQueries);
2791
2813
  React__namespace.useSyncExternalStore(React__namespace.useCallback(onStoreChange => isRestoring ? () => undefined : observer.subscribe(notifyManager.batchCalls(onStoreChange)), [observer, isRestoring]), () => observer.getCurrentResult(), () => observer.getCurrentResult());
2792
2814
  React__namespace.useEffect(() => {
2793
2815
  // Do not notify on updates because of changes in the options because
2794
2816
  // these changes should already be reflected in the optimistic result.
2795
- observer.setQueries(defaultedQueries, {
2817
+ observer.setQueries(defaultedQueries, options, {
2796
2818
  listeners: false
2797
2819
  });
2798
- }, [defaultedQueries, observer]);
2820
+ }, [defaultedQueries, options, observer]);
2799
2821
  const shouldAtLeastOneSuspend = optimisticResult.some((result, index) => shouldSuspend(defaultedQueries[index], result, isRestoring));
2800
2822
  const suspensePromises = shouldAtLeastOneSuspend ? optimisticResult.flatMap((result, index) => {
2801
- const options = defaultedQueries[index];
2823
+ const opts = defaultedQueries[index];
2802
2824
  const queryObserver = observer.getObservers()[index];
2803
- if (options && queryObserver) {
2804
- if (shouldSuspend(options, result, isRestoring)) {
2805
- return fetchOptimistic(options, queryObserver, errorResetBoundary);
2825
+ if (opts && queryObserver) {
2826
+ if (shouldSuspend(opts, result, isRestoring)) {
2827
+ return fetchOptimistic(opts, queryObserver, errorResetBoundary);
2806
2828
  } else if (willFetch(result, isRestoring)) {
2807
- void fetchOptimistic(options, queryObserver, errorResetBoundary);
2829
+ void fetchOptimistic(opts, queryObserver, errorResetBoundary);
2808
2830
  }
2809
2831
  }
2810
2832
  return [];
@@ -2822,7 +2844,7 @@
2822
2844
  if (firstSingleResultWhichShouldThrow?.error) {
2823
2845
  throw firstSingleResultWhichShouldThrow.error;
2824
2846
  }
2825
- return optimisticResult;
2847
+ return getCombinedResult(trackResult());
2826
2848
  }
2827
2849
 
2828
2850
  function useBaseQuery(options, Observer, queryClient) {