@tanstack/react-query 5.15.3 → 5.15.4
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.
- package/build/legacy/errorBoundaryUtils.cjs +1 -1
- package/build/legacy/errorBoundaryUtils.cjs.map +1 -1
- package/build/legacy/errorBoundaryUtils.d.cts +2 -2
- package/build/legacy/errorBoundaryUtils.d.ts +2 -2
- package/build/legacy/errorBoundaryUtils.js +1 -1
- package/build/legacy/errorBoundaryUtils.js.map +1 -1
- package/build/legacy/useBaseQuery.cjs +1 -2
- package/build/legacy/useBaseQuery.cjs.map +1 -1
- package/build/legacy/useBaseQuery.js +1 -2
- package/build/legacy/useBaseQuery.js.map +1 -1
- package/build/legacy/useQueries.cjs +4 -12
- package/build/legacy/useQueries.cjs.map +1 -1
- package/build/legacy/useQueries.js +4 -12
- package/build/legacy/useQueries.js.map +1 -1
- package/build/modern/errorBoundaryUtils.cjs +1 -1
- package/build/modern/errorBoundaryUtils.cjs.map +1 -1
- package/build/modern/errorBoundaryUtils.d.cts +2 -2
- package/build/modern/errorBoundaryUtils.d.ts +2 -2
- package/build/modern/errorBoundaryUtils.js +1 -1
- package/build/modern/errorBoundaryUtils.js.map +1 -1
- package/build/modern/useBaseQuery.cjs +1 -2
- package/build/modern/useBaseQuery.cjs.map +1 -1
- package/build/modern/useBaseQuery.js +1 -2
- package/build/modern/useBaseQuery.js.map +1 -1
- package/build/modern/useQueries.cjs +9 -14
- package/build/modern/useQueries.cjs.map +1 -1
- package/build/modern/useQueries.js +9 -14
- package/build/modern/useQueries.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/suspense.test.tsx +57 -0
- package/src/errorBoundaryUtils.ts +2 -1
- package/src/useBaseQuery.ts +8 -2
- package/src/useQueries.ts +12 -15
|
@@ -56,7 +56,7 @@ var getHasError = ({
|
|
|
56
56
|
throwOnError,
|
|
57
57
|
query
|
|
58
58
|
}) => {
|
|
59
|
-
return result.isError && !errorResetBoundary.isReset() && !result.isFetching && (0, import_utils.shouldThrowError)(throwOnError, [result.error, query]);
|
|
59
|
+
return result.isError && !errorResetBoundary.isReset() && !result.isFetching && query && (0, import_utils.shouldThrowError)(throwOnError, [result.error, query]);
|
|
60
60
|
};
|
|
61
61
|
// Annotate the CommonJS export names for ESM import in node:
|
|
62
62
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/errorBoundaryUtils.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\nimport { shouldThrowError } from './utils'\nimport type {\n DefaultedQueryObserverOptions,\n Query,\n QueryKey,\n QueryObserverResult,\n ThrowOnError,\n} from '@tanstack/query-core'\nimport type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'\n\nexport const ensurePreventErrorBoundaryRetry = <\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n if (options.suspense || options.throwOnError) {\n // Prevent retrying failed query if the error boundary has not been reset yet\n if (!errorResetBoundary.isReset()) {\n options.retryOnMount = false\n }\n }\n}\n\nexport const useClearResetErrorBoundary = (\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n React.useEffect(() => {\n errorResetBoundary.clearReset()\n }, [errorResetBoundary])\n}\n\nexport const getHasError = <\n TData,\n TError,\n TQueryFnData,\n TQueryData,\n TQueryKey extends QueryKey,\n>({\n result,\n errorResetBoundary,\n throwOnError,\n query,\n}: {\n result: QueryObserverResult<TData, TError>\n errorResetBoundary: QueryErrorResetBoundaryValue\n throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey
|
|
1
|
+
{"version":3,"sources":["../../src/errorBoundaryUtils.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\nimport { shouldThrowError } from './utils'\nimport type {\n DefaultedQueryObserverOptions,\n Query,\n QueryKey,\n QueryObserverResult,\n ThrowOnError,\n} from '@tanstack/query-core'\nimport type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'\n\nexport const ensurePreventErrorBoundaryRetry = <\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n if (options.suspense || options.throwOnError) {\n // Prevent retrying failed query if the error boundary has not been reset yet\n if (!errorResetBoundary.isReset()) {\n options.retryOnMount = false\n }\n }\n}\n\nexport const useClearResetErrorBoundary = (\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n React.useEffect(() => {\n errorResetBoundary.clearReset()\n }, [errorResetBoundary])\n}\n\nexport const getHasError = <\n TData,\n TError,\n TQueryFnData,\n TQueryData,\n TQueryKey extends QueryKey,\n>({\n result,\n errorResetBoundary,\n throwOnError,\n query,\n}: {\n result: QueryObserverResult<TData, TError>\n errorResetBoundary: QueryErrorResetBoundaryValue\n throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined\n}) => {\n return (\n result.isError &&\n !errorResetBoundary.isReset() &&\n !result.isFetching &&\n query &&\n shouldThrowError(throwOnError, [result.error, query])\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AACvB,mBAAiC;AAU1B,IAAM,kCAAkC,CAO7C,SAOA,uBACG;AACH,MAAI,QAAQ,YAAY,QAAQ,cAAc;AAE5C,QAAI,CAAC,mBAAmB,QAAQ,GAAG;AACjC,cAAQ,eAAe;AAAA,IACzB;AAAA,EACF;AACF;AAEO,IAAM,6BAA6B,CACxC,uBACG;AACH,EAAM,gBAAU,MAAM;AACpB,uBAAmB,WAAW;AAAA,EAChC,GAAG,CAAC,kBAAkB,CAAC;AACzB;AAEO,IAAM,cAAc,CAMzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAKM;AACJ,SACE,OAAO,WACP,CAAC,mBAAmB,QAAQ,KAC5B,CAAC,OAAO,cACR,aACA,+BAAiB,cAAc,CAAC,OAAO,OAAO,KAAK,CAAC;AAExD;","names":[]}
|
|
@@ -8,7 +8,7 @@ declare const getHasError: <TData, TError, TQueryFnData, TQueryData, TQueryKey e
|
|
|
8
8
|
result: QueryObserverResult<TData, TError>;
|
|
9
9
|
errorResetBoundary: QueryErrorResetBoundaryValue;
|
|
10
10
|
throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>;
|
|
11
|
-
query: Query<TQueryFnData, TError, TQueryData, TQueryKey
|
|
12
|
-
}) => boolean;
|
|
11
|
+
query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined;
|
|
12
|
+
}) => boolean | undefined;
|
|
13
13
|
|
|
14
14
|
export { ensurePreventErrorBoundaryRetry, getHasError, useClearResetErrorBoundary };
|
|
@@ -8,7 +8,7 @@ declare const getHasError: <TData, TError, TQueryFnData, TQueryData, TQueryKey e
|
|
|
8
8
|
result: QueryObserverResult<TData, TError>;
|
|
9
9
|
errorResetBoundary: QueryErrorResetBoundaryValue;
|
|
10
10
|
throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>;
|
|
11
|
-
query: Query<TQueryFnData, TError, TQueryData, TQueryKey
|
|
12
|
-
}) => boolean;
|
|
11
|
+
query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined;
|
|
12
|
+
}) => boolean | undefined;
|
|
13
13
|
|
|
14
14
|
export { ensurePreventErrorBoundaryRetry, getHasError, useClearResetErrorBoundary };
|
|
@@ -21,7 +21,7 @@ var getHasError = ({
|
|
|
21
21
|
throwOnError,
|
|
22
22
|
query
|
|
23
23
|
}) => {
|
|
24
|
-
return result.isError && !errorResetBoundary.isReset() && !result.isFetching && shouldThrowError(throwOnError, [result.error, query]);
|
|
24
|
+
return result.isError && !errorResetBoundary.isReset() && !result.isFetching && query && shouldThrowError(throwOnError, [result.error, query]);
|
|
25
25
|
};
|
|
26
26
|
export {
|
|
27
27
|
ensurePreventErrorBoundaryRetry,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/errorBoundaryUtils.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\nimport { shouldThrowError } from './utils'\nimport type {\n DefaultedQueryObserverOptions,\n Query,\n QueryKey,\n QueryObserverResult,\n ThrowOnError,\n} from '@tanstack/query-core'\nimport type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'\n\nexport const ensurePreventErrorBoundaryRetry = <\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n if (options.suspense || options.throwOnError) {\n // Prevent retrying failed query if the error boundary has not been reset yet\n if (!errorResetBoundary.isReset()) {\n options.retryOnMount = false\n }\n }\n}\n\nexport const useClearResetErrorBoundary = (\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n React.useEffect(() => {\n errorResetBoundary.clearReset()\n }, [errorResetBoundary])\n}\n\nexport const getHasError = <\n TData,\n TError,\n TQueryFnData,\n TQueryData,\n TQueryKey extends QueryKey,\n>({\n result,\n errorResetBoundary,\n throwOnError,\n query,\n}: {\n result: QueryObserverResult<TData, TError>\n errorResetBoundary: QueryErrorResetBoundaryValue\n throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey
|
|
1
|
+
{"version":3,"sources":["../../src/errorBoundaryUtils.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\nimport { shouldThrowError } from './utils'\nimport type {\n DefaultedQueryObserverOptions,\n Query,\n QueryKey,\n QueryObserverResult,\n ThrowOnError,\n} from '@tanstack/query-core'\nimport type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'\n\nexport const ensurePreventErrorBoundaryRetry = <\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n if (options.suspense || options.throwOnError) {\n // Prevent retrying failed query if the error boundary has not been reset yet\n if (!errorResetBoundary.isReset()) {\n options.retryOnMount = false\n }\n }\n}\n\nexport const useClearResetErrorBoundary = (\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n React.useEffect(() => {\n errorResetBoundary.clearReset()\n }, [errorResetBoundary])\n}\n\nexport const getHasError = <\n TData,\n TError,\n TQueryFnData,\n TQueryData,\n TQueryKey extends QueryKey,\n>({\n result,\n errorResetBoundary,\n throwOnError,\n query,\n}: {\n result: QueryObserverResult<TData, TError>\n errorResetBoundary: QueryErrorResetBoundaryValue\n throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined\n}) => {\n return (\n result.isError &&\n !errorResetBoundary.isReset() &&\n !result.isFetching &&\n query &&\n shouldThrowError(throwOnError, [result.error, query])\n )\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AACvB,SAAS,wBAAwB;AAU1B,IAAM,kCAAkC,CAO7C,SAOA,uBACG;AACH,MAAI,QAAQ,YAAY,QAAQ,cAAc;AAE5C,QAAI,CAAC,mBAAmB,QAAQ,GAAG;AACjC,cAAQ,eAAe;AAAA,IACzB;AAAA,EACF;AACF;AAEO,IAAM,6BAA6B,CACxC,uBACG;AACH,EAAM,gBAAU,MAAM;AACpB,uBAAmB,WAAW;AAAA,EAChC,GAAG,CAAC,kBAAkB,CAAC;AACzB;AAEO,IAAM,cAAc,CAMzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAKM;AACJ,SACE,OAAO,WACP,CAAC,mBAAmB,QAAQ,KAC5B,CAAC,OAAO,cACR,SACA,iBAAiB,cAAc,CAAC,OAAO,OAAO,KAAK,CAAC;AAExD;","names":[]}
|
|
@@ -80,14 +80,13 @@ function useBaseQuery(options, Observer, queryClient) {
|
|
|
80
80
|
observer.setOptions(defaultedOptions, { listeners: false });
|
|
81
81
|
}, [defaultedOptions, observer]);
|
|
82
82
|
if ((0, import_suspense.shouldSuspend)(defaultedOptions, result)) {
|
|
83
|
-
observer.setOptions(defaultedOptions, { listeners: false });
|
|
84
83
|
throw (0, import_suspense.fetchOptimistic)(defaultedOptions, observer, errorResetBoundary);
|
|
85
84
|
}
|
|
86
85
|
if ((0, import_errorBoundaryUtils.getHasError)({
|
|
87
86
|
result,
|
|
88
87
|
errorResetBoundary,
|
|
89
88
|
throwOnError: defaultedOptions.throwOnError,
|
|
90
|
-
query:
|
|
89
|
+
query: client.getQueryCache().get(defaultedOptions.queryHash)
|
|
91
90
|
})) {
|
|
92
91
|
throw result.error;
|
|
93
92
|
}
|
|
@@ -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 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)) {\n // Do the same thing as the effect right above because the effect won't run\n // when we suspend but also, the component won't re-mount so our observer would\n // be out of date.\n
|
|
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)) {\n // Do the same thing as the effect right above because the effect won't run\n // when we suspend but also, the component won't re-mount so our observer would\n // be out of date.\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: client\n .getQueryCache()\n .get<\n TQueryFnData,\n TError,\n TQueryData,\n TQueryKey\n >(defaultedOptions.queryHash),\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,MAAM,GAAG;AAI3C,cAAM,iCAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,UACE,uCAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,OACJ,cAAc,EACd,IAKC,iBAAiB,SAAS;AAAA,EAChC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
|
|
@@ -51,14 +51,13 @@ function useBaseQuery(options, Observer, queryClient) {
|
|
|
51
51
|
observer.setOptions(defaultedOptions, { listeners: false });
|
|
52
52
|
}, [defaultedOptions, observer]);
|
|
53
53
|
if (shouldSuspend(defaultedOptions, result)) {
|
|
54
|
-
observer.setOptions(defaultedOptions, { listeners: false });
|
|
55
54
|
throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary);
|
|
56
55
|
}
|
|
57
56
|
if (getHasError({
|
|
58
57
|
result,
|
|
59
58
|
errorResetBoundary,
|
|
60
59
|
throwOnError: defaultedOptions.throwOnError,
|
|
61
|
-
query:
|
|
60
|
+
query: client.getQueryCache().get(defaultedOptions.queryHash)
|
|
62
61
|
})) {
|
|
63
62
|
throw result.error;
|
|
64
63
|
}
|
|
@@ -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 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)) {\n // Do the same thing as the effect right above because the effect won't run\n // when we suspend but also, the component won't re-mount so our observer would\n // be out of date.\n
|
|
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)) {\n // Do the same thing as the effect right above because the effect won't run\n // when we suspend but also, the component won't re-mount so our observer would\n // be out of date.\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: client\n .getQueryCache()\n .get<\n TQueryFnData,\n TError,\n TQueryData,\n TQueryKey\n >(defaultedOptions.queryHash),\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,MAAM,GAAG;AAI3C,UAAM,gBAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,MACE,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,OACJ,cAAc,EACd,IAKC,iBAAiB,SAAS;AAAA,EAChC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
|
|
@@ -102,24 +102,16 @@ function useQueries({
|
|
|
102
102
|
return [];
|
|
103
103
|
}) : [];
|
|
104
104
|
if (suspensePromises.length > 0) {
|
|
105
|
-
observer.setQueries(
|
|
106
|
-
defaultedQueries,
|
|
107
|
-
options,
|
|
108
|
-
{
|
|
109
|
-
listeners: false
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
105
|
throw Promise.all(suspensePromises);
|
|
113
106
|
}
|
|
114
|
-
const observerQueries = observer.getQueries();
|
|
115
107
|
const firstSingleResultWhichShouldThrow = optimisticResult.find(
|
|
116
108
|
(result, index) => {
|
|
117
|
-
|
|
118
|
-
return (0, import_errorBoundaryUtils.getHasError)({
|
|
109
|
+
const query = defaultedQueries[index];
|
|
110
|
+
return query && (0, import_errorBoundaryUtils.getHasError)({
|
|
119
111
|
result,
|
|
120
112
|
errorResetBoundary,
|
|
121
|
-
throwOnError:
|
|
122
|
-
query:
|
|
113
|
+
throwOnError: query.throwOnError,
|
|
114
|
+
query: client.getQueryCache().get(query.queryHash)
|
|
123
115
|
});
|
|
124
116
|
}
|
|
125
117
|
);
|
|
@@ -1 +1 @@
|
|
|
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 {\n DefinedUseQueryResult,\n UseQueryOptions,\n UseQueryResult,\n} 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<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n : T extends {\n queryFn?: QueryFunction<\n infer TQueryFnData,\n infer TQueryKey\n >\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\n// A defined initialData setting should return a DefinedUseQueryResult rather than UseQueryResult\ntype GetDefinedOrUndefinedQueryResult<T, TData, TError = unknown> = T extends {\n initialData?: infer TInitialData\n}\n ? unknown extends TInitialData\n ? UseQueryResult<TData, TError>\n : TInitialData extends TData\n ? DefinedUseQueryResult<TData, TError>\n : TInitialData extends () => infer TInitialDataResult\n ? unknown extends TInitialDataResult\n ? UseQueryResult<TData, TError>\n : TInitialDataResult extends TData\n ? DefinedUseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, 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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n select?: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\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<\n [...Tail],\n [...Result, GetOptions<Head>],\n [...Depth, 1]\n >\n : Array<unknown> extends T\n ? T\n : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/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<\n UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n >\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<\n [...Tail],\n [...Result, GetResults<Head>],\n [...Depth, 1]\n >\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),\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)) {\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 observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\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;AAsNA,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,MAAM;AAAA,EAC/C;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,MAAM,GAAG;AAC/B,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,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AACA,UAAM,QAAQ,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UAAO;AAtVpB;AAuVM,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 {\n DefinedUseQueryResult,\n UseQueryOptions,\n UseQueryResult,\n} 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<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n : T extends {\n queryFn?: QueryFunction<\n infer TQueryFnData,\n infer TQueryKey\n >\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\n// A defined initialData setting should return a DefinedUseQueryResult rather than UseQueryResult\ntype GetDefinedOrUndefinedQueryResult<T, TData, TError = unknown> = T extends {\n initialData?: infer TInitialData\n}\n ? unknown extends TInitialData\n ? UseQueryResult<TData, TError>\n : TInitialData extends TData\n ? DefinedUseQueryResult<TData, TError>\n : TInitialData extends () => infer TInitialDataResult\n ? unknown extends TInitialDataResult\n ? UseQueryResult<TData, TError>\n : TInitialDataResult extends TData\n ? DefinedUseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, 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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n select?: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\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<\n [...Tail],\n [...Result, GetOptions<Head>],\n [...Depth, 1]\n >\n : Array<unknown> extends T\n ? T\n : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/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<\n UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n >\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<\n [...Tail],\n [...Result, GetResults<Head>],\n [...Depth, 1]\n >\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),\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)) {\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 firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) => {\n const query = defaultedQueries[index]\n return (\n query &&\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: query.throwOnError,\n query: client.getQueryCache().get(query.queryHash),\n })\n )\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;AAsNA,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,MAAM;AAAA,EAC/C;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,MAAM,GAAG;AAC/B,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,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UAAU;AACjB,YAAM,QAAQ,iBAAiB,KAAK;AACpC,aACE,aACA,uCAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA,cAAc,MAAM;AAAA,QACpB,OAAO,OAAO,cAAc,EAAE,IAAI,MAAM,SAAS;AAAA,MACnD,CAAC;AAAA,IAEL;AAAA,EACF;AAEA,MAAI,uFAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
|
|
@@ -82,24 +82,16 @@ function useQueries({
|
|
|
82
82
|
return [];
|
|
83
83
|
}) : [];
|
|
84
84
|
if (suspensePromises.length > 0) {
|
|
85
|
-
observer.setQueries(
|
|
86
|
-
defaultedQueries,
|
|
87
|
-
options,
|
|
88
|
-
{
|
|
89
|
-
listeners: false
|
|
90
|
-
}
|
|
91
|
-
);
|
|
92
85
|
throw Promise.all(suspensePromises);
|
|
93
86
|
}
|
|
94
|
-
const observerQueries = observer.getQueries();
|
|
95
87
|
const firstSingleResultWhichShouldThrow = optimisticResult.find(
|
|
96
88
|
(result, index) => {
|
|
97
|
-
|
|
98
|
-
return getHasError({
|
|
89
|
+
const query = defaultedQueries[index];
|
|
90
|
+
return query && getHasError({
|
|
99
91
|
result,
|
|
100
92
|
errorResetBoundary,
|
|
101
|
-
throwOnError:
|
|
102
|
-
query:
|
|
93
|
+
throwOnError: query.throwOnError,
|
|
94
|
+
query: client.getQueryCache().get(query.queryHash)
|
|
103
95
|
});
|
|
104
96
|
}
|
|
105
97
|
);
|
|
@@ -1 +1 @@
|
|
|
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 {\n DefinedUseQueryResult,\n UseQueryOptions,\n UseQueryResult,\n} 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<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n : T extends {\n queryFn?: QueryFunction<\n infer TQueryFnData,\n infer TQueryKey\n >\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\n// A defined initialData setting should return a DefinedUseQueryResult rather than UseQueryResult\ntype GetDefinedOrUndefinedQueryResult<T, TData, TError = unknown> = T extends {\n initialData?: infer TInitialData\n}\n ? unknown extends TInitialData\n ? UseQueryResult<TData, TError>\n : TInitialData extends TData\n ? DefinedUseQueryResult<TData, TError>\n : TInitialData extends () => infer TInitialDataResult\n ? unknown extends TInitialDataResult\n ? UseQueryResult<TData, TError>\n : TInitialDataResult extends TData\n ? DefinedUseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, 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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n select?: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\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<\n [...Tail],\n [...Result, GetOptions<Head>],\n [...Depth, 1]\n >\n : Array<unknown> extends T\n ? T\n : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/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<\n UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n >\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<\n [...Tail],\n [...Result, GetResults<Head>],\n [...Depth, 1]\n >\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),\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)) {\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 observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\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;AAsNA,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,MAAM;AAAA,EAC/C;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,MAAM,GAAG;AAC/B,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,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AACA,UAAM,QAAQ,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UAAO;AAtVpB;AAuVM,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 {\n DefinedUseQueryResult,\n UseQueryOptions,\n UseQueryResult,\n} 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<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n : T extends {\n queryFn?: QueryFunction<\n infer TQueryFnData,\n infer TQueryKey\n >\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\n// A defined initialData setting should return a DefinedUseQueryResult rather than UseQueryResult\ntype GetDefinedOrUndefinedQueryResult<T, TData, TError = unknown> = T extends {\n initialData?: infer TInitialData\n}\n ? unknown extends TInitialData\n ? UseQueryResult<TData, TError>\n : TInitialData extends TData\n ? DefinedUseQueryResult<TData, TError>\n : TInitialData extends () => infer TInitialDataResult\n ? unknown extends TInitialDataResult\n ? UseQueryResult<TData, TError>\n : TInitialDataResult extends TData\n ? DefinedUseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, 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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n select?: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\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<\n [...Tail],\n [...Result, GetOptions<Head>],\n [...Depth, 1]\n >\n : Array<unknown> extends T\n ? T\n : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/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<\n UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n >\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<\n [...Tail],\n [...Result, GetResults<Head>],\n [...Depth, 1]\n >\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),\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)) {\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 firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) => {\n const query = defaultedQueries[index]\n return (\n query &&\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: query.throwOnError,\n query: client.getQueryCache().get(query.queryHash),\n })\n )\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;AAsNA,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,MAAM;AAAA,EAC/C;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,MAAM,GAAG;AAC/B,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,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UAAU;AACjB,YAAM,QAAQ,iBAAiB,KAAK;AACpC,aACE,SACA,YAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA,cAAc,MAAM;AAAA,QACpB,OAAO,OAAO,cAAc,EAAE,IAAI,MAAM,SAAS;AAAA,MACnD,CAAC;AAAA,IAEL;AAAA,EACF;AAEA,MAAI,uFAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
|
|
@@ -56,7 +56,7 @@ var getHasError = ({
|
|
|
56
56
|
throwOnError,
|
|
57
57
|
query
|
|
58
58
|
}) => {
|
|
59
|
-
return result.isError && !errorResetBoundary.isReset() && !result.isFetching && (0, import_utils.shouldThrowError)(throwOnError, [result.error, query]);
|
|
59
|
+
return result.isError && !errorResetBoundary.isReset() && !result.isFetching && query && (0, import_utils.shouldThrowError)(throwOnError, [result.error, query]);
|
|
60
60
|
};
|
|
61
61
|
// Annotate the CommonJS export names for ESM import in node:
|
|
62
62
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/errorBoundaryUtils.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\nimport { shouldThrowError } from './utils'\nimport type {\n DefaultedQueryObserverOptions,\n Query,\n QueryKey,\n QueryObserverResult,\n ThrowOnError,\n} from '@tanstack/query-core'\nimport type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'\n\nexport const ensurePreventErrorBoundaryRetry = <\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n if (options.suspense || options.throwOnError) {\n // Prevent retrying failed query if the error boundary has not been reset yet\n if (!errorResetBoundary.isReset()) {\n options.retryOnMount = false\n }\n }\n}\n\nexport const useClearResetErrorBoundary = (\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n React.useEffect(() => {\n errorResetBoundary.clearReset()\n }, [errorResetBoundary])\n}\n\nexport const getHasError = <\n TData,\n TError,\n TQueryFnData,\n TQueryData,\n TQueryKey extends QueryKey,\n>({\n result,\n errorResetBoundary,\n throwOnError,\n query,\n}: {\n result: QueryObserverResult<TData, TError>\n errorResetBoundary: QueryErrorResetBoundaryValue\n throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey
|
|
1
|
+
{"version":3,"sources":["../../src/errorBoundaryUtils.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\nimport { shouldThrowError } from './utils'\nimport type {\n DefaultedQueryObserverOptions,\n Query,\n QueryKey,\n QueryObserverResult,\n ThrowOnError,\n} from '@tanstack/query-core'\nimport type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'\n\nexport const ensurePreventErrorBoundaryRetry = <\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n if (options.suspense || options.throwOnError) {\n // Prevent retrying failed query if the error boundary has not been reset yet\n if (!errorResetBoundary.isReset()) {\n options.retryOnMount = false\n }\n }\n}\n\nexport const useClearResetErrorBoundary = (\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n React.useEffect(() => {\n errorResetBoundary.clearReset()\n }, [errorResetBoundary])\n}\n\nexport const getHasError = <\n TData,\n TError,\n TQueryFnData,\n TQueryData,\n TQueryKey extends QueryKey,\n>({\n result,\n errorResetBoundary,\n throwOnError,\n query,\n}: {\n result: QueryObserverResult<TData, TError>\n errorResetBoundary: QueryErrorResetBoundaryValue\n throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined\n}) => {\n return (\n result.isError &&\n !errorResetBoundary.isReset() &&\n !result.isFetching &&\n query &&\n shouldThrowError(throwOnError, [result.error, query])\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AACvB,mBAAiC;AAU1B,IAAM,kCAAkC,CAO7C,SAOA,uBACG;AACH,MAAI,QAAQ,YAAY,QAAQ,cAAc;AAE5C,QAAI,CAAC,mBAAmB,QAAQ,GAAG;AACjC,cAAQ,eAAe;AAAA,IACzB;AAAA,EACF;AACF;AAEO,IAAM,6BAA6B,CACxC,uBACG;AACH,EAAM,gBAAU,MAAM;AACpB,uBAAmB,WAAW;AAAA,EAChC,GAAG,CAAC,kBAAkB,CAAC;AACzB;AAEO,IAAM,cAAc,CAMzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAKM;AACJ,SACE,OAAO,WACP,CAAC,mBAAmB,QAAQ,KAC5B,CAAC,OAAO,cACR,aACA,+BAAiB,cAAc,CAAC,OAAO,OAAO,KAAK,CAAC;AAExD;","names":[]}
|
|
@@ -8,7 +8,7 @@ declare const getHasError: <TData, TError, TQueryFnData, TQueryData, TQueryKey e
|
|
|
8
8
|
result: QueryObserverResult<TData, TError>;
|
|
9
9
|
errorResetBoundary: QueryErrorResetBoundaryValue;
|
|
10
10
|
throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>;
|
|
11
|
-
query: Query<TQueryFnData, TError, TQueryData, TQueryKey
|
|
12
|
-
}) => boolean;
|
|
11
|
+
query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined;
|
|
12
|
+
}) => boolean | undefined;
|
|
13
13
|
|
|
14
14
|
export { ensurePreventErrorBoundaryRetry, getHasError, useClearResetErrorBoundary };
|
|
@@ -8,7 +8,7 @@ declare const getHasError: <TData, TError, TQueryFnData, TQueryData, TQueryKey e
|
|
|
8
8
|
result: QueryObserverResult<TData, TError>;
|
|
9
9
|
errorResetBoundary: QueryErrorResetBoundaryValue;
|
|
10
10
|
throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>;
|
|
11
|
-
query: Query<TQueryFnData, TError, TQueryData, TQueryKey
|
|
12
|
-
}) => boolean;
|
|
11
|
+
query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined;
|
|
12
|
+
}) => boolean | undefined;
|
|
13
13
|
|
|
14
14
|
export { ensurePreventErrorBoundaryRetry, getHasError, useClearResetErrorBoundary };
|
|
@@ -21,7 +21,7 @@ var getHasError = ({
|
|
|
21
21
|
throwOnError,
|
|
22
22
|
query
|
|
23
23
|
}) => {
|
|
24
|
-
return result.isError && !errorResetBoundary.isReset() && !result.isFetching && shouldThrowError(throwOnError, [result.error, query]);
|
|
24
|
+
return result.isError && !errorResetBoundary.isReset() && !result.isFetching && query && shouldThrowError(throwOnError, [result.error, query]);
|
|
25
25
|
};
|
|
26
26
|
export {
|
|
27
27
|
ensurePreventErrorBoundaryRetry,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/errorBoundaryUtils.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\nimport { shouldThrowError } from './utils'\nimport type {\n DefaultedQueryObserverOptions,\n Query,\n QueryKey,\n QueryObserverResult,\n ThrowOnError,\n} from '@tanstack/query-core'\nimport type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'\n\nexport const ensurePreventErrorBoundaryRetry = <\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n if (options.suspense || options.throwOnError) {\n // Prevent retrying failed query if the error boundary has not been reset yet\n if (!errorResetBoundary.isReset()) {\n options.retryOnMount = false\n }\n }\n}\n\nexport const useClearResetErrorBoundary = (\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n React.useEffect(() => {\n errorResetBoundary.clearReset()\n }, [errorResetBoundary])\n}\n\nexport const getHasError = <\n TData,\n TError,\n TQueryFnData,\n TQueryData,\n TQueryKey extends QueryKey,\n>({\n result,\n errorResetBoundary,\n throwOnError,\n query,\n}: {\n result: QueryObserverResult<TData, TError>\n errorResetBoundary: QueryErrorResetBoundaryValue\n throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey
|
|
1
|
+
{"version":3,"sources":["../../src/errorBoundaryUtils.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\nimport { shouldThrowError } from './utils'\nimport type {\n DefaultedQueryObserverOptions,\n Query,\n QueryKey,\n QueryObserverResult,\n ThrowOnError,\n} from '@tanstack/query-core'\nimport type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'\n\nexport const ensurePreventErrorBoundaryRetry = <\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n if (options.suspense || options.throwOnError) {\n // Prevent retrying failed query if the error boundary has not been reset yet\n if (!errorResetBoundary.isReset()) {\n options.retryOnMount = false\n }\n }\n}\n\nexport const useClearResetErrorBoundary = (\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n React.useEffect(() => {\n errorResetBoundary.clearReset()\n }, [errorResetBoundary])\n}\n\nexport const getHasError = <\n TData,\n TError,\n TQueryFnData,\n TQueryData,\n TQueryKey extends QueryKey,\n>({\n result,\n errorResetBoundary,\n throwOnError,\n query,\n}: {\n result: QueryObserverResult<TData, TError>\n errorResetBoundary: QueryErrorResetBoundaryValue\n throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined\n}) => {\n return (\n result.isError &&\n !errorResetBoundary.isReset() &&\n !result.isFetching &&\n query &&\n shouldThrowError(throwOnError, [result.error, query])\n )\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AACvB,SAAS,wBAAwB;AAU1B,IAAM,kCAAkC,CAO7C,SAOA,uBACG;AACH,MAAI,QAAQ,YAAY,QAAQ,cAAc;AAE5C,QAAI,CAAC,mBAAmB,QAAQ,GAAG;AACjC,cAAQ,eAAe;AAAA,IACzB;AAAA,EACF;AACF;AAEO,IAAM,6BAA6B,CACxC,uBACG;AACH,EAAM,gBAAU,MAAM;AACpB,uBAAmB,WAAW;AAAA,EAChC,GAAG,CAAC,kBAAkB,CAAC;AACzB;AAEO,IAAM,cAAc,CAMzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAKM;AACJ,SACE,OAAO,WACP,CAAC,mBAAmB,QAAQ,KAC5B,CAAC,OAAO,cACR,SACA,iBAAiB,cAAc,CAAC,OAAO,OAAO,KAAK,CAAC;AAExD;","names":[]}
|
|
@@ -80,14 +80,13 @@ function useBaseQuery(options, Observer, queryClient) {
|
|
|
80
80
|
observer.setOptions(defaultedOptions, { listeners: false });
|
|
81
81
|
}, [defaultedOptions, observer]);
|
|
82
82
|
if ((0, import_suspense.shouldSuspend)(defaultedOptions, result)) {
|
|
83
|
-
observer.setOptions(defaultedOptions, { listeners: false });
|
|
84
83
|
throw (0, import_suspense.fetchOptimistic)(defaultedOptions, observer, errorResetBoundary);
|
|
85
84
|
}
|
|
86
85
|
if ((0, import_errorBoundaryUtils.getHasError)({
|
|
87
86
|
result,
|
|
88
87
|
errorResetBoundary,
|
|
89
88
|
throwOnError: defaultedOptions.throwOnError,
|
|
90
|
-
query:
|
|
89
|
+
query: client.getQueryCache().get(defaultedOptions.queryHash)
|
|
91
90
|
})) {
|
|
92
91
|
throw result.error;
|
|
93
92
|
}
|
|
@@ -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 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)) {\n // Do the same thing as the effect right above because the effect won't run\n // when we suspend but also, the component won't re-mount so our observer would\n // be out of date.\n
|
|
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)) {\n // Do the same thing as the effect right above because the effect won't run\n // when we suspend but also, the component won't re-mount so our observer would\n // be out of date.\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: client\n .getQueryCache()\n .get<\n TQueryFnData,\n TError,\n TQueryData,\n TQueryKey\n >(defaultedOptions.queryHash),\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,MAAM,GAAG;AAI3C,cAAM,iCAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,UACE,uCAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,OACJ,cAAc,EACd,IAKC,iBAAiB,SAAS;AAAA,EAChC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
|
|
@@ -51,14 +51,13 @@ function useBaseQuery(options, Observer, queryClient) {
|
|
|
51
51
|
observer.setOptions(defaultedOptions, { listeners: false });
|
|
52
52
|
}, [defaultedOptions, observer]);
|
|
53
53
|
if (shouldSuspend(defaultedOptions, result)) {
|
|
54
|
-
observer.setOptions(defaultedOptions, { listeners: false });
|
|
55
54
|
throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary);
|
|
56
55
|
}
|
|
57
56
|
if (getHasError({
|
|
58
57
|
result,
|
|
59
58
|
errorResetBoundary,
|
|
60
59
|
throwOnError: defaultedOptions.throwOnError,
|
|
61
|
-
query:
|
|
60
|
+
query: client.getQueryCache().get(defaultedOptions.queryHash)
|
|
62
61
|
})) {
|
|
63
62
|
throw result.error;
|
|
64
63
|
}
|
|
@@ -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 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)) {\n // Do the same thing as the effect right above because the effect won't run\n // when we suspend but also, the component won't re-mount so our observer would\n // be out of date.\n
|
|
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)) {\n // Do the same thing as the effect right above because the effect won't run\n // when we suspend but also, the component won't re-mount so our observer would\n // be out of date.\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: client\n .getQueryCache()\n .get<\n TQueryFnData,\n TError,\n TQueryData,\n TQueryKey\n >(defaultedOptions.queryHash),\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,MAAM,GAAG;AAI3C,UAAM,gBAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,MACE,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,OACJ,cAAc,EACd,IAKC,iBAAiB,SAAS;AAAA,EAChC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
|
|
@@ -102,23 +102,18 @@ function useQueries({
|
|
|
102
102
|
return [];
|
|
103
103
|
}) : [];
|
|
104
104
|
if (suspensePromises.length > 0) {
|
|
105
|
-
observer.setQueries(
|
|
106
|
-
defaultedQueries,
|
|
107
|
-
options,
|
|
108
|
-
{
|
|
109
|
-
listeners: false
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
105
|
throw Promise.all(suspensePromises);
|
|
113
106
|
}
|
|
114
|
-
const observerQueries = observer.getQueries();
|
|
115
107
|
const firstSingleResultWhichShouldThrow = optimisticResult.find(
|
|
116
|
-
(result, index) =>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
108
|
+
(result, index) => {
|
|
109
|
+
const query = defaultedQueries[index];
|
|
110
|
+
return query && (0, import_errorBoundaryUtils.getHasError)({
|
|
111
|
+
result,
|
|
112
|
+
errorResetBoundary,
|
|
113
|
+
throwOnError: query.throwOnError,
|
|
114
|
+
query: client.getQueryCache().get(query.queryHash)
|
|
115
|
+
});
|
|
116
|
+
}
|
|
122
117
|
);
|
|
123
118
|
if (firstSingleResultWhichShouldThrow?.error) {
|
|
124
119
|
throw firstSingleResultWhichShouldThrow.error;
|
|
@@ -1 +1 @@
|
|
|
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 {\n DefinedUseQueryResult,\n UseQueryOptions,\n UseQueryResult,\n} 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<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n : T extends {\n queryFn?: QueryFunction<\n infer TQueryFnData,\n infer TQueryKey\n >\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\n// A defined initialData setting should return a DefinedUseQueryResult rather than UseQueryResult\ntype GetDefinedOrUndefinedQueryResult<T, TData, TError = unknown> = T extends {\n initialData?: infer TInitialData\n}\n ? unknown extends TInitialData\n ? UseQueryResult<TData, TError>\n : TInitialData extends TData\n ? DefinedUseQueryResult<TData, TError>\n : TInitialData extends () => infer TInitialDataResult\n ? unknown extends TInitialDataResult\n ? UseQueryResult<TData, TError>\n : TInitialDataResult extends TData\n ? DefinedUseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, 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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n select?: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\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<\n [...Tail],\n [...Result, GetOptions<Head>],\n [...Depth, 1]\n >\n : Array<unknown> extends T\n ? T\n : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/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<\n UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n >\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<\n [...Tail],\n [...Result, GetResults<Head>],\n [...Depth, 1]\n >\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),\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)) {\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 observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\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;AAsNA,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,MAAM;AAAA,EAC/C;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,MAAM,GAAG;AAC/B,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,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AACA,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 {\n DefinedUseQueryResult,\n UseQueryOptions,\n UseQueryResult,\n} 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<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n : T extends {\n queryFn?: QueryFunction<\n infer TQueryFnData,\n infer TQueryKey\n >\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\n// A defined initialData setting should return a DefinedUseQueryResult rather than UseQueryResult\ntype GetDefinedOrUndefinedQueryResult<T, TData, TError = unknown> = T extends {\n initialData?: infer TInitialData\n}\n ? unknown extends TInitialData\n ? UseQueryResult<TData, TError>\n : TInitialData extends TData\n ? DefinedUseQueryResult<TData, TError>\n : TInitialData extends () => infer TInitialDataResult\n ? unknown extends TInitialDataResult\n ? UseQueryResult<TData, TError>\n : TInitialDataResult extends TData\n ? DefinedUseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, 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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n select?: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\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<\n [...Tail],\n [...Result, GetOptions<Head>],\n [...Depth, 1]\n >\n : Array<unknown> extends T\n ? T\n : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/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<\n UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n >\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<\n [...Tail],\n [...Result, GetResults<Head>],\n [...Depth, 1]\n >\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),\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)) {\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 firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) => {\n const query = defaultedQueries[index]\n return (\n query &&\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: query.throwOnError,\n query: client.getQueryCache().get(query.queryHash),\n })\n )\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;AAsNA,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,MAAM;AAAA,EAC/C;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,MAAM,GAAG;AAC/B,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,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UAAU;AACjB,YAAM,QAAQ,iBAAiB,KAAK;AACpC,aACE,aACA,uCAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA,cAAc,MAAM;AAAA,QACpB,OAAO,OAAO,cAAc,EAAE,IAAI,MAAM,SAAS;AAAA,MACnD,CAAC;AAAA,IAEL;AAAA,EACF;AAEA,MAAI,mCAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
|
|
@@ -82,23 +82,18 @@ function useQueries({
|
|
|
82
82
|
return [];
|
|
83
83
|
}) : [];
|
|
84
84
|
if (suspensePromises.length > 0) {
|
|
85
|
-
observer.setQueries(
|
|
86
|
-
defaultedQueries,
|
|
87
|
-
options,
|
|
88
|
-
{
|
|
89
|
-
listeners: false
|
|
90
|
-
}
|
|
91
|
-
);
|
|
92
85
|
throw Promise.all(suspensePromises);
|
|
93
86
|
}
|
|
94
|
-
const observerQueries = observer.getQueries();
|
|
95
87
|
const firstSingleResultWhichShouldThrow = optimisticResult.find(
|
|
96
|
-
(result, index) =>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
88
|
+
(result, index) => {
|
|
89
|
+
const query = defaultedQueries[index];
|
|
90
|
+
return query && getHasError({
|
|
91
|
+
result,
|
|
92
|
+
errorResetBoundary,
|
|
93
|
+
throwOnError: query.throwOnError,
|
|
94
|
+
query: client.getQueryCache().get(query.queryHash)
|
|
95
|
+
});
|
|
96
|
+
}
|
|
102
97
|
);
|
|
103
98
|
if (firstSingleResultWhichShouldThrow?.error) {
|
|
104
99
|
throw firstSingleResultWhichShouldThrow.error;
|
|
@@ -1 +1 @@
|
|
|
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 {\n DefinedUseQueryResult,\n UseQueryOptions,\n UseQueryResult,\n} 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<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n : T extends {\n queryFn?: QueryFunction<\n infer TQueryFnData,\n infer TQueryKey\n >\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\n// A defined initialData setting should return a DefinedUseQueryResult rather than UseQueryResult\ntype GetDefinedOrUndefinedQueryResult<T, TData, TError = unknown> = T extends {\n initialData?: infer TInitialData\n}\n ? unknown extends TInitialData\n ? UseQueryResult<TData, TError>\n : TInitialData extends TData\n ? DefinedUseQueryResult<TData, TError>\n : TInitialData extends () => infer TInitialDataResult\n ? unknown extends TInitialDataResult\n ? UseQueryResult<TData, TError>\n : TInitialDataResult extends TData\n ? DefinedUseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, 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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n select?: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\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<\n [...Tail],\n [...Result, GetOptions<Head>],\n [...Depth, 1]\n >\n : Array<unknown> extends T\n ? T\n : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/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<\n UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n >\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<\n [...Tail],\n [...Result, GetResults<Head>],\n [...Depth, 1]\n >\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),\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)) {\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 observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\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;AAsNA,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,MAAM;AAAA,EAC/C;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,MAAM,GAAG;AAC/B,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,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AACA,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 {\n DefinedUseQueryResult,\n UseQueryOptions,\n UseQueryResult,\n} 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<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n : T extends {\n queryFn?: QueryFunction<\n infer TQueryFnData,\n infer TQueryKey\n >\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\n// A defined initialData setting should return a DefinedUseQueryResult rather than UseQueryResult\ntype GetDefinedOrUndefinedQueryResult<T, TData, TError = unknown> = T extends {\n initialData?: infer TInitialData\n}\n ? unknown extends TInitialData\n ? UseQueryResult<TData, TError>\n : TInitialData extends TData\n ? DefinedUseQueryResult<TData, TError>\n : TInitialData extends () => infer TInitialDataResult\n ? unknown extends TInitialDataResult\n ? UseQueryResult<TData, TError>\n : TInitialDataResult extends TData\n ? DefinedUseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\n : UseQueryResult<TData, TError>\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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? GetDefinedOrUndefinedQueryResult<T, 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 ? GetDefinedOrUndefinedQueryResult<T, TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? GetDefinedOrUndefinedQueryResult<T, TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n select?: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? GetDefinedOrUndefinedQueryResult<\n T,\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<\n [...Tail],\n [...Result, GetOptions<Head>],\n [...Depth, 1]\n >\n : Array<unknown> extends T\n ? T\n : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/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<\n UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n >\n >\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<\n [...Tail],\n [...Result, GetResults<Head>],\n [...Depth, 1]\n >\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),\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)) {\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 firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) => {\n const query = defaultedQueries[index]\n return (\n query &&\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: query.throwOnError,\n query: client.getQueryCache().get(query.queryHash),\n })\n )\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;AAsNA,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,MAAM;AAAA,EAC/C;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,MAAM,GAAG;AAC/B,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,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UAAU;AACjB,YAAM,QAAQ,iBAAiB,KAAK;AACpC,aACE,SACA,YAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA,cAAc,MAAM;AAAA,QACpB,OAAO,OAAO,cAAc,EAAE,IAAI,MAAM,SAAS;AAAA,MACnD,CAAC;AAAA,IAEL;AAAA,EACF;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.15.
|
|
3
|
+
"version": "5.15.4",
|
|
4
4
|
"description": "Hooks for managing, caching and syncing asynchronous and remote data in React",
|
|
5
5
|
"author": "tannerlinsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"!build/codemods/**/__tests__"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@tanstack/query-core": "5.
|
|
44
|
+
"@tanstack/query-core": "5.15.4"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/react": "^18.2.45",
|
|
@@ -1033,4 +1033,61 @@ describe('useSuspenseQueries', () => {
|
|
|
1033
1033
|
|
|
1034
1034
|
await waitFor(() => rendered.getByText('data1'))
|
|
1035
1035
|
})
|
|
1036
|
+
|
|
1037
|
+
it('should not request old data inside transitions (issue #6486)', async () => {
|
|
1038
|
+
const key = queryKey()
|
|
1039
|
+
let queryFnCount = 0
|
|
1040
|
+
|
|
1041
|
+
function App() {
|
|
1042
|
+
const [count, setCount] = React.useState(0)
|
|
1043
|
+
|
|
1044
|
+
return (
|
|
1045
|
+
<div>
|
|
1046
|
+
<button
|
|
1047
|
+
onClick={() => React.startTransition(() => setCount(count + 1))}
|
|
1048
|
+
>
|
|
1049
|
+
inc
|
|
1050
|
+
</button>
|
|
1051
|
+
<React.Suspense fallback={'Loading...'}>
|
|
1052
|
+
<Page count={count} />
|
|
1053
|
+
</React.Suspense>
|
|
1054
|
+
</div>
|
|
1055
|
+
)
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
function Page({ count }: { count: number }) {
|
|
1059
|
+
const { data } = useSuspenseQuery({
|
|
1060
|
+
queryKey: [key, count],
|
|
1061
|
+
queryFn: async () => {
|
|
1062
|
+
queryFnCount++
|
|
1063
|
+
await sleep(10)
|
|
1064
|
+
return 'data' + count
|
|
1065
|
+
},
|
|
1066
|
+
})
|
|
1067
|
+
|
|
1068
|
+
return (
|
|
1069
|
+
<div>
|
|
1070
|
+
<div>{String(data)}</div>
|
|
1071
|
+
</div>
|
|
1072
|
+
)
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
const rendered = renderWithClient(
|
|
1076
|
+
queryClient,
|
|
1077
|
+
|
|
1078
|
+
<App />,
|
|
1079
|
+
)
|
|
1080
|
+
|
|
1081
|
+
await waitFor(() => rendered.getByText('Loading...'))
|
|
1082
|
+
|
|
1083
|
+
await waitFor(() => rendered.getByText('data0'))
|
|
1084
|
+
|
|
1085
|
+
fireEvent.click(rendered.getByText('inc'))
|
|
1086
|
+
|
|
1087
|
+
await waitFor(() => rendered.getByText('data1'))
|
|
1088
|
+
|
|
1089
|
+
await sleep(20)
|
|
1090
|
+
|
|
1091
|
+
expect(queryFnCount).toBe(2)
|
|
1092
|
+
})
|
|
1036
1093
|
})
|
|
@@ -57,12 +57,13 @@ export const getHasError = <
|
|
|
57
57
|
result: QueryObserverResult<TData, TError>
|
|
58
58
|
errorResetBoundary: QueryErrorResetBoundaryValue
|
|
59
59
|
throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>
|
|
60
|
-
query: Query<TQueryFnData, TError, TQueryData, TQueryKey>
|
|
60
|
+
query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined
|
|
61
61
|
}) => {
|
|
62
62
|
return (
|
|
63
63
|
result.isError &&
|
|
64
64
|
!errorResetBoundary.isReset() &&
|
|
65
65
|
!result.isFetching &&
|
|
66
|
+
query &&
|
|
66
67
|
shouldThrowError(throwOnError, [result.error, query])
|
|
67
68
|
)
|
|
68
69
|
}
|
package/src/useBaseQuery.ts
CHANGED
|
@@ -94,7 +94,6 @@ export function useBaseQuery<
|
|
|
94
94
|
// Do the same thing as the effect right above because the effect won't run
|
|
95
95
|
// when we suspend but also, the component won't re-mount so our observer would
|
|
96
96
|
// be out of date.
|
|
97
|
-
observer.setOptions(defaultedOptions, { listeners: false })
|
|
98
97
|
throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)
|
|
99
98
|
}
|
|
100
99
|
|
|
@@ -104,7 +103,14 @@ export function useBaseQuery<
|
|
|
104
103
|
result,
|
|
105
104
|
errorResetBoundary,
|
|
106
105
|
throwOnError: defaultedOptions.throwOnError,
|
|
107
|
-
query:
|
|
106
|
+
query: client
|
|
107
|
+
.getQueryCache()
|
|
108
|
+
.get<
|
|
109
|
+
TQueryFnData,
|
|
110
|
+
TError,
|
|
111
|
+
TQueryData,
|
|
112
|
+
TQueryKey
|
|
113
|
+
>(defaultedOptions.queryHash),
|
|
108
114
|
})
|
|
109
115
|
) {
|
|
110
116
|
throw result.error
|
package/src/useQueries.ts
CHANGED
|
@@ -329,24 +329,21 @@ export function useQueries<
|
|
|
329
329
|
: []
|
|
330
330
|
|
|
331
331
|
if (suspensePromises.length > 0) {
|
|
332
|
-
observer.setQueries(
|
|
333
|
-
defaultedQueries,
|
|
334
|
-
options as QueriesObserverOptions<TCombinedResult>,
|
|
335
|
-
{
|
|
336
|
-
listeners: false,
|
|
337
|
-
},
|
|
338
|
-
)
|
|
339
332
|
throw Promise.all(suspensePromises)
|
|
340
333
|
}
|
|
341
|
-
const observerQueries = observer.getQueries()
|
|
342
334
|
const firstSingleResultWhichShouldThrow = optimisticResult.find(
|
|
343
|
-
(result, index) =>
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
335
|
+
(result, index) => {
|
|
336
|
+
const query = defaultedQueries[index]
|
|
337
|
+
return (
|
|
338
|
+
query &&
|
|
339
|
+
getHasError({
|
|
340
|
+
result,
|
|
341
|
+
errorResetBoundary,
|
|
342
|
+
throwOnError: query.throwOnError,
|
|
343
|
+
query: client.getQueryCache().get(query.queryHash),
|
|
344
|
+
})
|
|
345
|
+
)
|
|
346
|
+
},
|
|
350
347
|
)
|
|
351
348
|
|
|
352
349
|
if (firstSingleResultWhichShouldThrow?.error) {
|