@tanstack/react-query 5.59.10 → 5.59.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/legacy/QueryErrorResetBoundary.cjs.map +1 -1
- package/build/legacy/QueryErrorResetBoundary.d.cts +9 -5
- package/build/legacy/QueryErrorResetBoundary.d.ts +9 -5
- package/build/legacy/QueryErrorResetBoundary.js.map +1 -1
- package/build/legacy/index.cjs.map +1 -1
- package/build/legacy/index.d.cts +3 -3
- package/build/legacy/index.d.ts +3 -3
- package/build/legacy/index.js.map +1 -1
- package/build/legacy/infiniteQueryOptions.cjs.map +1 -1
- package/build/legacy/infiniteQueryOptions.d.cts +8 -2
- package/build/legacy/infiniteQueryOptions.d.ts +8 -2
- package/build/legacy/infiniteQueryOptions.js.map +1 -1
- package/build/legacy/queryOptions.cjs.map +1 -1
- package/build/legacy/queryOptions.d.cts +8 -2
- package/build/legacy/queryOptions.d.ts +8 -2
- package/build/legacy/queryOptions.js.map +1 -1
- package/build/legacy/types.cjs.map +1 -1
- package/build/legacy/types.d.cts +5 -3
- package/build/legacy/types.d.ts +5 -3
- package/build/legacy/useSuspenseInfiniteQuery.cjs.map +1 -1
- package/build/legacy/useSuspenseInfiniteQuery.js.map +1 -1
- package/build/legacy/useSuspenseQuery.cjs.map +1 -1
- package/build/legacy/useSuspenseQuery.js.map +1 -1
- package/build/modern/QueryErrorResetBoundary.cjs.map +1 -1
- package/build/modern/QueryErrorResetBoundary.d.cts +9 -5
- package/build/modern/QueryErrorResetBoundary.d.ts +9 -5
- package/build/modern/QueryErrorResetBoundary.js.map +1 -1
- package/build/modern/index.cjs.map +1 -1
- package/build/modern/index.d.cts +3 -3
- package/build/modern/index.d.ts +3 -3
- package/build/modern/index.js.map +1 -1
- package/build/modern/infiniteQueryOptions.cjs.map +1 -1
- package/build/modern/infiniteQueryOptions.d.cts +8 -2
- package/build/modern/infiniteQueryOptions.d.ts +8 -2
- package/build/modern/infiniteQueryOptions.js.map +1 -1
- package/build/modern/queryOptions.cjs.map +1 -1
- package/build/modern/queryOptions.d.cts +8 -2
- package/build/modern/queryOptions.d.ts +8 -2
- package/build/modern/queryOptions.js.map +1 -1
- package/build/modern/types.cjs.map +1 -1
- package/build/modern/types.d.cts +5 -3
- package/build/modern/types.d.ts +5 -3
- package/build/modern/useSuspenseInfiniteQuery.cjs.map +1 -1
- package/build/modern/useSuspenseInfiniteQuery.js.map +1 -1
- package/build/modern/useSuspenseQuery.cjs.map +1 -1
- package/build/modern/useSuspenseQuery.js.map +1 -1
- package/package.json +2 -2
- package/src/QueryErrorResetBoundary.tsx +12 -9
- package/src/__tests__/infiniteQueryOptions.test-d.tsx +13 -1
- package/src/__tests__/prefetch.test.tsx +7 -3
- package/src/__tests__/queryOptions.test-d.tsx +10 -0
- package/src/__tests__/suspense.test-d.tsx +29 -11
- package/src/__tests__/useMutationState.test.tsx +13 -1
- package/src/__tests__/useQuery.test.tsx +87 -0
- package/src/__tests__/useSuspenseQueries.test-d.tsx +41 -18
- package/src/index.ts +8 -0
- package/src/infiniteQueryOptions.ts +56 -0
- package/src/queryOptions.ts +28 -0
- package/src/types.ts +22 -4
- package/src/useSuspenseInfiniteQuery.ts +1 -1
- package/src/useSuspenseQuery.ts +1 -1
|
@@ -7385,5 +7385,92 @@ describe('useQuery', () => {
|
|
|
7385
7385
|
fireEvent.click(rendered.getByText('enable'))
|
|
7386
7386
|
await waitFor(() => rendered.getByText('test1'))
|
|
7387
7387
|
})
|
|
7388
|
+
|
|
7389
|
+
it('should show correct data when read from cache only (staleTime)', async () => {
|
|
7390
|
+
const key = queryKey()
|
|
7391
|
+
let suspenseRenderCount = 0
|
|
7392
|
+
queryClient.setQueryData(key, 'initial')
|
|
7393
|
+
|
|
7394
|
+
function MyComponent(props: { promise: Promise<string> }) {
|
|
7395
|
+
const data = React.use(props.promise)
|
|
7396
|
+
|
|
7397
|
+
return <>{data}</>
|
|
7398
|
+
}
|
|
7399
|
+
|
|
7400
|
+
function Loading() {
|
|
7401
|
+
suspenseRenderCount++
|
|
7402
|
+
return <>loading..</>
|
|
7403
|
+
}
|
|
7404
|
+
function Page() {
|
|
7405
|
+
const query = useQuery({
|
|
7406
|
+
queryKey: key,
|
|
7407
|
+
queryFn: async () => {
|
|
7408
|
+
await sleep(1)
|
|
7409
|
+
return 'test'
|
|
7410
|
+
},
|
|
7411
|
+
staleTime: Infinity,
|
|
7412
|
+
})
|
|
7413
|
+
|
|
7414
|
+
return (
|
|
7415
|
+
<React.Suspense fallback={<Loading />}>
|
|
7416
|
+
<MyComponent promise={query.promise} />
|
|
7417
|
+
</React.Suspense>
|
|
7418
|
+
)
|
|
7419
|
+
}
|
|
7420
|
+
|
|
7421
|
+
const rendered = renderWithClient(queryClient, <Page />)
|
|
7422
|
+
await waitFor(() => rendered.getByText('initial'))
|
|
7423
|
+
|
|
7424
|
+
expect(suspenseRenderCount).toBe(0)
|
|
7425
|
+
})
|
|
7426
|
+
|
|
7427
|
+
it('should show correct data when switching between cache entries without re-fetches', async () => {
|
|
7428
|
+
const key = queryKey()
|
|
7429
|
+
|
|
7430
|
+
function MyComponent(props: { promise: Promise<string> }) {
|
|
7431
|
+
const data = React.use(props.promise)
|
|
7432
|
+
|
|
7433
|
+
return <>{data}</>
|
|
7434
|
+
}
|
|
7435
|
+
|
|
7436
|
+
function Loading() {
|
|
7437
|
+
return <>loading..</>
|
|
7438
|
+
}
|
|
7439
|
+
function Page() {
|
|
7440
|
+
const [count, setCount] = React.useState(0)
|
|
7441
|
+
const query = useQuery({
|
|
7442
|
+
queryKey: [key, count],
|
|
7443
|
+
queryFn: async () => {
|
|
7444
|
+
await sleep(10)
|
|
7445
|
+
return 'test' + count
|
|
7446
|
+
},
|
|
7447
|
+
staleTime: Infinity,
|
|
7448
|
+
})
|
|
7449
|
+
|
|
7450
|
+
return (
|
|
7451
|
+
<div>
|
|
7452
|
+
<React.Suspense fallback={<Loading />}>
|
|
7453
|
+
<MyComponent promise={query.promise} />
|
|
7454
|
+
</React.Suspense>
|
|
7455
|
+
<button onClick={() => setCount(count + 1)}>inc</button>
|
|
7456
|
+
<button onClick={() => setCount(count - 1)}>dec</button>
|
|
7457
|
+
</div>
|
|
7458
|
+
)
|
|
7459
|
+
}
|
|
7460
|
+
|
|
7461
|
+
const rendered = renderWithClient(queryClient, <Page />)
|
|
7462
|
+
await waitFor(() => rendered.getByText('loading..'))
|
|
7463
|
+
await waitFor(() => rendered.getByText('test0'))
|
|
7464
|
+
|
|
7465
|
+
fireEvent.click(rendered.getByText('inc'))
|
|
7466
|
+
await waitFor(() => rendered.getByText('loading..'))
|
|
7467
|
+
|
|
7468
|
+
await waitFor(() => rendered.getByText('test1'))
|
|
7469
|
+
|
|
7470
|
+
console.log('---------dec------------')
|
|
7471
|
+
fireEvent.click(rendered.getByText('dec'))
|
|
7472
|
+
|
|
7473
|
+
await waitFor(() => rendered.getByText('test0'))
|
|
7474
|
+
})
|
|
7388
7475
|
})
|
|
7389
7476
|
})
|
|
@@ -89,6 +89,47 @@ describe('UseSuspenseQueries config object overload', () => {
|
|
|
89
89
|
expectTypeOf(data).toEqualTypeOf<{ wow: boolean }>()
|
|
90
90
|
})
|
|
91
91
|
|
|
92
|
+
it('should not allow skipToken in queryFn', () => {
|
|
93
|
+
useSuspenseQueries({
|
|
94
|
+
queries: [
|
|
95
|
+
{
|
|
96
|
+
queryKey: ['key'],
|
|
97
|
+
// @ts-expect-error
|
|
98
|
+
queryFn: skipToken,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
useSuspenseQueries({
|
|
104
|
+
queries: [
|
|
105
|
+
{
|
|
106
|
+
queryKey: ['key'],
|
|
107
|
+
// @ts-expect-error
|
|
108
|
+
queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5),
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
})
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('TData should have correct type when conditional skipToken is passed', () => {
|
|
115
|
+
const queryResults = useSuspenseQueries({
|
|
116
|
+
queries: [
|
|
117
|
+
{
|
|
118
|
+
queryKey: ['withSkipToken'],
|
|
119
|
+
// @ts-expect-error
|
|
120
|
+
queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5),
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
const firstResult = queryResults[0]
|
|
126
|
+
|
|
127
|
+
expectTypeOf(firstResult).toEqualTypeOf<
|
|
128
|
+
UseSuspenseQueryResult<number, Error>
|
|
129
|
+
>()
|
|
130
|
+
expectTypeOf(firstResult.data).toEqualTypeOf<number>()
|
|
131
|
+
})
|
|
132
|
+
|
|
92
133
|
describe('custom hook', () => {
|
|
93
134
|
it('should allow custom hooks using UseQueryOptions', () => {
|
|
94
135
|
type Data = string
|
|
@@ -113,22 +154,4 @@ describe('UseSuspenseQueries config object overload', () => {
|
|
|
113
154
|
expectTypeOf(data).toEqualTypeOf<Data>()
|
|
114
155
|
})
|
|
115
156
|
})
|
|
116
|
-
|
|
117
|
-
it('TData should have correct type when conditional skipToken is passed', () => {
|
|
118
|
-
const queryResults = useSuspenseQueries({
|
|
119
|
-
queries: [
|
|
120
|
-
{
|
|
121
|
-
queryKey: ['withSkipToken'],
|
|
122
|
-
queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5),
|
|
123
|
-
},
|
|
124
|
-
],
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
const firstResult = queryResults[0]
|
|
128
|
-
|
|
129
|
-
expectTypeOf(firstResult).toEqualTypeOf<
|
|
130
|
-
UseSuspenseQueryResult<number, Error>
|
|
131
|
-
>()
|
|
132
|
-
expectTypeOf(firstResult.data).toEqualTypeOf<number>()
|
|
133
|
-
})
|
|
134
157
|
})
|
package/src/index.ts
CHANGED
|
@@ -21,11 +21,13 @@ export { queryOptions } from './queryOptions'
|
|
|
21
21
|
export type {
|
|
22
22
|
DefinedInitialDataOptions,
|
|
23
23
|
UndefinedInitialDataOptions,
|
|
24
|
+
UnusedSkipTokenOptions,
|
|
24
25
|
} from './queryOptions'
|
|
25
26
|
export { infiniteQueryOptions } from './infiniteQueryOptions'
|
|
26
27
|
export type {
|
|
27
28
|
DefinedInitialDataInfiniteOptions,
|
|
28
29
|
UndefinedInitialDataInfiniteOptions,
|
|
30
|
+
UnusedSkipTokenInfiniteOptions,
|
|
29
31
|
} from './infiniteQueryOptions'
|
|
30
32
|
export {
|
|
31
33
|
QueryClientContext,
|
|
@@ -36,6 +38,12 @@ export type { QueryClientProviderProps } from './QueryClientProvider'
|
|
|
36
38
|
export type { QueryErrorResetBoundaryProps } from './QueryErrorResetBoundary'
|
|
37
39
|
export { HydrationBoundary } from './HydrationBoundary'
|
|
38
40
|
export type { HydrationBoundaryProps } from './HydrationBoundary'
|
|
41
|
+
export type {
|
|
42
|
+
QueryErrorClearResetFunction,
|
|
43
|
+
QueryErrorIsResetFunction,
|
|
44
|
+
QueryErrorResetBoundaryFunction,
|
|
45
|
+
QueryErrorResetFunction,
|
|
46
|
+
} from './QueryErrorResetBoundary'
|
|
39
47
|
export {
|
|
40
48
|
QueryErrorResetBoundary,
|
|
41
49
|
useQueryErrorResetBoundary,
|
|
@@ -3,7 +3,9 @@ import type {
|
|
|
3
3
|
DefaultError,
|
|
4
4
|
InfiniteData,
|
|
5
5
|
InitialDataFunction,
|
|
6
|
+
OmitKeyof,
|
|
6
7
|
QueryKey,
|
|
8
|
+
SkipToken,
|
|
7
9
|
} from '@tanstack/query-core'
|
|
8
10
|
import type { UseInfiniteQueryOptions } from './types'
|
|
9
11
|
|
|
@@ -29,6 +31,36 @@ export type UndefinedInitialDataInfiniteOptions<
|
|
|
29
31
|
>
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
export type UnusedSkipTokenInfiniteOptions<
|
|
35
|
+
TQueryFnData,
|
|
36
|
+
TError = DefaultError,
|
|
37
|
+
TData = InfiniteData<TQueryFnData>,
|
|
38
|
+
TQueryKey extends QueryKey = QueryKey,
|
|
39
|
+
TPageParam = unknown,
|
|
40
|
+
> = OmitKeyof<
|
|
41
|
+
UseInfiniteQueryOptions<
|
|
42
|
+
TQueryFnData,
|
|
43
|
+
TError,
|
|
44
|
+
TData,
|
|
45
|
+
TQueryFnData,
|
|
46
|
+
TQueryKey,
|
|
47
|
+
TPageParam
|
|
48
|
+
>,
|
|
49
|
+
'queryFn'
|
|
50
|
+
> & {
|
|
51
|
+
queryFn: Exclude<
|
|
52
|
+
UseInfiniteQueryOptions<
|
|
53
|
+
TQueryFnData,
|
|
54
|
+
TError,
|
|
55
|
+
TData,
|
|
56
|
+
TQueryFnData,
|
|
57
|
+
TQueryKey,
|
|
58
|
+
TPageParam
|
|
59
|
+
>['queryFn'],
|
|
60
|
+
SkipToken
|
|
61
|
+
>
|
|
62
|
+
}
|
|
63
|
+
|
|
32
64
|
type NonUndefinedGuard<T> = T extends undefined ? never : T
|
|
33
65
|
|
|
34
66
|
export type DefinedInitialDataInfiniteOptions<
|
|
@@ -75,6 +107,30 @@ export function infiniteQueryOptions<
|
|
|
75
107
|
queryKey: DataTag<TQueryKey, InfiniteData<TQueryFnData>>
|
|
76
108
|
}
|
|
77
109
|
|
|
110
|
+
export function infiniteQueryOptions<
|
|
111
|
+
TQueryFnData,
|
|
112
|
+
TError = DefaultError,
|
|
113
|
+
TData = InfiniteData<TQueryFnData>,
|
|
114
|
+
TQueryKey extends QueryKey = QueryKey,
|
|
115
|
+
TPageParam = unknown,
|
|
116
|
+
>(
|
|
117
|
+
options: UnusedSkipTokenInfiniteOptions<
|
|
118
|
+
TQueryFnData,
|
|
119
|
+
TError,
|
|
120
|
+
TData,
|
|
121
|
+
TQueryKey,
|
|
122
|
+
TPageParam
|
|
123
|
+
>,
|
|
124
|
+
): UnusedSkipTokenInfiniteOptions<
|
|
125
|
+
TQueryFnData,
|
|
126
|
+
TError,
|
|
127
|
+
TData,
|
|
128
|
+
TQueryKey,
|
|
129
|
+
TPageParam
|
|
130
|
+
> & {
|
|
131
|
+
queryKey: DataTag<TQueryKey, InfiniteData<TQueryFnData>>
|
|
132
|
+
}
|
|
133
|
+
|
|
78
134
|
export function infiniteQueryOptions<
|
|
79
135
|
TQueryFnData,
|
|
80
136
|
TError = DefaultError,
|
package/src/queryOptions.ts
CHANGED
|
@@ -2,7 +2,9 @@ import type {
|
|
|
2
2
|
DataTag,
|
|
3
3
|
DefaultError,
|
|
4
4
|
InitialDataFunction,
|
|
5
|
+
OmitKeyof,
|
|
5
6
|
QueryKey,
|
|
7
|
+
SkipToken,
|
|
6
8
|
} from '@tanstack/query-core'
|
|
7
9
|
import type { UseQueryOptions } from './types'
|
|
8
10
|
|
|
@@ -18,6 +20,21 @@ export type UndefinedInitialDataOptions<
|
|
|
18
20
|
| NonUndefinedGuard<TQueryFnData>
|
|
19
21
|
}
|
|
20
22
|
|
|
23
|
+
export type UnusedSkipTokenOptions<
|
|
24
|
+
TQueryFnData = unknown,
|
|
25
|
+
TError = DefaultError,
|
|
26
|
+
TData = TQueryFnData,
|
|
27
|
+
TQueryKey extends QueryKey = QueryKey,
|
|
28
|
+
> = OmitKeyof<
|
|
29
|
+
UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
|
|
30
|
+
'queryFn'
|
|
31
|
+
> & {
|
|
32
|
+
queryFn: Exclude<
|
|
33
|
+
UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>['queryFn'],
|
|
34
|
+
SkipToken
|
|
35
|
+
>
|
|
36
|
+
}
|
|
37
|
+
|
|
21
38
|
type NonUndefinedGuard<T> = T extends undefined ? never : T
|
|
22
39
|
|
|
23
40
|
export type DefinedInitialDataOptions<
|
|
@@ -42,6 +59,17 @@ export function queryOptions<
|
|
|
42
59
|
queryKey: DataTag<TQueryKey, TQueryFnData>
|
|
43
60
|
}
|
|
44
61
|
|
|
62
|
+
export function queryOptions<
|
|
63
|
+
TQueryFnData = unknown,
|
|
64
|
+
TError = DefaultError,
|
|
65
|
+
TData = TQueryFnData,
|
|
66
|
+
TQueryKey extends QueryKey = QueryKey,
|
|
67
|
+
>(
|
|
68
|
+
options: UnusedSkipTokenOptions<TQueryFnData, TError, TData, TQueryKey>,
|
|
69
|
+
): UnusedSkipTokenOptions<TQueryFnData, TError, TData, TQueryKey> & {
|
|
70
|
+
queryKey: DataTag<TQueryKey, TQueryFnData>
|
|
71
|
+
}
|
|
72
|
+
|
|
45
73
|
export function queryOptions<
|
|
46
74
|
TQueryFnData = unknown,
|
|
47
75
|
TError = DefaultError,
|
package/src/types.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
QueryKey,
|
|
15
15
|
QueryObserverOptions,
|
|
16
16
|
QueryObserverResult,
|
|
17
|
+
SkipToken,
|
|
17
18
|
} from '@tanstack/query-core'
|
|
18
19
|
|
|
19
20
|
export interface UseBaseQueryOptions<
|
|
@@ -47,8 +48,13 @@ export interface UseSuspenseQueryOptions<
|
|
|
47
48
|
TQueryKey extends QueryKey = QueryKey,
|
|
48
49
|
> extends OmitKeyof<
|
|
49
50
|
UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
|
|
50
|
-
'enabled' | 'throwOnError' | 'placeholderData'
|
|
51
|
-
> {
|
|
51
|
+
'queryFn' | 'enabled' | 'throwOnError' | 'placeholderData'
|
|
52
|
+
> {
|
|
53
|
+
queryFn: Exclude<
|
|
54
|
+
UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>['queryFn'],
|
|
55
|
+
SkipToken
|
|
56
|
+
>
|
|
57
|
+
}
|
|
52
58
|
|
|
53
59
|
export interface UseInfiniteQueryOptions<
|
|
54
60
|
TQueryFnData = unknown,
|
|
@@ -85,8 +91,20 @@ export interface UseSuspenseInfiniteQueryOptions<
|
|
|
85
91
|
TQueryKey,
|
|
86
92
|
TPageParam
|
|
87
93
|
>,
|
|
88
|
-
'enabled' | 'throwOnError' | 'placeholderData'
|
|
89
|
-
> {
|
|
94
|
+
'queryFn' | 'enabled' | 'throwOnError' | 'placeholderData'
|
|
95
|
+
> {
|
|
96
|
+
queryFn: Exclude<
|
|
97
|
+
UseInfiniteQueryOptions<
|
|
98
|
+
TQueryFnData,
|
|
99
|
+
TError,
|
|
100
|
+
TData,
|
|
101
|
+
TQueryData,
|
|
102
|
+
TQueryKey,
|
|
103
|
+
TPageParam
|
|
104
|
+
>['queryFn'],
|
|
105
|
+
SkipToken
|
|
106
|
+
>
|
|
107
|
+
}
|
|
90
108
|
|
|
91
109
|
export type UseBaseQueryResult<
|
|
92
110
|
TData = unknown,
|
|
@@ -33,7 +33,7 @@ export function useSuspenseInfiniteQuery<
|
|
|
33
33
|
queryClient?: QueryClient,
|
|
34
34
|
): UseSuspenseInfiniteQueryResult<TData, TError> {
|
|
35
35
|
if (process.env.NODE_ENV !== 'production') {
|
|
36
|
-
if (options.queryFn === skipToken) {
|
|
36
|
+
if ((options.queryFn as any) === skipToken) {
|
|
37
37
|
console.error('skipToken is not allowed for useSuspenseInfiniteQuery')
|
|
38
38
|
}
|
|
39
39
|
}
|
package/src/useSuspenseQuery.ts
CHANGED
|
@@ -15,7 +15,7 @@ export function useSuspenseQuery<
|
|
|
15
15
|
queryClient?: QueryClient,
|
|
16
16
|
): UseSuspenseQueryResult<TData, TError> {
|
|
17
17
|
if (process.env.NODE_ENV !== 'production') {
|
|
18
|
-
if (options.queryFn === skipToken) {
|
|
18
|
+
if ((options.queryFn as any) === skipToken) {
|
|
19
19
|
console.error('skipToken is not allowed for useSuspenseQuery')
|
|
20
20
|
}
|
|
21
21
|
}
|