@tanstack/react-query 5.25.0 → 5.27.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.
Files changed (39) hide show
  1. package/build/codemods/coverage/clover.xml +2 -2
  2. package/build/codemods/coverage/index.html +1 -1
  3. package/build/codemods/coverage/utils/index.html +1 -1
  4. package/build/codemods/coverage/utils/index.js.html +1 -1
  5. package/build/codemods/coverage/utils/transformers/index.html +1 -1
  6. package/build/codemods/coverage/utils/transformers/query-cache-transformer.js.html +1 -1
  7. package/build/codemods/coverage/utils/transformers/query-client-transformer.js.html +1 -1
  8. package/build/codemods/coverage/utils/transformers/use-query-like-transformer.js.html +1 -1
  9. package/build/codemods/coverage/v4/index.html +1 -1
  10. package/build/codemods/coverage/v4/key-transformation.js.html +1 -1
  11. package/build/codemods/coverage/v4/replace-import-specifier.js.html +1 -1
  12. package/build/codemods/coverage/v4/utils/replacers/index.html +1 -1
  13. package/build/codemods/coverage/v4/utils/replacers/key-replacer.js.html +1 -1
  14. package/build/codemods/coverage/v5/is-loading/index.html +1 -1
  15. package/build/codemods/coverage/v5/is-loading/is-loading.js.html +1 -1
  16. package/build/codemods/coverage/v5/keep-previous-data/index.html +1 -1
  17. package/build/codemods/coverage/v5/keep-previous-data/keep-previous-data.js.html +1 -1
  18. package/build/codemods/coverage/v5/keep-previous-data/utils/already-has-placeholder-data-property.js.html +1 -1
  19. package/build/codemods/coverage/v5/keep-previous-data/utils/index.html +1 -1
  20. package/build/codemods/coverage/v5/remove-overloads/index.html +1 -1
  21. package/build/codemods/coverage/v5/remove-overloads/remove-overloads.js.html +1 -1
  22. package/build/codemods/coverage/v5/remove-overloads/transformers/filter-aware-usage-transformer.js.html +1 -1
  23. package/build/codemods/coverage/v5/remove-overloads/transformers/index.html +1 -1
  24. package/build/codemods/coverage/v5/remove-overloads/transformers/query-fn-aware-usage-transformer.js.html +1 -1
  25. package/build/codemods/coverage/v5/remove-overloads/utils/index.html +1 -1
  26. package/build/codemods/coverage/v5/remove-overloads/utils/index.js.html +1 -1
  27. package/build/codemods/coverage/v5/remove-overloads/utils/unknown-usage-error.js.html +1 -1
  28. package/build/codemods/coverage/v5/rename-hydrate/index.html +1 -1
  29. package/build/codemods/coverage/v5/rename-hydrate/rename-hydrate.js.html +1 -1
  30. package/build/codemods/coverage/v5/rename-properties/index.html +1 -1
  31. package/build/codemods/coverage/v5/rename-properties/rename-properties.js.html +1 -1
  32. package/build/query-codemods/vite.config.ts +1 -0
  33. package/package.json +2 -2
  34. package/src/__tests__/infiniteQueryOptions.test-d.tsx +4 -10
  35. package/src/__tests__/useInfiniteQuery.test.tsx +34 -58
  36. package/src/__tests__/useMutation.test.tsx +43 -62
  37. package/src/__tests__/useQueries.test.tsx +99 -100
  38. package/src/__tests__/useQuery.test.tsx +49 -47
  39. 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<unknown>(noQueryFn.data)
37
- expectTypeOf<unknown>(noQueryFn.error)
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>(fromQueryFn.data)
42
- expectTypeOf<unknown>(fromQueryFn.error)
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>(withResult.data)
50
- expectTypeOf<unknown | null>(withResult.error)
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>(withError.data)
58
- expectTypeOf<Error | null>(withError.error)
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>(unionTypeSync.data)
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>(unionTypeAsync.data)
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>(fromGenericQueryFn.data)
92
- expectTypeOf<unknown>(fromGenericQueryFn.error)
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<string | undefined>(fromGenericOptionsQueryFn.data)
99
- expectTypeOf<unknown>(fromGenericOptionsQueryFn.error)
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']>(context.queryKey)
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>(testQuery.data)
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>(testFuncStyle.data)
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<undefined>(state.data)
222
- expectTypeOf<null>(state.error)
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<undefined>(state.data)
228
- expectTypeOf<Error>(state.error)
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<string>(state.data)
233
- expectTypeOf<Error | null>(state.error)
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.mockRestore()
5220
- window.dispatchEvent(new Event('online'))
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.mockRestore()
5280
- window.dispatchEvent(new Event('online'))
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.mockRestore()
5511
- act(() => {
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
- window.dispatchEvent(new Event('online'))
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.mockRestore()
5633
- window.dispatchEvent(new Event('online'))
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
- window.dispatchEvent(new Event('online'))
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
- window.dispatchEvent(new Event('online'))
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.mockRestore()
5912
- window.dispatchEvent(new Event('online'))
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
 
@@ -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 { SpyInstance } from 'vitest'
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
- ): SpyInstance<[], DocumentVisibilityState> {
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
- ): SpyInstance<[], boolean> {
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) {