@tanstack/react-query 5.25.0 → 5.26.3
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/clover.xml +2 -2
- package/build/codemods/coverage/index.html +1 -1
- package/build/codemods/coverage/utils/index.html +1 -1
- package/build/codemods/coverage/utils/index.js.html +1 -1
- package/build/codemods/coverage/utils/transformers/index.html +1 -1
- package/build/codemods/coverage/utils/transformers/query-cache-transformer.js.html +1 -1
- package/build/codemods/coverage/utils/transformers/query-client-transformer.js.html +1 -1
- package/build/codemods/coverage/utils/transformers/use-query-like-transformer.js.html +1 -1
- package/build/codemods/coverage/v4/index.html +1 -1
- package/build/codemods/coverage/v4/key-transformation.js.html +1 -1
- package/build/codemods/coverage/v4/replace-import-specifier.js.html +1 -1
- package/build/codemods/coverage/v4/utils/replacers/index.html +1 -1
- package/build/codemods/coverage/v4/utils/replacers/key-replacer.js.html +1 -1
- package/build/codemods/coverage/v5/is-loading/index.html +1 -1
- package/build/codemods/coverage/v5/is-loading/is-loading.js.html +1 -1
- package/build/codemods/coverage/v5/keep-previous-data/index.html +1 -1
- package/build/codemods/coverage/v5/keep-previous-data/keep-previous-data.js.html +1 -1
- package/build/codemods/coverage/v5/keep-previous-data/utils/already-has-placeholder-data-property.js.html +1 -1
- package/build/codemods/coverage/v5/keep-previous-data/utils/index.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/index.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/remove-overloads.js.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/transformers/filter-aware-usage-transformer.js.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/transformers/index.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/transformers/query-fn-aware-usage-transformer.js.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/utils/index.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/utils/index.js.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/utils/unknown-usage-error.js.html +1 -1
- package/build/codemods/coverage/v5/rename-hydrate/index.html +1 -1
- package/build/codemods/coverage/v5/rename-hydrate/rename-hydrate.js.html +1 -1
- package/build/codemods/coverage/v5/rename-properties/index.html +1 -1
- package/build/codemods/coverage/v5/rename-properties/rename-properties.js.html +1 -1
- package/build/query-codemods/vite.config.ts +1 -0
- package/package.json +2 -2
- package/src/__tests__/infiniteQueryOptions.test-d.tsx +4 -10
- package/src/__tests__/useInfiniteQuery.test.tsx +34 -58
- package/src/__tests__/useMutation.test.tsx +43 -62
- package/src/__tests__/useQueries.test.tsx +99 -100
- package/src/__tests__/useQuery.test.tsx +49 -47
- package/src/__tests__/utils.tsx +3 -10
|
@@ -33,29 +33,29 @@ describe('useQuery', () => {
|
|
|
33
33
|
function Page() {
|
|
34
34
|
// unspecified query function should default to unknown
|
|
35
35
|
const noQueryFn = useQuery({ queryKey: key })
|
|
36
|
-
expectTypeOf
|
|
37
|
-
expectTypeOf
|
|
36
|
+
expectTypeOf(noQueryFn.data).toEqualTypeOf<unknown>()
|
|
37
|
+
expectTypeOf(noQueryFn.error).toEqualTypeOf<Error | null>()
|
|
38
38
|
|
|
39
39
|
// it should infer the result type from the query function
|
|
40
40
|
const fromQueryFn = useQuery({ queryKey: key, queryFn: () => 'test' })
|
|
41
|
-
expectTypeOf<string | undefined>(
|
|
42
|
-
expectTypeOf
|
|
41
|
+
expectTypeOf(fromQueryFn.data).toEqualTypeOf<string | undefined>()
|
|
42
|
+
expectTypeOf(fromQueryFn.error).toEqualTypeOf<Error | null>()
|
|
43
43
|
|
|
44
44
|
// it should be possible to specify the result type
|
|
45
45
|
const withResult = useQuery<string>({
|
|
46
46
|
queryKey: key,
|
|
47
47
|
queryFn: () => 'test',
|
|
48
48
|
})
|
|
49
|
-
expectTypeOf<string | undefined>(
|
|
50
|
-
expectTypeOf<
|
|
49
|
+
expectTypeOf(withResult.data).toEqualTypeOf<string | undefined>()
|
|
50
|
+
expectTypeOf(withResult.error).toEqualTypeOf<Error | null>()
|
|
51
51
|
|
|
52
52
|
// it should be possible to specify the error type
|
|
53
53
|
const withError = useQuery<string, Error>({
|
|
54
54
|
queryKey: key,
|
|
55
55
|
queryFn: () => 'test',
|
|
56
56
|
})
|
|
57
|
-
expectTypeOf<string | undefined>(
|
|
58
|
-
expectTypeOf<Error | null>(
|
|
57
|
+
expectTypeOf(withError.data).toEqualTypeOf<string | undefined>()
|
|
58
|
+
expectTypeOf(withError.error).toEqualTypeOf<Error | null>()
|
|
59
59
|
|
|
60
60
|
// it should provide the result type in the configuration
|
|
61
61
|
useQuery({
|
|
@@ -66,14 +66,14 @@ describe('useQuery', () => {
|
|
|
66
66
|
// it should be possible to specify a union type as result type
|
|
67
67
|
const unionTypeSync = useQuery({
|
|
68
68
|
queryKey: key,
|
|
69
|
-
queryFn: () => (Math.random() > 0.5 ? 'a' : 'b'),
|
|
69
|
+
queryFn: () => (Math.random() > 0.5 ? ('a' as const) : ('b' as const)),
|
|
70
70
|
})
|
|
71
|
-
expectTypeOf<'a' | 'b' | undefined>(
|
|
71
|
+
expectTypeOf(unionTypeSync.data).toEqualTypeOf<'a' | 'b' | undefined>()
|
|
72
72
|
const unionTypeAsync = useQuery<'a' | 'b'>({
|
|
73
73
|
queryKey: key,
|
|
74
74
|
queryFn: () => Promise.resolve(Math.random() > 0.5 ? 'a' : 'b'),
|
|
75
75
|
})
|
|
76
|
-
expectTypeOf<'a' | 'b' | undefined>(
|
|
76
|
+
expectTypeOf(unionTypeAsync.data).toEqualTypeOf<'a' | 'b' | undefined>()
|
|
77
77
|
|
|
78
78
|
// should error when the query function result does not match with the specified type
|
|
79
79
|
// @ts-expect-error
|
|
@@ -88,15 +88,19 @@ describe('useQuery', () => {
|
|
|
88
88
|
queryKey: key,
|
|
89
89
|
queryFn: () => queryFn(),
|
|
90
90
|
})
|
|
91
|
-
expectTypeOf<string | undefined>(
|
|
92
|
-
expectTypeOf
|
|
91
|
+
expectTypeOf(fromGenericQueryFn.data).toEqualTypeOf<string | undefined>()
|
|
92
|
+
expectTypeOf(fromGenericQueryFn.error).toEqualTypeOf<Error | null>()
|
|
93
93
|
|
|
94
94
|
const fromGenericOptionsQueryFn = useQuery({
|
|
95
95
|
queryKey: key,
|
|
96
96
|
queryFn: () => queryFn(),
|
|
97
97
|
})
|
|
98
|
-
expectTypeOf
|
|
99
|
-
|
|
98
|
+
expectTypeOf(fromGenericOptionsQueryFn.data).toEqualTypeOf<
|
|
99
|
+
string | undefined
|
|
100
|
+
>()
|
|
101
|
+
expectTypeOf(
|
|
102
|
+
fromGenericOptionsQueryFn.error,
|
|
103
|
+
).toEqualTypeOf<Error | null>()
|
|
100
104
|
|
|
101
105
|
type MyData = number
|
|
102
106
|
type MyQueryKey = readonly ['my-data', number]
|
|
@@ -115,7 +119,7 @@ describe('useQuery', () => {
|
|
|
115
119
|
const getMyDataStringKey: QueryFunction<MyData, ['1']> = async (
|
|
116
120
|
context,
|
|
117
121
|
) => {
|
|
118
|
-
expectTypeOf<['1']>(
|
|
122
|
+
expectTypeOf(context.queryKey).toEqualTypeOf<['1']>()
|
|
119
123
|
return Number(context.queryKey[0]) + 42
|
|
120
124
|
}
|
|
121
125
|
|
|
@@ -154,7 +158,7 @@ describe('useQuery', () => {
|
|
|
154
158
|
...options,
|
|
155
159
|
})
|
|
156
160
|
const testQuery = useWrappedQuery([''], async () => '1')
|
|
157
|
-
expectTypeOf<string | undefined>(
|
|
161
|
+
expectTypeOf(testQuery.data).toEqualTypeOf<string | undefined>()
|
|
158
162
|
|
|
159
163
|
// handles wrapped queries with custom fetcher passed directly to useQuery
|
|
160
164
|
const useWrappedFuncStyleQuery = <
|
|
@@ -171,7 +175,7 @@ describe('useQuery', () => {
|
|
|
171
175
|
>,
|
|
172
176
|
) => useQuery({ queryKey: qk, queryFn: fetcher, ...options })
|
|
173
177
|
const testFuncStyle = useWrappedFuncStyleQuery([''], async () => true)
|
|
174
|
-
expectTypeOf<boolean | undefined>(
|
|
178
|
+
expectTypeOf(testFuncStyle.data).toEqualTypeOf<boolean | undefined>()
|
|
175
179
|
}
|
|
176
180
|
})
|
|
177
181
|
|
|
@@ -218,19 +222,19 @@ describe('useQuery', () => {
|
|
|
218
222
|
states.push(state)
|
|
219
223
|
|
|
220
224
|
if (state.isPending) {
|
|
221
|
-
expectTypeOf
|
|
222
|
-
expectTypeOf
|
|
225
|
+
expectTypeOf(state.data).toEqualTypeOf<undefined>()
|
|
226
|
+
expectTypeOf(state.error).toEqualTypeOf<null>()
|
|
223
227
|
return <span>pending</span>
|
|
224
228
|
}
|
|
225
229
|
|
|
226
230
|
if (state.isLoadingError) {
|
|
227
|
-
expectTypeOf
|
|
228
|
-
expectTypeOf
|
|
231
|
+
expectTypeOf(state.data).toEqualTypeOf<undefined>()
|
|
232
|
+
expectTypeOf(state.error).toEqualTypeOf<Error>()
|
|
229
233
|
return <span>{state.error.message}</span>
|
|
230
234
|
}
|
|
231
235
|
|
|
232
|
-
expectTypeOf
|
|
233
|
-
expectTypeOf<Error | null>(
|
|
236
|
+
expectTypeOf(state.data).toEqualTypeOf<string>()
|
|
237
|
+
expectTypeOf(state.error).toEqualTypeOf<Error | null>()
|
|
234
238
|
return <span>{state.data}</span>
|
|
235
239
|
}
|
|
236
240
|
|
|
@@ -5212,12 +5216,11 @@ describe('useQuery', () => {
|
|
|
5212
5216
|
}
|
|
5213
5217
|
|
|
5214
5218
|
const rendered = renderWithClient(queryClient, <Page />)
|
|
5215
|
-
window.dispatchEvent(new Event('offline'))
|
|
5216
5219
|
|
|
5217
5220
|
await waitFor(() => rendered.getByText('status: pending, isPaused: true'))
|
|
5218
5221
|
|
|
5219
|
-
onlineMock.
|
|
5220
|
-
|
|
5222
|
+
onlineMock.mockReturnValue(true)
|
|
5223
|
+
queryClient.getQueryCache().onOnline()
|
|
5221
5224
|
|
|
5222
5225
|
await waitFor(() =>
|
|
5223
5226
|
rendered.getByText('status: success, isPaused: false'),
|
|
@@ -5227,6 +5230,7 @@ describe('useQuery', () => {
|
|
|
5227
5230
|
})
|
|
5228
5231
|
|
|
5229
5232
|
expect(states).toEqual(['paused', 'fetching', 'idle'])
|
|
5233
|
+
onlineMock.mockRestore()
|
|
5230
5234
|
})
|
|
5231
5235
|
|
|
5232
5236
|
it('online queries should not refetch if you are offline', async () => {
|
|
@@ -5265,7 +5269,6 @@ describe('useQuery', () => {
|
|
|
5265
5269
|
await waitFor(() => rendered.getByText('data: data1'))
|
|
5266
5270
|
|
|
5267
5271
|
const onlineMock = mockOnlineManagerIsOnline(false)
|
|
5268
|
-
window.dispatchEvent(new Event('offline'))
|
|
5269
5272
|
|
|
5270
5273
|
fireEvent.click(rendered.getByRole('button', { name: /invalidate/i }))
|
|
5271
5274
|
|
|
@@ -5276,8 +5279,8 @@ describe('useQuery', () => {
|
|
|
5276
5279
|
)
|
|
5277
5280
|
await waitFor(() => rendered.getByText('failureReason: null'))
|
|
5278
5281
|
|
|
5279
|
-
onlineMock.
|
|
5280
|
-
|
|
5282
|
+
onlineMock.mockReturnValue(true)
|
|
5283
|
+
queryClient.getQueryCache().onOnline()
|
|
5281
5284
|
|
|
5282
5285
|
await waitFor(() =>
|
|
5283
5286
|
rendered.getByText(
|
|
@@ -5295,6 +5298,8 @@ describe('useQuery', () => {
|
|
|
5295
5298
|
await waitFor(() => {
|
|
5296
5299
|
expect(rendered.getByText('data: data2')).toBeInTheDocument()
|
|
5297
5300
|
})
|
|
5301
|
+
|
|
5302
|
+
onlineMock.mockRestore()
|
|
5298
5303
|
})
|
|
5299
5304
|
|
|
5300
5305
|
it('online queries should not refetch if you are offline and refocus', async () => {
|
|
@@ -5484,7 +5489,6 @@ describe('useQuery', () => {
|
|
|
5484
5489
|
const onlineMock = mockOnlineManagerIsOnline(false)
|
|
5485
5490
|
|
|
5486
5491
|
const rendered = renderWithClient(queryClient, <Page />)
|
|
5487
|
-
window.dispatchEvent(new Event('offline'))
|
|
5488
5492
|
|
|
5489
5493
|
await waitFor(() =>
|
|
5490
5494
|
rendered.getByText('status: success, fetchStatus: paused'),
|
|
@@ -5507,10 +5511,8 @@ describe('useQuery', () => {
|
|
|
5507
5511
|
window.dispatchEvent(new Event('visibilitychange'))
|
|
5508
5512
|
})
|
|
5509
5513
|
|
|
5510
|
-
onlineMock.
|
|
5511
|
-
|
|
5512
|
-
window.dispatchEvent(new Event('online'))
|
|
5513
|
-
})
|
|
5514
|
+
onlineMock.mockReturnValue(true)
|
|
5515
|
+
queryClient.getQueryCache().onOnline()
|
|
5514
5516
|
|
|
5515
5517
|
await waitFor(() =>
|
|
5516
5518
|
rendered.getByText('status: success, fetchStatus: idle'),
|
|
@@ -5520,6 +5522,8 @@ describe('useQuery', () => {
|
|
|
5520
5522
|
})
|
|
5521
5523
|
|
|
5522
5524
|
expect(count).toBe(1)
|
|
5525
|
+
|
|
5526
|
+
onlineMock.mockRestore()
|
|
5523
5527
|
})
|
|
5524
5528
|
|
|
5525
5529
|
it('online queries should pause retries if you are offline', async () => {
|
|
@@ -5556,7 +5560,6 @@ describe('useQuery', () => {
|
|
|
5556
5560
|
)
|
|
5557
5561
|
|
|
5558
5562
|
const onlineMock = mockOnlineManagerIsOnline(false)
|
|
5559
|
-
window.dispatchEvent(new Event('offline'))
|
|
5560
5563
|
|
|
5561
5564
|
await sleep(20)
|
|
5562
5565
|
|
|
@@ -5570,7 +5573,7 @@ describe('useQuery', () => {
|
|
|
5570
5573
|
expect(count).toBe(1)
|
|
5571
5574
|
|
|
5572
5575
|
onlineMock.mockReturnValue(true)
|
|
5573
|
-
|
|
5576
|
+
queryClient.getQueryCache().onOnline()
|
|
5574
5577
|
|
|
5575
5578
|
await waitFor(() =>
|
|
5576
5579
|
rendered.getByText('status: error, fetchStatus: idle, failureCount: 3'),
|
|
@@ -5621,16 +5624,14 @@ describe('useQuery', () => {
|
|
|
5621
5624
|
|
|
5622
5625
|
const rendered = renderWithClient(queryClient, <Page />)
|
|
5623
5626
|
|
|
5624
|
-
window.dispatchEvent(new Event('offline'))
|
|
5625
|
-
|
|
5626
5627
|
await waitFor(() =>
|
|
5627
5628
|
rendered.getByText('status: pending, fetchStatus: paused'),
|
|
5628
5629
|
)
|
|
5629
5630
|
|
|
5630
5631
|
fireEvent.click(rendered.getByRole('button', { name: /hide/i }))
|
|
5631
5632
|
|
|
5632
|
-
onlineMock.
|
|
5633
|
-
|
|
5633
|
+
onlineMock.mockReturnValue(true)
|
|
5634
|
+
queryClient.getQueryCache().onOnline()
|
|
5634
5635
|
|
|
5635
5636
|
await waitFor(() => {
|
|
5636
5637
|
expect(queryClient.getQueryState(key)).toMatchObject({
|
|
@@ -5642,6 +5643,8 @@ describe('useQuery', () => {
|
|
|
5642
5643
|
// give it a bit more time to make sure queryFn is not called again
|
|
5643
5644
|
await sleep(15)
|
|
5644
5645
|
expect(count).toBe(1)
|
|
5646
|
+
|
|
5647
|
+
onlineMock.mockRestore()
|
|
5645
5648
|
})
|
|
5646
5649
|
|
|
5647
5650
|
it('online queries should not fetch if paused and we go online when cancelled and no refetchOnReconnect', async () => {
|
|
@@ -5691,7 +5694,7 @@ describe('useQuery', () => {
|
|
|
5691
5694
|
expect(count).toBe(0)
|
|
5692
5695
|
|
|
5693
5696
|
onlineMock.mockReturnValue(true)
|
|
5694
|
-
|
|
5697
|
+
queryClient.getQueryCache().onOnline()
|
|
5695
5698
|
|
|
5696
5699
|
await sleep(15)
|
|
5697
5700
|
|
|
@@ -5763,7 +5766,7 @@ describe('useQuery', () => {
|
|
|
5763
5766
|
await sleep(15)
|
|
5764
5767
|
|
|
5765
5768
|
onlineMock.mockReturnValue(true)
|
|
5766
|
-
|
|
5769
|
+
queryClient.getQueryCache().onOnline()
|
|
5767
5770
|
|
|
5768
5771
|
await sleep(15)
|
|
5769
5772
|
|
|
@@ -5897,8 +5900,6 @@ describe('useQuery', () => {
|
|
|
5897
5900
|
|
|
5898
5901
|
const rendered = renderWithClient(queryClient, <Page />)
|
|
5899
5902
|
|
|
5900
|
-
window.dispatchEvent(new Event('offline'))
|
|
5901
|
-
|
|
5902
5903
|
await waitFor(() =>
|
|
5903
5904
|
rendered.getByText(
|
|
5904
5905
|
'status: pending, fetchStatus: paused, failureCount: 1',
|
|
@@ -5908,8 +5909,8 @@ describe('useQuery', () => {
|
|
|
5908
5909
|
|
|
5909
5910
|
expect(count).toBe(1)
|
|
5910
5911
|
|
|
5911
|
-
onlineMock.
|
|
5912
|
-
|
|
5912
|
+
onlineMock.mockReturnValue(true)
|
|
5913
|
+
queryClient.getQueryCache().onOnline()
|
|
5913
5914
|
|
|
5914
5915
|
await waitFor(() =>
|
|
5915
5916
|
rendered.getByText('status: error, fetchStatus: idle, failureCount: 3'),
|
|
@@ -5917,6 +5918,7 @@ describe('useQuery', () => {
|
|
|
5917
5918
|
await waitFor(() => rendered.getByText('failureReason: failed3'))
|
|
5918
5919
|
|
|
5919
5920
|
expect(count).toBe(3)
|
|
5921
|
+
onlineMock.mockRestore()
|
|
5920
5922
|
})
|
|
5921
5923
|
})
|
|
5922
5924
|
|
package/src/__tests__/utils.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import { act, render } from '@testing-library/react'
|
|
|
4
4
|
import * as utils from '@tanstack/query-core'
|
|
5
5
|
import { QueryClient, QueryClientProvider, onlineManager } from '..'
|
|
6
6
|
import type { QueryClientConfig } from '..'
|
|
7
|
-
import type {
|
|
7
|
+
import type { MockInstance } from 'vitest'
|
|
8
8
|
|
|
9
9
|
export function renderWithClient(
|
|
10
10
|
client: QueryClient,
|
|
@@ -48,13 +48,13 @@ export function createQueryClient(config?: QueryClientConfig): QueryClient {
|
|
|
48
48
|
|
|
49
49
|
export function mockVisibilityState(
|
|
50
50
|
value: DocumentVisibilityState,
|
|
51
|
-
):
|
|
51
|
+
): MockInstance<[], DocumentVisibilityState> {
|
|
52
52
|
return vi.spyOn(document, 'visibilityState', 'get').mockReturnValue(value)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export function mockOnlineManagerIsOnline(
|
|
56
56
|
value: boolean,
|
|
57
|
-
):
|
|
57
|
+
): MockInstance<[], boolean> {
|
|
58
58
|
return vi.spyOn(onlineManager, 'isOnline').mockReturnValue(value)
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -78,13 +78,6 @@ export function setActTimeout(fn: () => void, ms?: number) {
|
|
|
78
78
|
}, ms)
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
/**
|
|
82
|
-
* Assert the parameter is not typed as `any`
|
|
83
|
-
*/
|
|
84
|
-
export function expectTypeNotAny<T>(_: 0 extends 1 & T ? never : T): void {
|
|
85
|
-
return undefined
|
|
86
|
-
}
|
|
87
|
-
|
|
88
81
|
// This monkey-patches the isServer-value from utils,
|
|
89
82
|
// so that we can pretend to be in a server environment
|
|
90
83
|
export function setIsServer(isServer: boolean) {
|