@tanstack/react-query 5.0.0-rc.6 → 5.0.0
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/codemods/coverage/base.css +224 -0
- package/build/codemods/coverage/block-navigation.js +87 -0
- package/build/codemods/coverage/clover.xml +6 -0
- package/build/codemods/coverage/coverage-final.json +1 -0
- package/build/codemods/coverage/favicon.png +0 -0
- package/build/codemods/coverage/index.html +101 -0
- package/build/codemods/coverage/prettify.css +1 -0
- package/build/codemods/coverage/prettify.js +2 -0
- package/build/codemods/coverage/sort-arrow-sprite.png +0 -0
- package/build/codemods/coverage/sorter.js +196 -0
- package/build/legacy/types.cjs.map +1 -1
- package/build/legacy/types.d.cts +3 -3
- package/build/legacy/types.d.ts +3 -3
- package/build/legacy/useQueries.cjs.map +1 -1
- package/build/legacy/useQueries.d.cts +9 -5
- package/build/legacy/useQueries.d.ts +9 -5
- package/build/legacy/useQueries.js.map +1 -1
- package/build/legacy/useSuspenseQueries.cjs.map +1 -1
- package/build/legacy/useSuspenseQueries.d.cts +9 -5
- package/build/legacy/useSuspenseQueries.d.ts +9 -5
- package/build/legacy/useSuspenseQueries.js.map +1 -1
- package/build/modern/types.cjs.map +1 -1
- package/build/modern/types.d.cts +3 -3
- package/build/modern/types.d.ts +3 -3
- package/build/modern/useQueries.cjs.map +1 -1
- package/build/modern/useQueries.d.cts +9 -5
- package/build/modern/useQueries.d.ts +9 -5
- package/build/modern/useQueries.js.map +1 -1
- package/build/modern/useSuspenseQueries.cjs.map +1 -1
- package/build/modern/useSuspenseQueries.d.cts +9 -5
- package/build/modern/useSuspenseQueries.d.ts +9 -5
- package/build/modern/useSuspenseQueries.js.map +1 -1
- package/package.json +2 -3
- package/src/__tests__/suspense.types.test.tsx +146 -0
- package/src/__tests__/useQueries.test.tsx +53 -1
- package/src/__tests__/useQuery.test.tsx +1 -1
- package/src/__tests__/useQuery.types.test.tsx +9 -7
- package/src/types.ts +2 -4
- package/src/useQueries.ts +23 -6
- package/src/useSuspenseQueries.ts +21 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UseQueryResult, UseQueryOptions } from './types.js';
|
|
2
|
-
import { DefaultError, QueryClient, QueryKey, QueriesPlaceholderDataFunction, QueryFunction } from '@tanstack/query-core';
|
|
2
|
+
import { DefaultError, QueryClient, QueryKey, QueriesPlaceholderDataFunction, QueryFunction, ThrowOnError } from '@tanstack/query-core';
|
|
3
3
|
|
|
4
4
|
type UseQueryOptionsForUseQueries<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> = Omit<UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, 'placeholderData' | 'suspense'> & {
|
|
5
5
|
placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>;
|
|
@@ -18,9 +18,11 @@ type GetOptions<T> = T extends {
|
|
|
18
18
|
} ? UseQueryOptionsForUseQueries<unknown, TError, TData> : T extends [infer TQueryFnData, infer TError, infer TData] ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData> : T extends [infer TQueryFnData, infer TError] ? UseQueryOptionsForUseQueries<TQueryFnData, TError> : T extends [infer TQueryFnData] ? UseQueryOptionsForUseQueries<TQueryFnData> : T extends {
|
|
19
19
|
queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>;
|
|
20
20
|
select: (data: any) => infer TData;
|
|
21
|
-
|
|
21
|
+
throwOnError?: ThrowOnError<any, infer TError, any, any>;
|
|
22
|
+
} ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey> : T extends {
|
|
22
23
|
queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>;
|
|
23
|
-
|
|
24
|
+
throwOnError?: ThrowOnError<any, infer TError, any, any>;
|
|
25
|
+
} ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TQueryFnData, TQueryKey> : UseQueryOptionsForUseQueries;
|
|
24
26
|
type GetResults<T> = T extends {
|
|
25
27
|
queryFnData: any;
|
|
26
28
|
error?: infer TError;
|
|
@@ -34,9 +36,11 @@ type GetResults<T> = T extends {
|
|
|
34
36
|
} ? UseQueryResult<TData, TError> : T extends [any, infer TError, infer TData] ? UseQueryResult<TData, TError> : T extends [infer TQueryFnData, infer TError] ? UseQueryResult<TQueryFnData, TError> : T extends [infer TQueryFnData] ? UseQueryResult<TQueryFnData> : T extends {
|
|
35
37
|
queryFn?: QueryFunction<unknown, any>;
|
|
36
38
|
select: (data: any) => infer TData;
|
|
37
|
-
|
|
39
|
+
throwOnError?: ThrowOnError<any, infer TError, any, any>;
|
|
40
|
+
} ? UseQueryResult<TData, unknown extends TError ? DefaultError : TError> : T extends {
|
|
38
41
|
queryFn?: QueryFunction<infer TQueryFnData, any>;
|
|
39
|
-
|
|
42
|
+
throwOnError?: ThrowOnError<any, infer TError, any, any>;
|
|
43
|
+
} ? UseQueryResult<TQueryFnData, unknown extends TError ? DefaultError : TError> : UseQueryResult;
|
|
40
44
|
/**
|
|
41
45
|
* QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param
|
|
42
46
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { QueriesObserver, notifyManager } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n fetchOptimistic,\n shouldSuspend,\n willFetch,\n} from './suspense'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport type {\n DefaultError,\n QueriesObserverOptions,\n QueriesPlaceholderDataFunction,\n QueryClient,\n QueryFunction,\n QueryKey,\n} 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 }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TData, TQueryKey>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey> }\n ? UseQueryOptionsForUseQueries<TQueryFnData, Error, TQueryFnData, TQueryKey>\n : // Fallback\n UseQueryOptionsForUseQueries\n\ntype GetResults<T> =\n // Part 1: responsible for mapping explicit type parameter to function result, if object\n T extends { queryFnData: any; error?: infer TError; data: infer TData }\n ? UseQueryResult<TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryResult<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryResult<TData, TError>\n : // Part 2: responsible for mapping explicit type parameter to function result, if tuple\n T extends [any, infer TError, infer TData]\n ? UseQueryResult<TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryResult<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryResult<TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<unknown, any>\n select: (data: any) => infer TData\n }\n ? UseQueryResult<TData>\n : T extends { queryFn?: QueryFunction<infer TQueryFnData, any> }\n ? UseQueryResult<TQueryFnData>\n : // Fallback\n UseQueryResult\n\n/**\n * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param\n */\nexport type QueriesOptions<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryOptionsForUseQueries>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetOptions<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>\n : Array<unknown> extends T\n ? T\n : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogenous type!\n // use this to infer the param types in the case of Array.map() argument\n T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >\n >\n ? Array<UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>>\n : // Fallback\n Array<UseQueryOptionsForUseQueries>\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryResult>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetResults<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>\n : T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >\n >\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n Array<\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n >\n : // Fallback\n Array<UseQueryResult>\n\nexport function useQueries<\n T extends Array<any>,\n TCombinedResult = QueriesResults<T>,\n>(\n {\n queries,\n ...options\n }: {\n queries: readonly [...QueriesOptions<T>]\n combine?: (result: QueriesResults<T>) => TCombinedResult\n },\n queryClient?: QueryClient,\n): TCombinedResult {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((opts) => {\n const defaultedOptions = client.defaultQueryOptions(opts)\n\n // Make sure the results are already in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n return defaultedOptions\n }),\n [queries, client, isRestoring],\n )\n\n defaultedQueries.forEach((query) => {\n ensureStaleTime(query)\n ensurePreventErrorBoundaryRetry(query, errorResetBoundary)\n })\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new QueriesObserver<TCombinedResult>(\n client,\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n ),\n )\n\n const [optimisticResult, getCombinedResult, trackResult] =\n observer.getOptimisticResult(defaultedQueries)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) =>\n isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\n }, [defaultedQueries, options, observer])\n\n const shouldAtLeastOneSuspend = optimisticResult.some((result, index) =>\n shouldSuspend(defaultedQueries[index], result, isRestoring),\n )\n\n const suspensePromises = shouldAtLeastOneSuspend\n ? optimisticResult.flatMap((result, index) => {\n const opts = defaultedQueries[index]\n const queryObserver = observer.getObservers()[index]\n\n if (opts && queryObserver) {\n if (shouldSuspend(opts, result, isRestoring)) {\n return fetchOptimistic(opts, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(opts, queryObserver, errorResetBoundary)\n }\n }\n return []\n })\n : []\n\n if (suspensePromises.length > 0) {\n throw Promise.all(suspensePromises)\n }\n const observerQueries = observer.getQueries()\n const firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) =>\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedQueries[index]?.throwOnError ?? false,\n query: observerQueries[index]!,\n }),\n )\n\n if (firstSingleResultWhichShouldThrow?.error) {\n throw firstSingleResultWhichShouldThrow.error\n }\n\n return getCombinedResult(trackResult())\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB,SAAS,iBAAiB,qBAAqB;AAC/C,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,kCAAkC;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAoJA,SAAS,WAId;AAAA,EACE;AAAA,EACA,GAAG;AACL,GAIA,aACiB;AACjB,QAAM,SAAS,eAAe,WAAW;AACzC,QAAM,cAAc,eAAe;AACnC,QAAM,qBAAqB,2BAA2B;AAEtD,QAAM,mBAAyB;AAAA,IAC7B,MACE,QAAQ,IAAI,CAAC,SAAS;AACpB,YAAM,mBAAmB,OAAO,oBAAoB,IAAI;AAGxD,uBAAiB,qBAAqB,cAClC,gBACA;AAEJ,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,SAAS,QAAQ,WAAW;AAAA,EAC/B;AAEA,mBAAiB,QAAQ,CAAC,UAAU;AAClC,oBAAgB,KAAK;AACrB,oCAAgC,OAAO,kBAAkB;AAAA,EAC3D,CAAC;AAED,6BAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,CAAC,kBAAkB,mBAAmB,WAAW,IACrD,SAAS,oBAAoB,gBAAgB;AAE/C,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBACC,cACI,MAAM,SACN,SAAS,UAAU,cAAc,WAAW,aAAa,CAAC;AAAA,MAChE,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,GAAG,CAAC,kBAAkB,SAAS,QAAQ,CAAC;AAExC,QAAM,0BAA0B,iBAAiB;AAAA,IAAK,CAAC,QAAQ,UAC7D,cAAc,iBAAiB,KAAK,GAAG,QAAQ,WAAW;AAAA,EAC5D;AAEA,QAAM,mBAAmB,0BACrB,iBAAiB,QAAQ,CAAC,QAAQ,UAAU;AAC1C,UAAM,OAAO,iBAAiB,KAAK;AACnC,UAAM,gBAAgB,SAAS,aAAa,EAAE,KAAK;AAEnD,QAAI,QAAQ,eAAe;AACzB,UAAI,cAAc,MAAM,QAAQ,WAAW,GAAG;AAC5C,eAAO,gBAAgB,MAAM,eAAe,kBAAkB;AAAA,MAChE,WAAW,UAAU,QAAQ,WAAW,GAAG;AACzC,aAAK,gBAAgB,MAAM,eAAe,kBAAkB;AAAA,MAC9D;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV,CAAC,IACD,CAAC;AAEL,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,QAAQ,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UACP,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA,cAAc,iBAAiB,KAAK,GAAG,gBAAgB;AAAA,MACvD,OAAO,gBAAgB,KAAK;AAAA,IAC9B,CAAC;AAAA,EACL;AAEA,MAAI,mCAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/useQueries.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { QueriesObserver, notifyManager } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport {\n ensureStaleTime,\n fetchOptimistic,\n shouldSuspend,\n willFetch,\n} from './suspense'\nimport type { UseQueryOptions, UseQueryResult } from './types'\nimport type {\n DefaultError,\n QueriesObserverOptions,\n QueriesPlaceholderDataFunction,\n QueryClient,\n QueryFunction,\n QueryKey,\n ThrowOnError,\n} from '@tanstack/query-core'\n\n// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.\n// `placeholderData` function always gets undefined passed\ntype UseQueryOptionsForUseQueries<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> = Omit<\n UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'placeholderData' | 'suspense'\n> & {\n placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>\n}\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetOptions<T> =\n // Part 1: responsible for applying explicit type parameter to function arguments, if object { queryFnData: TQueryFnData, error: TError, data: TData }\n T extends {\n queryFnData: infer TQueryFnData\n error?: infer TError\n data: infer TData\n }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryOptionsForUseQueries<unknown, TError, TData>\n : // Part 2: responsible for applying explicit type parameter to function arguments, if tuple [TQueryFnData, TError, TData]\n T extends [infer TQueryFnData, infer TError, infer TData]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryOptionsForUseQueries<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryOptionsForUseQueries<\n TQueryFnData,\n TError,\n TQueryFnData,\n TQueryKey\n >\n : // Fallback\n UseQueryOptionsForUseQueries\n\ntype GetResults<T> =\n // Part 1: responsible for mapping explicit type parameter to function result, if object\n T extends { queryFnData: any; error?: infer TError; data: infer TData }\n ? UseQueryResult<TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseQueryResult<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseQueryResult<TData, TError>\n : // Part 2: responsible for mapping explicit type parameter to function result, if tuple\n T extends [any, infer TError, infer TData]\n ? UseQueryResult<TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? UseQueryResult<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseQueryResult<TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<unknown, any>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<TData, unknown extends TError ? DefaultError : TError>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, any>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseQueryResult<\n TQueryFnData,\n unknown extends TError ? DefaultError : TError\n >\n : // Fallback\n UseQueryResult\n\n/**\n * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param\n */\nexport type QueriesOptions<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryOptionsForUseQueries>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetOptions<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>\n : Array<unknown> extends T\n ? T\n : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogenous type!\n // use this to infer the param types in the case of Array.map() argument\n T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >\n >\n ? Array<UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>>\n : // Fallback\n Array<UseQueryOptionsForUseQueries>\n\n/**\n * QueriesResults reducer recursively maps type param to results\n */\nexport type QueriesResults<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseQueryResult>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetResults<Head>]\n : T extends [infer Head, ...infer Tail]\n ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>\n : T extends Array<\n UseQueryOptionsForUseQueries<\n infer TQueryFnData,\n infer TError,\n infer TData,\n any\n >\n >\n ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results\n Array<\n UseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n >\n : // Fallback\n Array<UseQueryResult>\n\nexport function useQueries<\n T extends Array<any>,\n TCombinedResult = QueriesResults<T>,\n>(\n {\n queries,\n ...options\n }: {\n queries: readonly [...QueriesOptions<T>]\n combine?: (result: QueriesResults<T>) => TCombinedResult\n },\n queryClient?: QueryClient,\n): TCombinedResult {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n\n const defaultedQueries = React.useMemo(\n () =>\n queries.map((opts) => {\n const defaultedOptions = client.defaultQueryOptions(opts)\n\n // Make sure the results are already in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n return defaultedOptions\n }),\n [queries, client, isRestoring],\n )\n\n defaultedQueries.forEach((query) => {\n ensureStaleTime(query)\n ensurePreventErrorBoundaryRetry(query, errorResetBoundary)\n })\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new QueriesObserver<TCombinedResult>(\n client,\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n ),\n )\n\n const [optimisticResult, getCombinedResult, trackResult] =\n observer.getOptimisticResult(defaultedQueries)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) =>\n isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setQueries(\n defaultedQueries,\n options as QueriesObserverOptions<TCombinedResult>,\n {\n listeners: false,\n },\n )\n }, [defaultedQueries, options, observer])\n\n const shouldAtLeastOneSuspend = optimisticResult.some((result, index) =>\n shouldSuspend(defaultedQueries[index], result, isRestoring),\n )\n\n const suspensePromises = shouldAtLeastOneSuspend\n ? optimisticResult.flatMap((result, index) => {\n const opts = defaultedQueries[index]\n const queryObserver = observer.getObservers()[index]\n\n if (opts && queryObserver) {\n if (shouldSuspend(opts, result, isRestoring)) {\n return fetchOptimistic(opts, queryObserver, errorResetBoundary)\n } else if (willFetch(result, isRestoring)) {\n void fetchOptimistic(opts, queryObserver, errorResetBoundary)\n }\n }\n return []\n })\n : []\n\n if (suspensePromises.length > 0) {\n throw Promise.all(suspensePromises)\n }\n const observerQueries = observer.getQueries()\n const firstSingleResultWhichShouldThrow = optimisticResult.find(\n (result, index) =>\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedQueries[index]?.throwOnError ?? false,\n query: observerQueries[index]!,\n }),\n )\n\n if (firstSingleResultWhichShouldThrow?.error) {\n throw firstSingleResultWhichShouldThrow.error\n }\n\n return getCombinedResult(trackResult())\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB,SAAS,iBAAiB,qBAAqB;AAC/C,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,kCAAkC;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAqKA,SAAS,WAId;AAAA,EACE;AAAA,EACA,GAAG;AACL,GAIA,aACiB;AACjB,QAAM,SAAS,eAAe,WAAW;AACzC,QAAM,cAAc,eAAe;AACnC,QAAM,qBAAqB,2BAA2B;AAEtD,QAAM,mBAAyB;AAAA,IAC7B,MACE,QAAQ,IAAI,CAAC,SAAS;AACpB,YAAM,mBAAmB,OAAO,oBAAoB,IAAI;AAGxD,uBAAiB,qBAAqB,cAClC,gBACA;AAEJ,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,SAAS,QAAQ,WAAW;AAAA,EAC/B;AAEA,mBAAiB,QAAQ,CAAC,UAAU;AAClC,oBAAgB,KAAK;AACrB,oCAAgC,OAAO,kBAAkB;AAAA,EAC3D,CAAC;AAED,6BAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,CAAC,kBAAkB,mBAAmB,WAAW,IACrD,SAAS,oBAAoB,gBAAgB;AAE/C,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBACC,cACI,MAAM,SACN,SAAS,UAAU,cAAc,WAAW,aAAa,CAAC;AAAA,MAChE,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,GAAG,CAAC,kBAAkB,SAAS,QAAQ,CAAC;AAExC,QAAM,0BAA0B,iBAAiB;AAAA,IAAK,CAAC,QAAQ,UAC7D,cAAc,iBAAiB,KAAK,GAAG,QAAQ,WAAW;AAAA,EAC5D;AAEA,QAAM,mBAAmB,0BACrB,iBAAiB,QAAQ,CAAC,QAAQ,UAAU;AAC1C,UAAM,OAAO,iBAAiB,KAAK;AACnC,UAAM,gBAAgB,SAAS,aAAa,EAAE,KAAK;AAEnD,QAAI,QAAQ,eAAe;AACzB,UAAI,cAAc,MAAM,QAAQ,WAAW,GAAG;AAC5C,eAAO,gBAAgB,MAAM,eAAe,kBAAkB;AAAA,MAChE,WAAW,UAAU,QAAQ,WAAW,GAAG;AACzC,aAAK,gBAAgB,MAAM,eAAe,kBAAkB;AAAA,MAC9D;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV,CAAC,IACD,CAAC;AAEL,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,QAAQ,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,oCAAoC,iBAAiB;AAAA,IACzD,CAAC,QAAQ,UACP,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA,cAAc,iBAAiB,KAAK,GAAG,gBAAgB;AAAA,MACvD,OAAO,gBAAgB,KAAK;AAAA,IAC9B,CAAC;AAAA,EACL;AAEA,MAAI,mCAAmC,OAAO;AAC5C,UAAM,kCAAkC;AAAA,EAC1C;AAEA,SAAO,kBAAkB,YAAY,CAAC;AACxC;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/useSuspenseQueries.ts"],"sourcesContent":["'use client'\nimport { useQueries } from './useQueries'\nimport { defaultThrowOnError } from './suspense'\nimport type { UseSuspenseQueryOptions, UseSuspenseQueryResult } from './types'\nimport type {\n DefaultError,\n QueryClient,\n QueryFunction,\n} from '@tanstack/query-core'\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetSuspenseOptions<T> =\n // Part 1: responsible for applying explicit type parameter to function arguments, if object { queryFnData: TQueryFnData, error: TError, data: TData }\n T extends {\n queryFnData: infer TQueryFnData\n error?: infer TError\n data: infer TData\n }\n ? UseSuspenseQueryOptions<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseSuspenseQueryOptions<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseSuspenseQueryOptions<unknown, TError, TData>\n : // Part 2: responsible for applying explicit type parameter to function arguments, if tuple [TQueryFnData, TError, TData]\n T extends [infer TQueryFnData, infer TError, infer TData]\n ? UseSuspenseQueryOptions<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseSuspenseQueryOptions<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseSuspenseQueryOptions<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n }\n ? UseSuspenseQueryOptions<TQueryFnData,
|
|
1
|
+
{"version":3,"sources":["../../src/useSuspenseQueries.ts"],"sourcesContent":["'use client'\nimport { useQueries } from './useQueries'\nimport { defaultThrowOnError } from './suspense'\nimport type { UseSuspenseQueryOptions, UseSuspenseQueryResult } from './types'\nimport type {\n DefaultError,\n QueryClient,\n QueryFunction,\n ThrowOnError,\n} from '@tanstack/query-core'\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetSuspenseOptions<T> =\n // Part 1: responsible for applying explicit type parameter to function arguments, if object { queryFnData: TQueryFnData, error: TError, data: TData }\n T extends {\n queryFnData: infer TQueryFnData\n error?: infer TError\n data: infer TData\n }\n ? UseSuspenseQueryOptions<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseSuspenseQueryOptions<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseSuspenseQueryOptions<unknown, TError, TData>\n : // Part 2: responsible for applying explicit type parameter to function arguments, if tuple [TQueryFnData, TError, TData]\n T extends [infer TQueryFnData, infer TError, infer TData]\n ? UseSuspenseQueryOptions<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseSuspenseQueryOptions<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseSuspenseQueryOptions<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseSuspenseQueryOptions<TQueryFnData, TError, TQueryFnData, TQueryKey>\n : // Fallback\n UseSuspenseQueryOptions\n\ntype GetSuspenseResults<T> =\n // Part 1: responsible for mapping explicit type parameter to function result, if object\n T extends { queryFnData: any; error?: infer TError; data: infer TData }\n ? UseSuspenseQueryResult<TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseSuspenseQueryResult<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseSuspenseQueryResult<TData, TError>\n : // Part 2: responsible for mapping explicit type parameter to function result, if tuple\n T extends [any, infer TError, infer TData]\n ? UseSuspenseQueryResult<TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? UseSuspenseQueryResult<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseSuspenseQueryResult<TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<unknown, any>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseSuspenseQueryResult<\n 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 ? UseSuspenseQueryResult<\n TQueryFnData,\n unknown extends TError ? DefaultError : TError\n >\n : // Fallback\n UseSuspenseQueryResult\n\n/**\n * SuspenseQueriesOptions reducer recursively unwraps function arguments to infer/enforce type param\n */\nexport type SuspenseQueriesOptions<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseSuspenseQueryOptions>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetSuspenseOptions<Head>]\n : T extends [infer Head, ...infer Tail]\n ? SuspenseQueriesOptions<\n [...Tail],\n [...Result, GetSuspenseOptions<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 UseSuspenseQueryOptions<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >\n >\n ? Array<UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>>\n : // Fallback\n Array<UseSuspenseQueryOptions>\n\n/**\n * SuspenseQueriesResults reducer recursively maps type param to results\n */\nexport type SuspenseQueriesResults<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseSuspenseQueryResult>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetSuspenseResults<Head>]\n : T extends [infer Head, ...infer Tail]\n ? SuspenseQueriesResults<\n [...Tail],\n [...Result, GetSuspenseResults<Head>],\n [...Depth, 1]\n >\n : T extends Array<\n UseSuspenseQueryOptions<\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 UseSuspenseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n >\n : // Fallback\n Array<UseSuspenseQueryResult>\n\nexport function useSuspenseQueries<\n T extends Array<any>,\n TCombinedResult = SuspenseQueriesResults<T>,\n>(\n options: {\n queries: readonly [...SuspenseQueriesOptions<T>]\n combine?: (result: SuspenseQueriesResults<T>) => TCombinedResult\n },\n queryClient?: QueryClient,\n): TCombinedResult {\n return useQueries(\n {\n ...options,\n queries: options.queries.map((query) => ({\n ...query,\n suspense: true,\n throwOnError: defaultThrowOnError,\n enabled: true,\n })),\n } as any,\n queryClient,\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,wBAA2B;AAC3B,sBAAoC;AA0J7B,SAAS,mBAId,SAIA,aACiB;AACjB,aAAO;AAAA,IACL;AAAA,MACE,GAAG;AAAA,MACH,SAAS,QAAQ,QAAQ,IAAI,CAAC,WAAW;AAAA,QACvC,GAAG;AAAA,QACH,UAAU;AAAA,QACV,cAAc;AAAA,QACd,SAAS;AAAA,MACX,EAAE;AAAA,IACJ;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UseSuspenseQueryOptions, UseSuspenseQueryResult } from './types.cjs';
|
|
2
|
-
import { DefaultError, QueryClient, QueryFunction } from '@tanstack/query-core';
|
|
2
|
+
import { DefaultError, QueryClient, QueryFunction, ThrowOnError } from '@tanstack/query-core';
|
|
3
3
|
|
|
4
4
|
type MAXIMUM_DEPTH = 20;
|
|
5
5
|
type GetSuspenseOptions<T> = T extends {
|
|
@@ -15,9 +15,11 @@ type GetSuspenseOptions<T> = T extends {
|
|
|
15
15
|
} ? UseSuspenseQueryOptions<unknown, TError, TData> : T extends [infer TQueryFnData, infer TError, infer TData] ? UseSuspenseQueryOptions<TQueryFnData, TError, TData> : T extends [infer TQueryFnData, infer TError] ? UseSuspenseQueryOptions<TQueryFnData, TError> : T extends [infer TQueryFnData] ? UseSuspenseQueryOptions<TQueryFnData> : T extends {
|
|
16
16
|
queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>;
|
|
17
17
|
select: (data: any) => infer TData;
|
|
18
|
-
|
|
18
|
+
throwOnError?: ThrowOnError<any, infer TError, any, any>;
|
|
19
|
+
} ? UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey> : T extends {
|
|
19
20
|
queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>;
|
|
20
|
-
|
|
21
|
+
throwOnError?: ThrowOnError<any, infer TError, any, any>;
|
|
22
|
+
} ? UseSuspenseQueryOptions<TQueryFnData, TError, TQueryFnData, TQueryKey> : UseSuspenseQueryOptions;
|
|
21
23
|
type GetSuspenseResults<T> = T extends {
|
|
22
24
|
queryFnData: any;
|
|
23
25
|
error?: infer TError;
|
|
@@ -31,9 +33,11 @@ type GetSuspenseResults<T> = T extends {
|
|
|
31
33
|
} ? UseSuspenseQueryResult<TData, TError> : T extends [any, infer TError, infer TData] ? UseSuspenseQueryResult<TData, TError> : T extends [infer TQueryFnData, infer TError] ? UseSuspenseQueryResult<TQueryFnData, TError> : T extends [infer TQueryFnData] ? UseSuspenseQueryResult<TQueryFnData> : T extends {
|
|
32
34
|
queryFn?: QueryFunction<unknown, any>;
|
|
33
35
|
select: (data: any) => infer TData;
|
|
34
|
-
|
|
36
|
+
throwOnError?: ThrowOnError<any, infer TError, any, any>;
|
|
37
|
+
} ? UseSuspenseQueryResult<TData, unknown extends TError ? DefaultError : TError> : T extends {
|
|
35
38
|
queryFn?: QueryFunction<infer TQueryFnData, any>;
|
|
36
|
-
|
|
39
|
+
throwOnError?: ThrowOnError<any, infer TError, any, any>;
|
|
40
|
+
} ? UseSuspenseQueryResult<TQueryFnData, unknown extends TError ? DefaultError : TError> : UseSuspenseQueryResult;
|
|
37
41
|
/**
|
|
38
42
|
* SuspenseQueriesOptions reducer recursively unwraps function arguments to infer/enforce type param
|
|
39
43
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UseSuspenseQueryOptions, UseSuspenseQueryResult } from './types.js';
|
|
2
|
-
import { DefaultError, QueryClient, QueryFunction } from '@tanstack/query-core';
|
|
2
|
+
import { DefaultError, QueryClient, QueryFunction, ThrowOnError } from '@tanstack/query-core';
|
|
3
3
|
|
|
4
4
|
type MAXIMUM_DEPTH = 20;
|
|
5
5
|
type GetSuspenseOptions<T> = T extends {
|
|
@@ -15,9 +15,11 @@ type GetSuspenseOptions<T> = T extends {
|
|
|
15
15
|
} ? UseSuspenseQueryOptions<unknown, TError, TData> : T extends [infer TQueryFnData, infer TError, infer TData] ? UseSuspenseQueryOptions<TQueryFnData, TError, TData> : T extends [infer TQueryFnData, infer TError] ? UseSuspenseQueryOptions<TQueryFnData, TError> : T extends [infer TQueryFnData] ? UseSuspenseQueryOptions<TQueryFnData> : T extends {
|
|
16
16
|
queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>;
|
|
17
17
|
select: (data: any) => infer TData;
|
|
18
|
-
|
|
18
|
+
throwOnError?: ThrowOnError<any, infer TError, any, any>;
|
|
19
|
+
} ? UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey> : T extends {
|
|
19
20
|
queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>;
|
|
20
|
-
|
|
21
|
+
throwOnError?: ThrowOnError<any, infer TError, any, any>;
|
|
22
|
+
} ? UseSuspenseQueryOptions<TQueryFnData, TError, TQueryFnData, TQueryKey> : UseSuspenseQueryOptions;
|
|
21
23
|
type GetSuspenseResults<T> = T extends {
|
|
22
24
|
queryFnData: any;
|
|
23
25
|
error?: infer TError;
|
|
@@ -31,9 +33,11 @@ type GetSuspenseResults<T> = T extends {
|
|
|
31
33
|
} ? UseSuspenseQueryResult<TData, TError> : T extends [any, infer TError, infer TData] ? UseSuspenseQueryResult<TData, TError> : T extends [infer TQueryFnData, infer TError] ? UseSuspenseQueryResult<TQueryFnData, TError> : T extends [infer TQueryFnData] ? UseSuspenseQueryResult<TQueryFnData> : T extends {
|
|
32
34
|
queryFn?: QueryFunction<unknown, any>;
|
|
33
35
|
select: (data: any) => infer TData;
|
|
34
|
-
|
|
36
|
+
throwOnError?: ThrowOnError<any, infer TError, any, any>;
|
|
37
|
+
} ? UseSuspenseQueryResult<TData, unknown extends TError ? DefaultError : TError> : T extends {
|
|
35
38
|
queryFn?: QueryFunction<infer TQueryFnData, any>;
|
|
36
|
-
|
|
39
|
+
throwOnError?: ThrowOnError<any, infer TError, any, any>;
|
|
40
|
+
} ? UseSuspenseQueryResult<TQueryFnData, unknown extends TError ? DefaultError : TError> : UseSuspenseQueryResult;
|
|
37
41
|
/**
|
|
38
42
|
* SuspenseQueriesOptions reducer recursively unwraps function arguments to infer/enforce type param
|
|
39
43
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/useSuspenseQueries.ts"],"sourcesContent":["'use client'\nimport { useQueries } from './useQueries'\nimport { defaultThrowOnError } from './suspense'\nimport type { UseSuspenseQueryOptions, UseSuspenseQueryResult } from './types'\nimport type {\n DefaultError,\n QueryClient,\n QueryFunction,\n} from '@tanstack/query-core'\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetSuspenseOptions<T> =\n // Part 1: responsible for applying explicit type parameter to function arguments, if object { queryFnData: TQueryFnData, error: TError, data: TData }\n T extends {\n queryFnData: infer TQueryFnData\n error?: infer TError\n data: infer TData\n }\n ? UseSuspenseQueryOptions<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseSuspenseQueryOptions<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseSuspenseQueryOptions<unknown, TError, TData>\n : // Part 2: responsible for applying explicit type parameter to function arguments, if tuple [TQueryFnData, TError, TData]\n T extends [infer TQueryFnData, infer TError, infer TData]\n ? UseSuspenseQueryOptions<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseSuspenseQueryOptions<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseSuspenseQueryOptions<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n }\n ? UseSuspenseQueryOptions<TQueryFnData,
|
|
1
|
+
{"version":3,"sources":["../../src/useSuspenseQueries.ts"],"sourcesContent":["'use client'\nimport { useQueries } from './useQueries'\nimport { defaultThrowOnError } from './suspense'\nimport type { UseSuspenseQueryOptions, UseSuspenseQueryResult } from './types'\nimport type {\n DefaultError,\n QueryClient,\n QueryFunction,\n ThrowOnError,\n} from '@tanstack/query-core'\n\n// Avoid TS depth-limit error in case of large array literal\ntype MAXIMUM_DEPTH = 20\n\ntype GetSuspenseOptions<T> =\n // Part 1: responsible for applying explicit type parameter to function arguments, if object { queryFnData: TQueryFnData, error: TError, data: TData }\n T extends {\n queryFnData: infer TQueryFnData\n error?: infer TError\n data: infer TData\n }\n ? UseSuspenseQueryOptions<TQueryFnData, TError, TData>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseSuspenseQueryOptions<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseSuspenseQueryOptions<unknown, TError, TData>\n : // Part 2: responsible for applying explicit type parameter to function arguments, if tuple [TQueryFnData, TError, TData]\n T extends [infer TQueryFnData, infer TError, infer TData]\n ? UseSuspenseQueryOptions<TQueryFnData, TError, TData>\n : T extends [infer TQueryFnData, infer TError]\n ? UseSuspenseQueryOptions<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseSuspenseQueryOptions<TQueryFnData>\n : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>\n : T extends {\n queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseSuspenseQueryOptions<TQueryFnData, TError, TQueryFnData, TQueryKey>\n : // Fallback\n UseSuspenseQueryOptions\n\ntype GetSuspenseResults<T> =\n // Part 1: responsible for mapping explicit type parameter to function result, if object\n T extends { queryFnData: any; error?: infer TError; data: infer TData }\n ? UseSuspenseQueryResult<TData, TError>\n : T extends { queryFnData: infer TQueryFnData; error?: infer TError }\n ? UseSuspenseQueryResult<TQueryFnData, TError>\n : T extends { data: infer TData; error?: infer TError }\n ? UseSuspenseQueryResult<TData, TError>\n : // Part 2: responsible for mapping explicit type parameter to function result, if tuple\n T extends [any, infer TError, infer TData]\n ? UseSuspenseQueryResult<TData, TError>\n : T extends [infer TQueryFnData, infer TError]\n ? UseSuspenseQueryResult<TQueryFnData, TError>\n : T extends [infer TQueryFnData]\n ? UseSuspenseQueryResult<TQueryFnData>\n : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided\n T extends {\n queryFn?: QueryFunction<unknown, any>\n select: (data: any) => infer TData\n throwOnError?: ThrowOnError<any, infer TError, any, any>\n }\n ? UseSuspenseQueryResult<\n 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 ? UseSuspenseQueryResult<\n TQueryFnData,\n unknown extends TError ? DefaultError : TError\n >\n : // Fallback\n UseSuspenseQueryResult\n\n/**\n * SuspenseQueriesOptions reducer recursively unwraps function arguments to infer/enforce type param\n */\nexport type SuspenseQueriesOptions<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseSuspenseQueryOptions>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetSuspenseOptions<Head>]\n : T extends [infer Head, ...infer Tail]\n ? SuspenseQueriesOptions<\n [...Tail],\n [...Result, GetSuspenseOptions<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 UseSuspenseQueryOptions<\n infer TQueryFnData,\n infer TError,\n infer TData,\n infer TQueryKey\n >\n >\n ? Array<UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>>\n : // Fallback\n Array<UseSuspenseQueryOptions>\n\n/**\n * SuspenseQueriesResults reducer recursively maps type param to results\n */\nexport type SuspenseQueriesResults<\n T extends Array<any>,\n Result extends Array<any> = [],\n Depth extends ReadonlyArray<number> = [],\n> = Depth['length'] extends MAXIMUM_DEPTH\n ? Array<UseSuspenseQueryResult>\n : T extends []\n ? []\n : T extends [infer Head]\n ? [...Result, GetSuspenseResults<Head>]\n : T extends [infer Head, ...infer Tail]\n ? SuspenseQueriesResults<\n [...Tail],\n [...Result, GetSuspenseResults<Head>],\n [...Depth, 1]\n >\n : T extends Array<\n UseSuspenseQueryOptions<\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 UseSuspenseQueryResult<\n unknown extends TData ? TQueryFnData : TData,\n unknown extends TError ? DefaultError : TError\n >\n >\n : // Fallback\n Array<UseSuspenseQueryResult>\n\nexport function useSuspenseQueries<\n T extends Array<any>,\n TCombinedResult = SuspenseQueriesResults<T>,\n>(\n options: {\n queries: readonly [...SuspenseQueriesOptions<T>]\n combine?: (result: SuspenseQueriesResults<T>) => TCombinedResult\n },\n queryClient?: QueryClient,\n): TCombinedResult {\n return useQueries(\n {\n ...options,\n queries: options.queries.map((query) => ({\n ...query,\n suspense: true,\n throwOnError: defaultThrowOnError,\n enabled: true,\n })),\n } as any,\n queryClient,\n )\n}\n"],"mappings":";;;AACA,SAAS,kBAAkB;AAC3B,SAAS,2BAA2B;AA0J7B,SAAS,mBAId,SAIA,aACiB;AACjB,SAAO;AAAA,IACL;AAAA,MACE,GAAG;AAAA,MACH,SAAS,QAAQ,QAAQ,IAAI,CAAC,WAAW;AAAA,QACvC,GAAG;AAAA,QACH,UAAU;AAAA,QACV,cAAc;AAAA,QACd,SAAS;AAAA,MACX,EAAE;AAAA,IACJ;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/react-query",
|
|
3
|
-
"version": "5.0.0
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "Hooks for managing, caching and syncing asynchronous and remote data in React",
|
|
5
5
|
"author": "tannerlinsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,8 +41,7 @@
|
|
|
41
41
|
"!build/codemods/**/__tests__"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"
|
|
45
|
-
"@tanstack/query-core": "5.0.0-rc.6"
|
|
44
|
+
"@tanstack/query-core": "5.0.0"
|
|
46
45
|
},
|
|
47
46
|
"devDependencies": {
|
|
48
47
|
"@types/react": "^18.2.4",
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { useSuspenseQuery } from '../useSuspenseQuery'
|
|
2
|
+
import { useSuspenseInfiniteQuery } from '../useSuspenseInfiniteQuery'
|
|
3
|
+
import { doNotExecute } from './utils'
|
|
4
|
+
import type { InfiniteData } from '@tanstack/query-core'
|
|
5
|
+
import type { Equal, Expect } from './utils'
|
|
6
|
+
|
|
7
|
+
describe('useSuspenseQuery', () => {
|
|
8
|
+
it('should always have data defined', () => {
|
|
9
|
+
doNotExecute(() => {
|
|
10
|
+
const { data } = useSuspenseQuery({
|
|
11
|
+
queryKey: ['key'],
|
|
12
|
+
queryFn: () => Promise.resolve(5),
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const result: Expect<Equal<typeof data, number>> = true
|
|
16
|
+
return result
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('should not have pending status', () => {
|
|
21
|
+
doNotExecute(() => {
|
|
22
|
+
const { status } = useSuspenseQuery({
|
|
23
|
+
queryKey: ['key'],
|
|
24
|
+
queryFn: () => Promise.resolve(5),
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const result: Expect<Equal<typeof status, 'error' | 'success'>> = true
|
|
28
|
+
return result
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('should not allow placeholderData, enabled or throwOnError props', () => {
|
|
33
|
+
doNotExecute(() => {
|
|
34
|
+
useSuspenseQuery({
|
|
35
|
+
queryKey: ['key'],
|
|
36
|
+
queryFn: () => Promise.resolve(5),
|
|
37
|
+
// @ts-expect-error TS2345
|
|
38
|
+
placeholderData: 5,
|
|
39
|
+
enabled: true,
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
useSuspenseQuery({
|
|
43
|
+
queryKey: ['key'],
|
|
44
|
+
queryFn: () => Promise.resolve(5),
|
|
45
|
+
// @ts-expect-error TS2345
|
|
46
|
+
enabled: true,
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
useSuspenseQuery({
|
|
50
|
+
queryKey: ['key'],
|
|
51
|
+
queryFn: () => Promise.resolve(5),
|
|
52
|
+
// @ts-expect-error TS2345
|
|
53
|
+
throwOnError: true,
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('should not return isPlaceholderData', () => {
|
|
59
|
+
doNotExecute(() => {
|
|
60
|
+
const query = useSuspenseQuery({
|
|
61
|
+
queryKey: ['key'],
|
|
62
|
+
queryFn: () => Promise.resolve(5),
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
// @ts-expect-error TS2339
|
|
66
|
+
void query.isPlaceholderData
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
describe('useSuspenseInfiniteQuery', () => {
|
|
72
|
+
it('should always have data defined', () => {
|
|
73
|
+
doNotExecute(() => {
|
|
74
|
+
const { data } = useSuspenseInfiniteQuery({
|
|
75
|
+
queryKey: ['key'],
|
|
76
|
+
queryFn: () => Promise.resolve(5),
|
|
77
|
+
initialPageParam: 1,
|
|
78
|
+
getNextPageParam: () => 1,
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
const result: Expect<Equal<typeof data, InfiniteData<number, unknown>>> =
|
|
82
|
+
true
|
|
83
|
+
return result
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('should not have pending status', () => {
|
|
88
|
+
doNotExecute(() => {
|
|
89
|
+
const { status } = useSuspenseInfiniteQuery({
|
|
90
|
+
queryKey: ['key'],
|
|
91
|
+
queryFn: () => Promise.resolve(5),
|
|
92
|
+
initialPageParam: 1,
|
|
93
|
+
getNextPageParam: () => 1,
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
const result: Expect<Equal<typeof status, 'error' | 'success'>> = true
|
|
97
|
+
return result
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('should not allow placeholderData, enabled or throwOnError props', () => {
|
|
102
|
+
doNotExecute(() => {
|
|
103
|
+
useSuspenseInfiniteQuery({
|
|
104
|
+
queryKey: ['key'],
|
|
105
|
+
queryFn: () => Promise.resolve(5),
|
|
106
|
+
initialPageParam: 1,
|
|
107
|
+
getNextPageParam: () => 1,
|
|
108
|
+
// @ts-expect-error TS2345
|
|
109
|
+
placeholderData: 5,
|
|
110
|
+
enabled: true,
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
useSuspenseInfiniteQuery({
|
|
114
|
+
queryKey: ['key'],
|
|
115
|
+
queryFn: () => Promise.resolve(5),
|
|
116
|
+
initialPageParam: 1,
|
|
117
|
+
getNextPageParam: () => 1,
|
|
118
|
+
// @ts-expect-error TS2345
|
|
119
|
+
enabled: true,
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
useSuspenseInfiniteQuery({
|
|
123
|
+
queryKey: ['key'],
|
|
124
|
+
queryFn: () => Promise.resolve(5),
|
|
125
|
+
initialPageParam: 1,
|
|
126
|
+
getNextPageParam: () => 1,
|
|
127
|
+
// @ts-expect-error TS2345
|
|
128
|
+
throwOnError: true,
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it('should not return isPlaceholderData', () => {
|
|
134
|
+
doNotExecute(() => {
|
|
135
|
+
const query = useSuspenseInfiniteQuery({
|
|
136
|
+
queryKey: ['key'],
|
|
137
|
+
queryFn: () => Promise.resolve(5),
|
|
138
|
+
initialPageParam: 1,
|
|
139
|
+
getNextPageParam: () => 1,
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
// @ts-expect-error TS2339
|
|
143
|
+
void query.isPlaceholderData
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
})
|
|
@@ -377,6 +377,10 @@ describe('useQueries', () => {
|
|
|
377
377
|
const key2 = queryKey()
|
|
378
378
|
const key3 = queryKey()
|
|
379
379
|
const key4 = queryKey()
|
|
380
|
+
const key5 = queryKey()
|
|
381
|
+
|
|
382
|
+
type BizError = { code: number }
|
|
383
|
+
const throwOnError = (_error: BizError) => true
|
|
380
384
|
|
|
381
385
|
// @ts-expect-error (Page component is not rendered)
|
|
382
386
|
// eslint-disable-next-line
|
|
@@ -391,6 +395,18 @@ describe('useQueries', () => {
|
|
|
391
395
|
expectTypeOf<Array<QueryObserverResult<number, unknown>>>(result1)
|
|
392
396
|
expectTypeOf<number | undefined>(result1[0]?.data)
|
|
393
397
|
|
|
398
|
+
// Array.map preserves TError
|
|
399
|
+
const result1_err = useQueries({
|
|
400
|
+
queries: Array(50).map((_, i) => ({
|
|
401
|
+
queryKey: ['key', i] as const,
|
|
402
|
+
queryFn: () => i + 10,
|
|
403
|
+
throwOnError,
|
|
404
|
+
})),
|
|
405
|
+
})
|
|
406
|
+
expectTypeOf<Array<QueryObserverResult<number, unknown>>>(result1_err)
|
|
407
|
+
expectTypeOf<number | undefined>(result1_err[0]?.data)
|
|
408
|
+
expectTypeOf<BizError | null | undefined>(result1_err[0]?.error)
|
|
409
|
+
|
|
394
410
|
// Array.map preserves TData
|
|
395
411
|
const result2 = useQueries({
|
|
396
412
|
queries: Array(50).map((_, i) => ({
|
|
@@ -401,6 +417,16 @@ describe('useQueries', () => {
|
|
|
401
417
|
})
|
|
402
418
|
expectTypeOf<Array<QueryObserverResult<string, unknown>>>(result2)
|
|
403
419
|
|
|
420
|
+
const result2_err = useQueries({
|
|
421
|
+
queries: Array(50).map((_, i) => ({
|
|
422
|
+
queryKey: ['key', i] as const,
|
|
423
|
+
queryFn: () => i + 10,
|
|
424
|
+
select: (data: number) => data.toString(),
|
|
425
|
+
throwOnError,
|
|
426
|
+
})),
|
|
427
|
+
})
|
|
428
|
+
expectTypeOf<Array<QueryObserverResult<string, BizError>>>(result2_err)
|
|
429
|
+
|
|
404
430
|
const result3 = useQueries({
|
|
405
431
|
queries: [
|
|
406
432
|
{
|
|
@@ -416,6 +442,11 @@ describe('useQueries', () => {
|
|
|
416
442
|
queryFn: () => ['string[]'],
|
|
417
443
|
select: () => 123,
|
|
418
444
|
},
|
|
445
|
+
{
|
|
446
|
+
queryKey: key5,
|
|
447
|
+
queryFn: () => 'string',
|
|
448
|
+
throwOnError,
|
|
449
|
+
},
|
|
419
450
|
],
|
|
420
451
|
})
|
|
421
452
|
expectTypeOf<QueryObserverResult<number, unknown>>(result3[0])
|
|
@@ -423,8 +454,11 @@ describe('useQueries', () => {
|
|
|
423
454
|
expectTypeOf<QueryObserverResult<number, unknown>>(result3[2])
|
|
424
455
|
expectTypeOf<number | undefined>(result3[0].data)
|
|
425
456
|
expectTypeOf<string | undefined>(result3[1].data)
|
|
457
|
+
expectTypeOf<string | undefined>(result3[3].data)
|
|
426
458
|
// select takes precedence over queryFn
|
|
427
459
|
expectTypeOf<number | undefined>(result3[2].data)
|
|
460
|
+
// infer TError from throwOnError
|
|
461
|
+
expectTypeOf<BizError | null | undefined>(result3[3].error)
|
|
428
462
|
|
|
429
463
|
// initialData/placeholderData are enforced
|
|
430
464
|
useQueries({
|
|
@@ -446,7 +480,7 @@ describe('useQueries', () => {
|
|
|
446
480
|
],
|
|
447
481
|
})
|
|
448
482
|
|
|
449
|
-
// select params are "indirectly" enforced
|
|
483
|
+
// select and throwOnError params are "indirectly" enforced
|
|
450
484
|
useQueries({
|
|
451
485
|
queries: [
|
|
452
486
|
// unfortunately TS will not suggest the type for you
|
|
@@ -469,6 +503,11 @@ describe('useQueries', () => {
|
|
|
469
503
|
queryFn: () => 'string',
|
|
470
504
|
select: (a: string) => parseInt(a),
|
|
471
505
|
},
|
|
506
|
+
{
|
|
507
|
+
queryKey: key5,
|
|
508
|
+
queryFn: () => 'string',
|
|
509
|
+
throwOnError,
|
|
510
|
+
},
|
|
472
511
|
],
|
|
473
512
|
})
|
|
474
513
|
|
|
@@ -504,11 +543,18 @@ describe('useQueries', () => {
|
|
|
504
543
|
queryFn: () => 'string',
|
|
505
544
|
select: (a: string) => parseInt(a),
|
|
506
545
|
},
|
|
546
|
+
{
|
|
547
|
+
queryKey: key5,
|
|
548
|
+
queryFn: () => 'string',
|
|
549
|
+
select: (a: string) => parseInt(a),
|
|
550
|
+
throwOnError,
|
|
551
|
+
},
|
|
507
552
|
],
|
|
508
553
|
})
|
|
509
554
|
expectTypeOf<QueryObserverResult<string, unknown>>(result4[0])
|
|
510
555
|
expectTypeOf<QueryObserverResult<string, unknown>>(result4[1])
|
|
511
556
|
expectTypeOf<QueryObserverResult<number, unknown>>(result4[2])
|
|
557
|
+
expectTypeOf<QueryObserverResult<number, BizError>>(result4[3])
|
|
512
558
|
|
|
513
559
|
// handles when queryFn returns a Promise
|
|
514
560
|
const result5 = useQueries({
|
|
@@ -532,10 +578,16 @@ describe('useQueries', () => {
|
|
|
532
578
|
queryKey: ['key1'],
|
|
533
579
|
queryFn: () => 123,
|
|
534
580
|
},
|
|
581
|
+
{
|
|
582
|
+
queryKey: key5,
|
|
583
|
+
queryFn: () => 'string',
|
|
584
|
+
throwOnError,
|
|
585
|
+
},
|
|
535
586
|
],
|
|
536
587
|
} as const)
|
|
537
588
|
expectTypeOf<QueryObserverResult<string, unknown>>(result6[0])
|
|
538
589
|
expectTypeOf<QueryObserverResult<number, unknown>>(result6[1])
|
|
590
|
+
expectTypeOf<QueryObserverResult<string, BizError>>(result6[2])
|
|
539
591
|
|
|
540
592
|
// field names should be enforced - array literal
|
|
541
593
|
useQueries({
|
|
@@ -4146,7 +4146,7 @@ describe('useQuery', () => {
|
|
|
4146
4146
|
await sleep(10)
|
|
4147
4147
|
return count++
|
|
4148
4148
|
},
|
|
4149
|
-
refetchInterval: (data = 0) => (data < 2 ? 10 : false),
|
|
4149
|
+
refetchInterval: ({ state: { data = 0 } }) => (data < 2 ? 10 : false),
|
|
4150
4150
|
})
|
|
4151
4151
|
|
|
4152
4152
|
states.push(queryInfo)
|
|
@@ -47,13 +47,15 @@ describe('initialData', () => {
|
|
|
47
47
|
|
|
48
48
|
it('it should be possible to define a different TData than TQueryFnData using select with queryOptions spread into useQuery', () => {
|
|
49
49
|
doNotExecute(() => {
|
|
50
|
-
const options =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
const options = queryOptions({
|
|
51
|
+
queryKey: ['key'],
|
|
52
|
+
queryFn: () => Promise.resolve(1),
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
const query = useQuery({
|
|
56
|
+
...options,
|
|
57
|
+
select: (data) => data > 1,
|
|
58
|
+
})
|
|
57
59
|
|
|
58
60
|
const result: Expect<
|
|
59
61
|
Equal<boolean | undefined, (typeof query)['data']>
|
package/src/types.ts
CHANGED
|
@@ -6,14 +6,12 @@ import type {
|
|
|
6
6
|
DefinedQueryObserverResult,
|
|
7
7
|
InfiniteQueryObserverOptions,
|
|
8
8
|
InfiniteQueryObserverResult,
|
|
9
|
-
InfiniteQueryObserverSuccessResult,
|
|
10
9
|
MutateFunction,
|
|
11
10
|
MutationObserverOptions,
|
|
12
11
|
MutationObserverResult,
|
|
13
12
|
QueryKey,
|
|
14
13
|
QueryObserverOptions,
|
|
15
14
|
QueryObserverResult,
|
|
16
|
-
QueryObserverSuccessResult,
|
|
17
15
|
WithRequired,
|
|
18
16
|
} from '@tanstack/query-core'
|
|
19
17
|
|
|
@@ -105,7 +103,7 @@ export type UseQueryResult<
|
|
|
105
103
|
export type UseSuspenseQueryResult<
|
|
106
104
|
TData = unknown,
|
|
107
105
|
TError = DefaultError,
|
|
108
|
-
> = Omit<
|
|
106
|
+
> = Omit<DefinedQueryObserverResult<TData, TError>, 'isPlaceholderData'>
|
|
109
107
|
|
|
110
108
|
export type DefinedUseQueryResult<
|
|
111
109
|
TData = unknown,
|
|
@@ -125,7 +123,7 @@ export type DefinedUseInfiniteQueryResult<
|
|
|
125
123
|
export type UseSuspenseInfiniteQueryResult<
|
|
126
124
|
TData = unknown,
|
|
127
125
|
TError = DefaultError,
|
|
128
|
-
> = Omit<
|
|
126
|
+
> = Omit<DefinedInfiniteQueryObserverResult<TData, TError>, 'isPlaceholderData'>
|
|
129
127
|
|
|
130
128
|
export interface UseMutationOptions<
|
|
131
129
|
TData = unknown,
|