@tanstack/react-query 5.0.0-beta.2 → 5.0.0-beta.23
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/index.cjs +3 -0
- package/build/legacy/index.cjs.map +1 -1
- package/build/legacy/index.d.cts +3 -2
- package/build/legacy/index.d.ts +3 -2
- package/build/legacy/index.js +2 -0
- package/build/legacy/index.js.map +1 -1
- package/build/legacy/infiniteQueryOptions.cjs.map +1 -1
- package/build/legacy/infiniteQueryOptions.d.cts +1 -1
- package/build/legacy/infiniteQueryOptions.d.ts +1 -1
- package/build/legacy/infiniteQueryOptions.js.map +1 -1
- package/build/legacy/queryOptions.cjs.map +1 -1
- package/build/legacy/queryOptions.d.cts +4 -3
- package/build/legacy/queryOptions.d.ts +4 -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/useInfiniteQuery.cjs.map +1 -1
- package/build/legacy/useInfiniteQuery.d.cts +2 -1
- package/build/legacy/useInfiniteQuery.d.ts +2 -1
- package/build/legacy/useInfiniteQuery.js.map +1 -1
- 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/useQuery.cjs.map +1 -1
- package/build/legacy/useQuery.d.cts +2 -1
- package/build/legacy/useQuery.d.ts +2 -1
- package/build/legacy/useQuery.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/index.cjs +3 -0
- package/build/modern/index.cjs.map +1 -1
- package/build/modern/index.d.cts +3 -2
- package/build/modern/index.d.ts +3 -2
- package/build/modern/index.js +2 -0
- package/build/modern/index.js.map +1 -1
- package/build/modern/infiniteQueryOptions.cjs.map +1 -1
- package/build/modern/infiniteQueryOptions.d.cts +1 -1
- package/build/modern/infiniteQueryOptions.d.ts +1 -1
- package/build/modern/infiniteQueryOptions.js.map +1 -1
- package/build/modern/queryOptions.cjs.map +1 -1
- package/build/modern/queryOptions.d.cts +4 -3
- package/build/modern/queryOptions.d.ts +4 -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/useInfiniteQuery.cjs.map +1 -1
- package/build/modern/useInfiniteQuery.d.cts +2 -1
- package/build/modern/useInfiniteQuery.d.ts +2 -1
- package/build/modern/useInfiniteQuery.js.map +1 -1
- 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/useQuery.cjs.map +1 -1
- package/build/modern/useQuery.d.cts +2 -1
- package/build/modern/useQuery.d.ts +2 -1
- package/build/modern/useQuery.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 +8 -4
- package/src/__tests__/QueryResetErrorBoundary.test.tsx +10 -6
- 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 +24 -13
- 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 +14 -12
- package/src/__tests__/useQuery.test.tsx +109 -80
- package/src/__tests__/useQuery.types.test.tsx +36 -55
- package/src/index.ts +13 -0
- package/src/infiniteQueryOptions.ts +3 -1
- package/src/queryOptions.ts +19 -7
- package/src/suspense.ts +12 -0
- package/src/types.ts +18 -12
- package/src/useInfiniteQuery.ts +7 -2
- package/src/useQueries.ts +34 -28
- package/src/useQuery.ts +3 -1
- package/src/useSuspenseQueries.ts +164 -0
- package/src/useSuspenseQuery.ts +2 -1
- package/src/utils.ts +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useQuery } from '../useQuery'
|
|
2
2
|
import { queryOptions } from '../queryOptions'
|
|
3
3
|
import { doNotExecute } from './utils'
|
|
4
|
+
import type { UseQueryOptions } from '../types'
|
|
4
5
|
import type { Equal, Expect } from './utils'
|
|
5
6
|
|
|
6
7
|
describe('initialData', () => {
|
|
@@ -44,6 +45,19 @@ describe('initialData', () => {
|
|
|
44
45
|
})
|
|
45
46
|
})
|
|
46
47
|
|
|
48
|
+
it('it should be possible to define a different TData than TQueryFnData using select with queryOptions spread into useQuery', () => {
|
|
49
|
+
doNotExecute(() => {
|
|
50
|
+
const options = queryOptions({
|
|
51
|
+
queryKey: ['key'],
|
|
52
|
+
queryFn: () => Promise.resolve(1),
|
|
53
|
+
})
|
|
54
|
+
useQuery({
|
|
55
|
+
...options,
|
|
56
|
+
select: (data) => data > 1,
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
|
|
47
61
|
it('TData should always be defined when initialData is provided as a function which ALWAYS returns the data', () => {
|
|
48
62
|
doNotExecute(() => {
|
|
49
63
|
const { data } = useQuery({
|
|
@@ -97,79 +111,46 @@ describe('initialData', () => {
|
|
|
97
111
|
return result
|
|
98
112
|
})
|
|
99
113
|
})
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
describe('Query key overload', () => {
|
|
103
|
-
it('TData should always be defined when initialData is provided', () => {
|
|
104
|
-
doNotExecute(() => {
|
|
105
|
-
const { data } = useQuery({
|
|
106
|
-
queryKey: ['key'],
|
|
107
|
-
queryFn: () => {
|
|
108
|
-
return {
|
|
109
|
-
wow: true,
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
initialData: {
|
|
113
|
-
wow: true,
|
|
114
|
-
},
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
const result: Expect<Equal<{ wow: boolean }, typeof data>> = true
|
|
118
|
-
return result
|
|
119
|
-
})
|
|
120
|
-
})
|
|
121
114
|
|
|
122
|
-
it('TData should
|
|
115
|
+
it('TData should be narrowed after an isSuccess check when initialData is provided as a function which can return undefined', () => {
|
|
123
116
|
doNotExecute(() => {
|
|
124
|
-
const { data } = useQuery({
|
|
117
|
+
const { data, isSuccess } = useQuery({
|
|
125
118
|
queryKey: ['key'],
|
|
126
119
|
queryFn: () => {
|
|
127
120
|
return {
|
|
128
121
|
wow: true,
|
|
129
122
|
}
|
|
130
123
|
},
|
|
124
|
+
initialData: () => undefined as { wow: boolean } | undefined,
|
|
131
125
|
})
|
|
132
126
|
|
|
133
|
-
|
|
134
|
-
true
|
|
135
|
-
|
|
127
|
+
if (isSuccess) {
|
|
128
|
+
const result: Expect<Equal<{ wow: boolean }, typeof data>> = true
|
|
129
|
+
return result
|
|
130
|
+
}
|
|
131
|
+
return false
|
|
136
132
|
})
|
|
137
133
|
})
|
|
138
134
|
})
|
|
139
135
|
|
|
140
|
-
describe('
|
|
141
|
-
it('
|
|
136
|
+
describe('custom hook', () => {
|
|
137
|
+
it('should allow custom hooks using UseQueryOptions', () => {
|
|
142
138
|
doNotExecute(() => {
|
|
143
|
-
|
|
144
|
-
queryKey: ['key'],
|
|
145
|
-
queryFn: () => {
|
|
146
|
-
return {
|
|
147
|
-
wow: true,
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
initialData: {
|
|
151
|
-
wow: true,
|
|
152
|
-
},
|
|
153
|
-
})
|
|
139
|
+
type Data = string
|
|
154
140
|
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
141
|
+
const useCustomQuery = (
|
|
142
|
+
options?: Omit<UseQueryOptions<Data>, 'queryKey' | 'queryFn'>,
|
|
143
|
+
) => {
|
|
144
|
+
return useQuery({
|
|
145
|
+
...options,
|
|
146
|
+
queryKey: ['todos-key'],
|
|
147
|
+
queryFn: () => Promise.resolve('data'),
|
|
148
|
+
})
|
|
149
|
+
}
|
|
159
150
|
|
|
160
|
-
|
|
161
|
-
doNotExecute(() => {
|
|
162
|
-
const { data } = useQuery({
|
|
163
|
-
queryKey: ['key'],
|
|
164
|
-
queryFn: () => {
|
|
165
|
-
return {
|
|
166
|
-
wow: true,
|
|
167
|
-
}
|
|
168
|
-
},
|
|
169
|
-
})
|
|
151
|
+
const { data } = useCustomQuery()
|
|
170
152
|
|
|
171
|
-
const result: Expect<Equal<
|
|
172
|
-
true
|
|
153
|
+
const result: Expect<Equal<Data | undefined, typeof data>> = true
|
|
173
154
|
return result
|
|
174
155
|
})
|
|
175
156
|
})
|
package/src/index.ts
CHANGED
|
@@ -10,8 +10,21 @@ 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'
|
|
19
|
+
export type {
|
|
20
|
+
DefinedInitialDataOptions,
|
|
21
|
+
UndefinedInitialDataOptions,
|
|
22
|
+
} from './queryOptions'
|
|
14
23
|
export { infiniteQueryOptions } from './infiniteQueryOptions'
|
|
24
|
+
export type {
|
|
25
|
+
DefinedInitialDataInfiniteOptions,
|
|
26
|
+
UndefinedInitialDataInfiniteOptions,
|
|
27
|
+
} from './infiniteQueryOptions'
|
|
15
28
|
export {
|
|
16
29
|
QueryClientContext,
|
|
17
30
|
QueryClientProvider,
|
|
@@ -35,7 +35,9 @@ export type DefinedInitialDataInfiniteOptions<
|
|
|
35
35
|
TQueryKey,
|
|
36
36
|
TPageParam
|
|
37
37
|
> & {
|
|
38
|
-
initialData:
|
|
38
|
+
initialData:
|
|
39
|
+
| InfiniteData<TQueryData, TPageParam>
|
|
40
|
+
| (() => InfiniteData<TQueryData, TPageParam>)
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
export function infiniteQueryOptions<
|
package/src/queryOptions.ts
CHANGED
|
@@ -10,13 +10,17 @@ 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>)
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
export function queryOptions<
|
|
@@ -24,18 +28,26 @@ export function queryOptions<
|
|
|
24
28
|
TError = DefaultError,
|
|
25
29
|
TData = TQueryFnData,
|
|
26
30
|
TQueryKey extends QueryKey = QueryKey,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
TOptions extends UndefinedInitialDataOptions<
|
|
32
|
+
TQueryFnData,
|
|
33
|
+
TError,
|
|
34
|
+
TData,
|
|
35
|
+
TQueryKey
|
|
36
|
+
> = UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,
|
|
37
|
+
>(options: TOptions): TOptions
|
|
30
38
|
|
|
31
39
|
export function queryOptions<
|
|
32
40
|
TQueryFnData = unknown,
|
|
33
41
|
TError = DefaultError,
|
|
34
42
|
TData = TQueryFnData,
|
|
35
43
|
TQueryKey extends QueryKey = QueryKey,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
TOptions extends DefinedInitialDataOptions<
|
|
45
|
+
TQueryFnData,
|
|
46
|
+
TError,
|
|
47
|
+
TData,
|
|
48
|
+
TQueryKey
|
|
49
|
+
> = DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,
|
|
50
|
+
>(options: TOptions): TOptions
|
|
39
51
|
|
|
40
52
|
export function queryOptions(options: unknown) {
|
|
41
53
|
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/useInfiniteQuery.ts
CHANGED
|
@@ -70,11 +70,16 @@ export function useInfiniteQuery<
|
|
|
70
70
|
TPageParam
|
|
71
71
|
>,
|
|
72
72
|
queryClient?: QueryClient,
|
|
73
|
-
): UseInfiniteQueryResult<TData, TError>
|
|
73
|
+
): UseInfiniteQueryResult<TData, TError>
|
|
74
|
+
|
|
75
|
+
export function useInfiniteQuery(
|
|
76
|
+
options: UseInfiniteQueryOptions,
|
|
77
|
+
queryClient?: QueryClient,
|
|
78
|
+
) {
|
|
74
79
|
return useBaseQuery(
|
|
75
80
|
options,
|
|
76
81
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
77
82
|
InfiniteQueryObserver as typeof QueryObserver,
|
|
78
83
|
queryClient,
|
|
79
|
-
)
|
|
84
|
+
)
|
|
80
85
|
}
|
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
|
{
|
package/src/useQuery.ts
CHANGED
|
@@ -40,6 +40,8 @@ export function useQuery<
|
|
|
40
40
|
>(
|
|
41
41
|
options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
|
|
42
42
|
queryClient?: QueryClient,
|
|
43
|
-
)
|
|
43
|
+
): UseQueryResult<TData, TError>
|
|
44
|
+
|
|
45
|
+
export function useQuery(options: UseQueryOptions, queryClient?: QueryClient) {
|
|
44
46
|
return useBaseQuery(options, QueryObserver, queryClient)
|
|
45
47
|
}
|
|
@@ -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