@tanstack/react-query 5.0.0-beta.9 → 5.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/build/legacy/HydrationBoundary.cjs +37 -2
- package/build/legacy/HydrationBoundary.cjs.map +1 -1
- package/build/legacy/HydrationBoundary.d.cts +3 -1
- package/build/legacy/HydrationBoundary.d.ts +3 -1
- package/build/legacy/HydrationBoundary.js +37 -2
- package/build/legacy/HydrationBoundary.js.map +1 -1
- package/build/legacy/index.cjs +3 -0
- package/build/legacy/index.cjs.map +1 -1
- package/build/legacy/index.d.cts +1 -0
- package/build/legacy/index.d.ts +1 -0
- package/build/legacy/index.js +2 -0
- package/build/legacy/index.js.map +1 -1
- package/build/legacy/queryOptions.cjs.map +1 -1
- package/build/legacy/queryOptions.d.cts +7 -3
- package/build/legacy/queryOptions.d.ts +7 -3
- package/build/legacy/queryOptions.js.map +1 -1
- package/build/legacy/suspense.cjs +3 -0
- package/build/legacy/suspense.cjs.map +1 -1
- package/build/legacy/suspense.d.cts +3 -2
- package/build/legacy/suspense.d.ts +3 -2
- package/build/legacy/suspense.js +2 -0
- package/build/legacy/suspense.js.map +1 -1
- package/build/legacy/types.cjs.map +1 -1
- package/build/legacy/types.d.cts +4 -4
- package/build/legacy/types.d.ts +4 -4
- package/build/legacy/useQueries.cjs.map +1 -1
- package/build/legacy/useQueries.d.cts +4 -4
- package/build/legacy/useQueries.d.ts +4 -4
- package/build/legacy/useQueries.js.map +1 -1
- package/build/legacy/useSuspenseQueries.cjs +47 -0
- package/build/legacy/useSuspenseQueries.cjs.map +1 -0
- package/build/legacy/useSuspenseQueries.d.cts +66 -0
- package/build/legacy/useSuspenseQueries.d.ts +66 -0
- package/build/legacy/useSuspenseQueries.js +23 -0
- package/build/legacy/useSuspenseQueries.js.map +1 -0
- package/build/legacy/useSuspenseQuery.cjs +2 -1
- package/build/legacy/useSuspenseQuery.cjs.map +1 -1
- package/build/legacy/useSuspenseQuery.js +2 -1
- package/build/legacy/useSuspenseQuery.js.map +1 -1
- package/build/legacy/utils.cjs.map +1 -1
- package/build/legacy/utils.d.cts +1 -1
- package/build/legacy/utils.d.ts +1 -1
- package/build/legacy/utils.js.map +1 -1
- package/build/modern/HydrationBoundary.cjs +37 -2
- package/build/modern/HydrationBoundary.cjs.map +1 -1
- package/build/modern/HydrationBoundary.d.cts +3 -1
- package/build/modern/HydrationBoundary.d.ts +3 -1
- package/build/modern/HydrationBoundary.js +37 -2
- package/build/modern/HydrationBoundary.js.map +1 -1
- package/build/modern/index.cjs +3 -0
- package/build/modern/index.cjs.map +1 -1
- package/build/modern/index.d.cts +1 -0
- package/build/modern/index.d.ts +1 -0
- package/build/modern/index.js +2 -0
- package/build/modern/index.js.map +1 -1
- package/build/modern/queryOptions.cjs.map +1 -1
- package/build/modern/queryOptions.d.cts +7 -3
- package/build/modern/queryOptions.d.ts +7 -3
- package/build/modern/queryOptions.js.map +1 -1
- package/build/modern/suspense.cjs +3 -0
- package/build/modern/suspense.cjs.map +1 -1
- package/build/modern/suspense.d.cts +3 -2
- package/build/modern/suspense.d.ts +3 -2
- package/build/modern/suspense.js +2 -0
- package/build/modern/suspense.js.map +1 -1
- package/build/modern/types.cjs.map +1 -1
- package/build/modern/types.d.cts +4 -4
- package/build/modern/types.d.ts +4 -4
- package/build/modern/useQueries.cjs.map +1 -1
- package/build/modern/useQueries.d.cts +4 -4
- package/build/modern/useQueries.d.ts +4 -4
- package/build/modern/useQueries.js.map +1 -1
- package/build/modern/useSuspenseQueries.cjs +47 -0
- package/build/modern/useSuspenseQueries.cjs.map +1 -0
- package/build/modern/useSuspenseQueries.d.cts +66 -0
- package/build/modern/useSuspenseQueries.d.ts +66 -0
- package/build/modern/useSuspenseQueries.js +23 -0
- package/build/modern/useSuspenseQueries.js.map +1 -0
- package/build/modern/useSuspenseQuery.cjs +2 -1
- package/build/modern/useSuspenseQuery.cjs.map +1 -1
- package/build/modern/useSuspenseQuery.js +2 -1
- package/build/modern/useSuspenseQuery.js.map +1 -1
- package/build/modern/utils.cjs.map +1 -1
- package/build/modern/utils.d.cts +1 -1
- package/build/modern/utils.d.ts +1 -1
- package/build/modern/utils.js.map +1 -1
- package/package.json +7 -3
- package/src/HydrationBoundary.tsx +78 -8
- package/src/__tests__/HydrationBoundary.test.tsx +111 -7
- package/src/__tests__/QueryResetErrorBoundary.test.tsx +10 -6
- package/src/__tests__/fine-grained-persister.test.tsx +163 -0
- package/src/__tests__/queryOptions.types.test.tsx +31 -0
- package/src/__tests__/ssr.test.tsx +2 -2
- package/src/__tests__/suspense.test.tsx +94 -386
- package/src/__tests__/useInfiniteQuery.test.tsx +44 -44
- package/src/__tests__/useInfiniteQuery.type.test.tsx +10 -10
- package/src/__tests__/useIsFetching.test.tsx +2 -2
- package/src/__tests__/useMutation.test.tsx +4 -4
- package/src/__tests__/useMutationState.test.tsx +4 -4
- package/src/__tests__/useQueries.test.tsx +65 -64
- package/src/__tests__/useQuery.test.tsx +142 -141
- package/src/__tests__/useQuery.types.test.tsx +34 -0
- package/src/__tests__/utils.tsx +0 -7
- package/src/index.ts +5 -0
- package/src/queryOptions.ts +11 -3
- package/src/suspense.ts +12 -0
- package/src/types.ts +18 -12
- package/src/useQueries.ts +34 -28
- package/src/useSuspenseQueries.ts +164 -0
- package/src/useSuspenseQuery.ts +2 -1
- package/src/utils.ts +1 -1
- package/build/codemods/coverage/base.css +0 -224
- package/build/codemods/coverage/block-navigation.js +0 -87
- package/build/codemods/coverage/clover.xml +0 -6
- package/build/codemods/coverage/coverage-final.json +0 -1
- package/build/codemods/coverage/favicon.png +0 -0
- package/build/codemods/coverage/index.html +0 -101
- package/build/codemods/coverage/prettify.css +0 -1
- package/build/codemods/coverage/prettify.js +0 -2
- package/build/codemods/coverage/sort-arrow-sprite.png +0 -0
- package/build/codemods/coverage/sorter.js +0 -196
|
@@ -111,6 +111,26 @@ describe('initialData', () => {
|
|
|
111
111
|
return result
|
|
112
112
|
})
|
|
113
113
|
})
|
|
114
|
+
|
|
115
|
+
it('TData should be narrowed after an isSuccess check when initialData is provided as a function which can return undefined', () => {
|
|
116
|
+
doNotExecute(() => {
|
|
117
|
+
const { data, isSuccess } = useQuery({
|
|
118
|
+
queryKey: ['key'],
|
|
119
|
+
queryFn: () => {
|
|
120
|
+
return {
|
|
121
|
+
wow: true,
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
initialData: () => undefined as { wow: boolean } | undefined,
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
if (isSuccess) {
|
|
128
|
+
const result: Expect<Equal<{ wow: boolean }, typeof data>> = true
|
|
129
|
+
return result
|
|
130
|
+
}
|
|
131
|
+
return false
|
|
132
|
+
})
|
|
133
|
+
})
|
|
114
134
|
})
|
|
115
135
|
|
|
116
136
|
describe('custom hook', () => {
|
|
@@ -135,4 +155,18 @@ describe('initialData', () => {
|
|
|
135
155
|
})
|
|
136
156
|
})
|
|
137
157
|
})
|
|
158
|
+
|
|
159
|
+
describe('structuralSharing', () => {
|
|
160
|
+
it('should restrict to same types', () => {
|
|
161
|
+
doNotExecute(() => {
|
|
162
|
+
useQuery({
|
|
163
|
+
queryKey: ['key'],
|
|
164
|
+
queryFn: () => 5,
|
|
165
|
+
structuralSharing: (_oldData, newData) => {
|
|
166
|
+
return newData
|
|
167
|
+
},
|
|
168
|
+
})
|
|
169
|
+
})
|
|
170
|
+
})
|
|
171
|
+
})
|
|
138
172
|
})
|
package/src/__tests__/utils.tsx
CHANGED
|
@@ -79,13 +79,6 @@ export function setActTimeout(fn: () => void, ms?: number) {
|
|
|
79
79
|
}, ms)
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
/**
|
|
83
|
-
* Assert the parameter is of a specific type.
|
|
84
|
-
*/
|
|
85
|
-
export function expectType<T>(_: T): void {
|
|
86
|
-
return undefined
|
|
87
|
-
}
|
|
88
|
-
|
|
89
82
|
export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <
|
|
90
83
|
T,
|
|
91
84
|
>() => T extends Y ? 1 : 2
|
package/src/index.ts
CHANGED
|
@@ -10,6 +10,11 @@ export type { QueriesResults, QueriesOptions } from './useQueries'
|
|
|
10
10
|
export { useQuery } from './useQuery'
|
|
11
11
|
export { useSuspenseQuery } from './useSuspenseQuery'
|
|
12
12
|
export { useSuspenseInfiniteQuery } from './useSuspenseInfiniteQuery'
|
|
13
|
+
export { useSuspenseQueries } from './useSuspenseQueries'
|
|
14
|
+
export type {
|
|
15
|
+
SuspenseQueriesResults,
|
|
16
|
+
SuspenseQueriesOptions,
|
|
17
|
+
} from './useSuspenseQueries'
|
|
13
18
|
export { queryOptions } from './queryOptions'
|
|
14
19
|
export type {
|
|
15
20
|
DefinedInitialDataOptions,
|
package/src/queryOptions.ts
CHANGED
|
@@ -10,13 +10,21 @@ export type UndefinedInitialDataOptions<
|
|
|
10
10
|
initialData?: undefined
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
type NonUndefinedGuard<T> = T extends undefined ? never : T
|
|
14
|
+
|
|
13
15
|
export type DefinedInitialDataOptions<
|
|
14
16
|
TQueryFnData = unknown,
|
|
15
17
|
TError = DefaultError,
|
|
16
18
|
TData = TQueryFnData,
|
|
17
19
|
TQueryKey extends QueryKey = QueryKey,
|
|
18
20
|
> = UseQueryOptions<TQueryFnData, TError, TData, TQueryKey> & {
|
|
19
|
-
initialData:
|
|
21
|
+
initialData:
|
|
22
|
+
| NonUndefinedGuard<TQueryFnData>
|
|
23
|
+
| (() => NonUndefinedGuard<TQueryFnData>)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type ValidateQueryOptions<T> = {
|
|
27
|
+
[K in keyof T]: K extends keyof UseQueryOptions ? T[K] : never
|
|
20
28
|
}
|
|
21
29
|
|
|
22
30
|
export function queryOptions<
|
|
@@ -30,7 +38,7 @@ export function queryOptions<
|
|
|
30
38
|
TData,
|
|
31
39
|
TQueryKey
|
|
32
40
|
> = UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,
|
|
33
|
-
>(options: TOptions): TOptions
|
|
41
|
+
>(options: ValidateQueryOptions<TOptions>): TOptions
|
|
34
42
|
|
|
35
43
|
export function queryOptions<
|
|
36
44
|
TQueryFnData = unknown,
|
|
@@ -43,7 +51,7 @@ export function queryOptions<
|
|
|
43
51
|
TData,
|
|
44
52
|
TQueryKey
|
|
45
53
|
> = DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,
|
|
46
|
-
>(options: TOptions): TOptions
|
|
54
|
+
>(options: ValidateQueryOptions<TOptions>): TOptions
|
|
47
55
|
|
|
48
56
|
export function queryOptions(options: unknown) {
|
|
49
57
|
return options
|
package/src/suspense.ts
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
|
+
import type { DefaultError } from '@tanstack/query-core/src'
|
|
1
2
|
import type {
|
|
2
3
|
DefaultedQueryObserverOptions,
|
|
4
|
+
Query,
|
|
3
5
|
QueryKey,
|
|
4
6
|
QueryObserver,
|
|
5
7
|
QueryObserverResult,
|
|
6
8
|
} from '@tanstack/query-core'
|
|
7
9
|
import type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'
|
|
8
10
|
|
|
11
|
+
export const defaultThrowOnError = <
|
|
12
|
+
TQueryFnData = unknown,
|
|
13
|
+
TError = DefaultError,
|
|
14
|
+
TData = TQueryFnData,
|
|
15
|
+
TQueryKey extends QueryKey = QueryKey,
|
|
16
|
+
>(
|
|
17
|
+
_error: TError,
|
|
18
|
+
query: Query<TQueryFnData, TError, TData, TQueryKey>,
|
|
19
|
+
) => typeof query.state.data === 'undefined'
|
|
20
|
+
|
|
9
21
|
export const ensureStaleTime = (
|
|
10
22
|
defaultedOptions: DefaultedQueryObserverOptions<any, any, any, any, any>,
|
|
11
23
|
) => {
|
package/src/types.ts
CHANGED
|
@@ -33,9 +33,12 @@ export interface UseQueryOptions<
|
|
|
33
33
|
TError = DefaultError,
|
|
34
34
|
TData = TQueryFnData,
|
|
35
35
|
TQueryKey extends QueryKey = QueryKey,
|
|
36
|
-
> extends
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
> extends Omit<
|
|
37
|
+
WithRequired<
|
|
38
|
+
UseBaseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>,
|
|
39
|
+
'queryKey'
|
|
40
|
+
>,
|
|
41
|
+
'suspense'
|
|
39
42
|
> {}
|
|
40
43
|
|
|
41
44
|
export interface UseSuspenseQueryOptions<
|
|
@@ -45,7 +48,7 @@ export interface UseSuspenseQueryOptions<
|
|
|
45
48
|
TQueryKey extends QueryKey = QueryKey,
|
|
46
49
|
> extends Omit<
|
|
47
50
|
UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
|
|
48
|
-
'enabled' | '
|
|
51
|
+
'enabled' | 'throwOnError' | 'placeholderData'
|
|
49
52
|
> {}
|
|
50
53
|
|
|
51
54
|
export interface UseInfiniteQueryOptions<
|
|
@@ -56,13 +59,16 @@ export interface UseInfiniteQueryOptions<
|
|
|
56
59
|
TQueryKey extends QueryKey = QueryKey,
|
|
57
60
|
TPageParam = unknown,
|
|
58
61
|
> extends WithRequired<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
Omit<
|
|
63
|
+
InfiniteQueryObserverOptions<
|
|
64
|
+
TQueryFnData,
|
|
65
|
+
TError,
|
|
66
|
+
TData,
|
|
67
|
+
TQueryData,
|
|
68
|
+
TQueryKey,
|
|
69
|
+
TPageParam
|
|
70
|
+
>,
|
|
71
|
+
'suspense'
|
|
66
72
|
>,
|
|
67
73
|
'queryKey'
|
|
68
74
|
> {}
|
|
@@ -83,7 +89,7 @@ export interface UseSuspenseInfiniteQueryOptions<
|
|
|
83
89
|
TQueryKey,
|
|
84
90
|
TPageParam
|
|
85
91
|
>,
|
|
86
|
-
'enabled' | '
|
|
92
|
+
'enabled' | 'throwOnError' | 'placeholderData'
|
|
87
93
|
> {}
|
|
88
94
|
|
|
89
95
|
export type UseBaseQueryResult<
|
package/src/useQueries.ts
CHANGED
|
@@ -35,7 +35,7 @@ type UseQueryOptionsForUseQueries<
|
|
|
35
35
|
TQueryKey extends QueryKey = QueryKey,
|
|
36
36
|
> = Omit<
|
|
37
37
|
UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
|
|
38
|
-
'placeholderData'
|
|
38
|
+
'placeholderData' | 'suspense'
|
|
39
39
|
> & {
|
|
40
40
|
placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>
|
|
41
41
|
}
|
|
@@ -103,62 +103,68 @@ type GetResults<T> =
|
|
|
103
103
|
* QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param
|
|
104
104
|
*/
|
|
105
105
|
export type QueriesOptions<
|
|
106
|
-
T extends any
|
|
107
|
-
Result extends any
|
|
106
|
+
T extends Array<any>,
|
|
107
|
+
Result extends Array<any> = [],
|
|
108
108
|
Depth extends ReadonlyArray<number> = [],
|
|
109
109
|
> = Depth['length'] extends MAXIMUM_DEPTH
|
|
110
|
-
? UseQueryOptionsForUseQueries
|
|
110
|
+
? Array<UseQueryOptionsForUseQueries>
|
|
111
111
|
: T extends []
|
|
112
112
|
? []
|
|
113
113
|
: T extends [infer Head]
|
|
114
114
|
? [...Result, GetOptions<Head>]
|
|
115
115
|
: T extends [infer Head, ...infer Tail]
|
|
116
116
|
? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>
|
|
117
|
-
: unknown
|
|
117
|
+
: Array<unknown> extends T
|
|
118
118
|
? T
|
|
119
119
|
: // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogenous type!
|
|
120
120
|
// use this to infer the param types in the case of Array.map() argument
|
|
121
|
-
T extends
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
T extends Array<
|
|
122
|
+
UseQueryOptionsForUseQueries<
|
|
123
|
+
infer TQueryFnData,
|
|
124
|
+
infer TError,
|
|
125
|
+
infer TData,
|
|
126
|
+
infer TQueryKey
|
|
127
|
+
>
|
|
128
|
+
>
|
|
129
|
+
? Array<UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>>
|
|
128
130
|
: // Fallback
|
|
129
|
-
UseQueryOptionsForUseQueries
|
|
131
|
+
Array<UseQueryOptionsForUseQueries>
|
|
130
132
|
|
|
131
133
|
/**
|
|
132
134
|
* QueriesResults reducer recursively maps type param to results
|
|
133
135
|
*/
|
|
134
136
|
export type QueriesResults<
|
|
135
|
-
T extends any
|
|
136
|
-
Result extends any
|
|
137
|
+
T extends Array<any>,
|
|
138
|
+
Result extends Array<any> = [],
|
|
137
139
|
Depth extends ReadonlyArray<number> = [],
|
|
138
140
|
> = Depth['length'] extends MAXIMUM_DEPTH
|
|
139
|
-
? UseQueryResult
|
|
141
|
+
? Array<UseQueryResult>
|
|
140
142
|
: T extends []
|
|
141
143
|
? []
|
|
142
144
|
: T extends [infer Head]
|
|
143
145
|
? [...Result, GetResults<Head>]
|
|
144
146
|
: T extends [infer Head, ...infer Tail]
|
|
145
147
|
? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>
|
|
146
|
-
: T extends
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
148
|
+
: T extends Array<
|
|
149
|
+
UseQueryOptionsForUseQueries<
|
|
150
|
+
infer TQueryFnData,
|
|
151
|
+
infer TError,
|
|
152
|
+
infer TData,
|
|
153
|
+
any
|
|
154
|
+
>
|
|
155
|
+
>
|
|
152
156
|
? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
+
Array<
|
|
158
|
+
UseQueryResult<
|
|
159
|
+
unknown extends TData ? TQueryFnData : TData,
|
|
160
|
+
unknown extends TError ? DefaultError : TError
|
|
161
|
+
>
|
|
162
|
+
>
|
|
157
163
|
: // Fallback
|
|
158
|
-
UseQueryResult
|
|
164
|
+
Array<UseQueryResult>
|
|
159
165
|
|
|
160
166
|
export function useQueries<
|
|
161
|
-
T extends any
|
|
167
|
+
T extends Array<any>,
|
|
162
168
|
TCombinedResult = QueriesResults<T>,
|
|
163
169
|
>(
|
|
164
170
|
{
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { useQueries } from './useQueries'
|
|
3
|
+
import { defaultThrowOnError } from './suspense'
|
|
4
|
+
import type { UseSuspenseQueryOptions, UseSuspenseQueryResult } from './types'
|
|
5
|
+
import type {
|
|
6
|
+
DefaultError,
|
|
7
|
+
QueryClient,
|
|
8
|
+
QueryFunction,
|
|
9
|
+
} from '@tanstack/query-core'
|
|
10
|
+
|
|
11
|
+
// Avoid TS depth-limit error in case of large array literal
|
|
12
|
+
type MAXIMUM_DEPTH = 20
|
|
13
|
+
|
|
14
|
+
type GetSuspenseOptions<T> =
|
|
15
|
+
// Part 1: responsible for applying explicit type parameter to function arguments, if object { queryFnData: TQueryFnData, error: TError, data: TData }
|
|
16
|
+
T extends {
|
|
17
|
+
queryFnData: infer TQueryFnData
|
|
18
|
+
error?: infer TError
|
|
19
|
+
data: infer TData
|
|
20
|
+
}
|
|
21
|
+
? UseSuspenseQueryOptions<TQueryFnData, TError, TData>
|
|
22
|
+
: T extends { queryFnData: infer TQueryFnData; error?: infer TError }
|
|
23
|
+
? UseSuspenseQueryOptions<TQueryFnData, TError>
|
|
24
|
+
: T extends { data: infer TData; error?: infer TError }
|
|
25
|
+
? UseSuspenseQueryOptions<unknown, TError, TData>
|
|
26
|
+
: // Part 2: responsible for applying explicit type parameter to function arguments, if tuple [TQueryFnData, TError, TData]
|
|
27
|
+
T extends [infer TQueryFnData, infer TError, infer TData]
|
|
28
|
+
? UseSuspenseQueryOptions<TQueryFnData, TError, TData>
|
|
29
|
+
: T extends [infer TQueryFnData, infer TError]
|
|
30
|
+
? UseSuspenseQueryOptions<TQueryFnData, TError>
|
|
31
|
+
: T extends [infer TQueryFnData]
|
|
32
|
+
? UseSuspenseQueryOptions<TQueryFnData>
|
|
33
|
+
: // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided
|
|
34
|
+
T extends {
|
|
35
|
+
queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>
|
|
36
|
+
select: (data: any) => infer TData
|
|
37
|
+
}
|
|
38
|
+
? UseSuspenseQueryOptions<TQueryFnData, Error, TData, TQueryKey>
|
|
39
|
+
: T extends { queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey> }
|
|
40
|
+
? UseSuspenseQueryOptions<TQueryFnData, Error, TQueryFnData, TQueryKey>
|
|
41
|
+
: // Fallback
|
|
42
|
+
UseSuspenseQueryOptions
|
|
43
|
+
|
|
44
|
+
type GetSuspenseResults<T> =
|
|
45
|
+
// Part 1: responsible for mapping explicit type parameter to function result, if object
|
|
46
|
+
T extends { queryFnData: any; error?: infer TError; data: infer TData }
|
|
47
|
+
? UseSuspenseQueryResult<TData, TError>
|
|
48
|
+
: T extends { queryFnData: infer TQueryFnData; error?: infer TError }
|
|
49
|
+
? UseSuspenseQueryResult<TQueryFnData, TError>
|
|
50
|
+
: T extends { data: infer TData; error?: infer TError }
|
|
51
|
+
? UseSuspenseQueryResult<TData, TError>
|
|
52
|
+
: // Part 2: responsible for mapping explicit type parameter to function result, if tuple
|
|
53
|
+
T extends [any, infer TError, infer TData]
|
|
54
|
+
? UseSuspenseQueryResult<TData, TError>
|
|
55
|
+
: T extends [infer TQueryFnData, infer TError]
|
|
56
|
+
? UseSuspenseQueryResult<TQueryFnData, TError>
|
|
57
|
+
: T extends [infer TQueryFnData]
|
|
58
|
+
? UseSuspenseQueryResult<TQueryFnData>
|
|
59
|
+
: // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided
|
|
60
|
+
T extends {
|
|
61
|
+
queryFn?: QueryFunction<unknown, any>
|
|
62
|
+
select: (data: any) => infer TData
|
|
63
|
+
}
|
|
64
|
+
? UseSuspenseQueryResult<TData>
|
|
65
|
+
: T extends { queryFn?: QueryFunction<infer TQueryFnData, any> }
|
|
66
|
+
? UseSuspenseQueryResult<TQueryFnData>
|
|
67
|
+
: // Fallback
|
|
68
|
+
UseSuspenseQueryResult
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* SuspenseQueriesOptions reducer recursively unwraps function arguments to infer/enforce type param
|
|
72
|
+
*/
|
|
73
|
+
export type SuspenseQueriesOptions<
|
|
74
|
+
T extends Array<any>,
|
|
75
|
+
Result extends Array<any> = [],
|
|
76
|
+
Depth extends ReadonlyArray<number> = [],
|
|
77
|
+
> = Depth['length'] extends MAXIMUM_DEPTH
|
|
78
|
+
? Array<UseSuspenseQueryOptions>
|
|
79
|
+
: T extends []
|
|
80
|
+
? []
|
|
81
|
+
: T extends [infer Head]
|
|
82
|
+
? [...Result, GetSuspenseOptions<Head>]
|
|
83
|
+
: T extends [infer Head, ...infer Tail]
|
|
84
|
+
? SuspenseQueriesOptions<
|
|
85
|
+
[...Tail],
|
|
86
|
+
[...Result, GetSuspenseOptions<Head>],
|
|
87
|
+
[...Depth, 1]
|
|
88
|
+
>
|
|
89
|
+
: Array<unknown> extends T
|
|
90
|
+
? T
|
|
91
|
+
: // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogenous type!
|
|
92
|
+
// use this to infer the param types in the case of Array.map() argument
|
|
93
|
+
T extends Array<
|
|
94
|
+
UseSuspenseQueryOptions<
|
|
95
|
+
infer TQueryFnData,
|
|
96
|
+
infer TError,
|
|
97
|
+
infer TData,
|
|
98
|
+
infer TQueryKey
|
|
99
|
+
>
|
|
100
|
+
>
|
|
101
|
+
? Array<UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>>
|
|
102
|
+
: // Fallback
|
|
103
|
+
Array<UseSuspenseQueryOptions>
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* SuspenseQueriesResults reducer recursively maps type param to results
|
|
107
|
+
*/
|
|
108
|
+
export type SuspenseQueriesResults<
|
|
109
|
+
T extends Array<any>,
|
|
110
|
+
Result extends Array<any> = [],
|
|
111
|
+
Depth extends ReadonlyArray<number> = [],
|
|
112
|
+
> = Depth['length'] extends MAXIMUM_DEPTH
|
|
113
|
+
? Array<UseSuspenseQueryResult>
|
|
114
|
+
: T extends []
|
|
115
|
+
? []
|
|
116
|
+
: T extends [infer Head]
|
|
117
|
+
? [...Result, GetSuspenseResults<Head>]
|
|
118
|
+
: T extends [infer Head, ...infer Tail]
|
|
119
|
+
? SuspenseQueriesResults<
|
|
120
|
+
[...Tail],
|
|
121
|
+
[...Result, GetSuspenseResults<Head>],
|
|
122
|
+
[...Depth, 1]
|
|
123
|
+
>
|
|
124
|
+
: T extends Array<
|
|
125
|
+
UseSuspenseQueryOptions<
|
|
126
|
+
infer TQueryFnData,
|
|
127
|
+
infer TError,
|
|
128
|
+
infer TData,
|
|
129
|
+
any
|
|
130
|
+
>
|
|
131
|
+
>
|
|
132
|
+
? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results
|
|
133
|
+
Array<
|
|
134
|
+
UseSuspenseQueryResult<
|
|
135
|
+
unknown extends TData ? TQueryFnData : TData,
|
|
136
|
+
unknown extends TError ? DefaultError : TError
|
|
137
|
+
>
|
|
138
|
+
>
|
|
139
|
+
: // Fallback
|
|
140
|
+
Array<UseSuspenseQueryResult>
|
|
141
|
+
|
|
142
|
+
export function useSuspenseQueries<
|
|
143
|
+
T extends Array<any>,
|
|
144
|
+
TCombinedResult = SuspenseQueriesResults<T>,
|
|
145
|
+
>(
|
|
146
|
+
options: {
|
|
147
|
+
queries: readonly [...SuspenseQueriesOptions<T>]
|
|
148
|
+
combine?: (result: SuspenseQueriesResults<T>) => TCombinedResult
|
|
149
|
+
},
|
|
150
|
+
queryClient?: QueryClient,
|
|
151
|
+
): TCombinedResult {
|
|
152
|
+
return useQueries(
|
|
153
|
+
{
|
|
154
|
+
...options,
|
|
155
|
+
queries: options.queries.map((query) => ({
|
|
156
|
+
...query,
|
|
157
|
+
suspense: true,
|
|
158
|
+
throwOnError: defaultThrowOnError,
|
|
159
|
+
enabled: true,
|
|
160
|
+
})),
|
|
161
|
+
} as any,
|
|
162
|
+
queryClient,
|
|
163
|
+
)
|
|
164
|
+
}
|
package/src/useSuspenseQuery.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { QueryObserver } from '@tanstack/query-core'
|
|
3
3
|
import { useBaseQuery } from './useBaseQuery'
|
|
4
|
+
import { defaultThrowOnError } from './suspense'
|
|
4
5
|
import type { UseSuspenseQueryOptions, UseSuspenseQueryResult } from './types'
|
|
5
6
|
import type { DefaultError, QueryClient, QueryKey } from '@tanstack/query-core'
|
|
6
7
|
|
|
@@ -18,7 +19,7 @@ export function useSuspenseQuery<
|
|
|
18
19
|
...options,
|
|
19
20
|
enabled: true,
|
|
20
21
|
suspense: true,
|
|
21
|
-
throwOnError:
|
|
22
|
+
throwOnError: defaultThrowOnError,
|
|
22
23
|
},
|
|
23
24
|
QueryObserver,
|
|
24
25
|
queryClient,
|
package/src/utils.ts
CHANGED