@tanstack/react-query 5.0.0-alpha.2 → 5.0.0-alpha.21

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 (110) hide show
  1. package/build/lib/HydrationBoundary.esm.js +1 -0
  2. package/build/lib/HydrationBoundary.esm.js.map +1 -1
  3. package/build/lib/HydrationBoundary.js +1 -0
  4. package/build/lib/HydrationBoundary.js.map +1 -1
  5. package/build/lib/HydrationBoundary.mjs +1 -0
  6. package/build/lib/HydrationBoundary.mjs.map +1 -1
  7. package/build/lib/QueryClientProvider.esm.js +1 -0
  8. package/build/lib/QueryClientProvider.esm.js.map +1 -1
  9. package/build/lib/QueryClientProvider.js +1 -0
  10. package/build/lib/QueryClientProvider.js.map +1 -1
  11. package/build/lib/QueryClientProvider.mjs +1 -0
  12. package/build/lib/QueryClientProvider.mjs.map +1 -1
  13. package/build/lib/QueryErrorResetBoundary.esm.js +1 -0
  14. package/build/lib/QueryErrorResetBoundary.esm.js.map +1 -1
  15. package/build/lib/QueryErrorResetBoundary.js +1 -0
  16. package/build/lib/QueryErrorResetBoundary.js.map +1 -1
  17. package/build/lib/QueryErrorResetBoundary.mjs +1 -0
  18. package/build/lib/QueryErrorResetBoundary.mjs.map +1 -1
  19. package/build/lib/__tests__/ssr.test.d.ts +0 -3
  20. package/build/lib/__tests__/utils.d.ts +2 -3
  21. package/build/lib/errorBoundaryUtils.esm.js +1 -0
  22. package/build/lib/errorBoundaryUtils.esm.js.map +1 -1
  23. package/build/lib/errorBoundaryUtils.js +1 -0
  24. package/build/lib/errorBoundaryUtils.js.map +1 -1
  25. package/build/lib/errorBoundaryUtils.mjs +1 -0
  26. package/build/lib/errorBoundaryUtils.mjs.map +1 -1
  27. package/build/lib/isRestoring.esm.js +1 -0
  28. package/build/lib/isRestoring.esm.js.map +1 -1
  29. package/build/lib/isRestoring.js +1 -0
  30. package/build/lib/isRestoring.js.map +1 -1
  31. package/build/lib/isRestoring.mjs +1 -0
  32. package/build/lib/isRestoring.mjs.map +1 -1
  33. package/build/lib/suspense.d.ts +1 -1
  34. package/build/lib/suspense.esm.js +2 -9
  35. package/build/lib/suspense.esm.js.map +1 -1
  36. package/build/lib/suspense.js +2 -9
  37. package/build/lib/suspense.js.map +1 -1
  38. package/build/lib/suspense.mjs +1 -8
  39. package/build/lib/suspense.mjs.map +1 -1
  40. package/build/lib/useBaseQuery.esm.js +1 -11
  41. package/build/lib/useBaseQuery.esm.js.map +1 -1
  42. package/build/lib/useBaseQuery.js +1 -11
  43. package/build/lib/useBaseQuery.js.map +1 -1
  44. package/build/lib/useBaseQuery.mjs +1 -11
  45. package/build/lib/useBaseQuery.mjs.map +1 -1
  46. package/build/lib/useInfiniteQuery.esm.js +1 -0
  47. package/build/lib/useInfiniteQuery.esm.js.map +1 -1
  48. package/build/lib/useInfiniteQuery.js +1 -0
  49. package/build/lib/useInfiniteQuery.js.map +1 -1
  50. package/build/lib/useInfiniteQuery.mjs +1 -0
  51. package/build/lib/useInfiniteQuery.mjs.map +1 -1
  52. package/build/lib/useIsFetching.esm.js +1 -0
  53. package/build/lib/useIsFetching.esm.js.map +1 -1
  54. package/build/lib/useIsFetching.js +1 -0
  55. package/build/lib/useIsFetching.js.map +1 -1
  56. package/build/lib/useIsFetching.mjs +1 -0
  57. package/build/lib/useIsFetching.mjs.map +1 -1
  58. package/build/lib/useMutation.esm.js +1 -0
  59. package/build/lib/useMutation.esm.js.map +1 -1
  60. package/build/lib/useMutation.js +1 -0
  61. package/build/lib/useMutation.js.map +1 -1
  62. package/build/lib/useMutation.mjs +1 -0
  63. package/build/lib/useMutation.mjs.map +1 -1
  64. package/build/lib/useMutationState.d.ts +3 -3
  65. package/build/lib/useMutationState.esm.js +1 -0
  66. package/build/lib/useMutationState.esm.js.map +1 -1
  67. package/build/lib/useMutationState.js +1 -0
  68. package/build/lib/useMutationState.js.map +1 -1
  69. package/build/lib/useMutationState.mjs +1 -0
  70. package/build/lib/useMutationState.mjs.map +1 -1
  71. package/build/lib/useQueries.d.ts +2 -3
  72. package/build/lib/useQueries.esm.js +20 -16
  73. package/build/lib/useQueries.esm.js.map +1 -1
  74. package/build/lib/useQueries.js +20 -16
  75. package/build/lib/useQueries.js.map +1 -1
  76. package/build/lib/useQueries.mjs +11 -10
  77. package/build/lib/useQueries.mjs.map +1 -1
  78. package/build/lib/useQuery.esm.js +1 -0
  79. package/build/lib/useQuery.esm.js.map +1 -1
  80. package/build/lib/useQuery.js +1 -0
  81. package/build/lib/useQuery.js.map +1 -1
  82. package/build/lib/useQuery.mjs +1 -0
  83. package/build/lib/useQuery.mjs.map +1 -1
  84. package/build/umd/index.development.js +108 -138
  85. package/build/umd/index.development.js.map +1 -1
  86. package/build/umd/index.production.js +1 -1
  87. package/build/umd/index.production.js.map +1 -1
  88. package/package.json +3 -3
  89. package/src/__tests__/HydrationBoundary.test.tsx +4 -3
  90. package/src/__tests__/QueryClientProvider.test.tsx +2 -1
  91. package/src/__tests__/QueryResetErrorBoundary.test.tsx +753 -620
  92. package/src/__tests__/ssr-hydration.test.tsx +11 -10
  93. package/src/__tests__/ssr.test.tsx +4 -7
  94. package/src/__tests__/suspense.test.tsx +11 -92
  95. package/src/__tests__/useInfiniteQuery.test.tsx +18 -16
  96. package/src/__tests__/useInfiniteQuery.type.test.tsx +94 -13
  97. package/src/__tests__/useMutation.test.tsx +21 -20
  98. package/src/__tests__/useMutationState.test.tsx +24 -58
  99. package/src/__tests__/useQueries.test.tsx +25 -154
  100. package/src/__tests__/useQuery.test.tsx +174 -359
  101. package/src/__tests__/utils.tsx +3 -2
  102. package/src/errorBoundaryUtils.ts +1 -0
  103. package/src/suspense.ts +3 -11
  104. package/src/useBaseQuery.ts +1 -19
  105. package/src/useInfiniteQuery.ts +1 -0
  106. package/src/useIsFetching.ts +1 -0
  107. package/src/useMutation.ts +1 -0
  108. package/src/useMutationState.ts +4 -3
  109. package/src/useQueries.ts +19 -18
  110. package/src/useQuery.ts +1 -0
@@ -4,12 +4,12 @@ import { useIsMutating, useMutationState } from '../useMutationState'
4
4
  import { useMutation } from '../useMutation'
5
5
  import {
6
6
  createQueryClient,
7
+ doNotExecute,
7
8
  renderWithClient,
8
9
  setActTimeout,
9
10
  sleep,
10
11
  } from './utils'
11
- import * as MutationCacheModule from '../../../query-core/src/mutationCache'
12
- import { screen } from 'solid-testing-library'
12
+ import type { MutationState, MutationStatus } from '@tanstack/query-core'
13
13
 
14
14
  describe('useIsMutating', () => {
15
15
  it('should return the number of fetching mutations', async () => {
@@ -140,61 +140,6 @@ describe('useIsMutating', () => {
140
140
  await waitFor(() => expect(isMutatings).toEqual([0, 1, 0]))
141
141
  })
142
142
 
143
- it('should not change state if unmounted', async () => {
144
- // We have to mock the MutationCache to not unsubscribe
145
- // the listener when the component is unmounted
146
- class MutationCacheMock extends MutationCacheModule.MutationCache {
147
- subscribe(listener: any) {
148
- super.subscribe(listener)
149
- return () => void 0
150
- }
151
- }
152
-
153
- const MutationCacheSpy = jest
154
- .spyOn(MutationCacheModule, 'MutationCache')
155
- .mockImplementation((fn) => {
156
- return new MutationCacheMock(fn)
157
- })
158
-
159
- const queryClient = createQueryClient()
160
-
161
- function IsMutating() {
162
- useIsMutating()
163
- return null
164
- }
165
-
166
- function Page() {
167
- const [mounted, setMounted] = React.useState(true)
168
- const { mutate: mutate1 } = useMutation({
169
- mutationKey: ['mutation1'],
170
- mutationFn: async () => {
171
- await sleep(10)
172
- return 'data'
173
- },
174
- })
175
-
176
- React.useEffect(() => {
177
- mutate1()
178
- }, [mutate1])
179
-
180
- return (
181
- <div>
182
- <button onClick={() => setMounted(false)}>unmount</button>
183
- {mounted && <IsMutating />}
184
- </div>
185
- )
186
- }
187
-
188
- const { getByText } = renderWithClient(queryClient, <Page />)
189
- fireEvent.click(getByText('unmount'))
190
-
191
- // Should not display the console error
192
- // "Warning: Can't perform a React state update on an unmounted component"
193
-
194
- await sleep(20)
195
- MutationCacheSpy.mockRestore()
196
- })
197
-
198
143
  it('should use provided custom queryClient', async () => {
199
144
  const queryClient = createQueryClient()
200
145
 
@@ -229,6 +174,27 @@ describe('useIsMutating', () => {
229
174
  })
230
175
 
231
176
  describe('useMutationState', () => {
177
+ describe('types', () => {
178
+ it('should default to QueryState', () => {
179
+ doNotExecute(() => {
180
+ const result = useMutationState({
181
+ filters: { status: 'pending' },
182
+ })
183
+
184
+ expectTypeOf(result).toEqualTypeOf<Array<MutationState>>()
185
+ })
186
+ })
187
+ it('should infer with select', () => {
188
+ doNotExecute(() => {
189
+ const result = useMutationState({
190
+ filters: { status: 'pending' },
191
+ select: (mutation) => mutation.state.status,
192
+ })
193
+
194
+ expectTypeOf(result).toEqualTypeOf<Array<MutationStatus>>()
195
+ })
196
+ })
197
+ })
232
198
  it('should return variables after calling mutate', async () => {
233
199
  const queryClient = createQueryClient()
234
200
  const variables: unknown[][] = []
@@ -275,7 +241,7 @@ describe('useMutationState', () => {
275
241
 
276
242
  await waitFor(() => rendered.getByText('data: null'))
277
243
 
278
- fireEvent.click(screen.getByRole('button', { name: /mutate/i }))
244
+ fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
279
245
 
280
246
  await waitFor(() => rendered.getByText('data: data1'))
281
247
 
@@ -1,9 +1,17 @@
1
- import { fireEvent, render, waitFor } from '@testing-library/react'
1
+ import { render, waitFor } from '@testing-library/react'
2
2
  import * as React from 'react'
3
3
  import { ErrorBoundary } from 'react-error-boundary'
4
4
 
5
- import * as QueriesObserverModule from '../../../query-core/src/queriesObserver'
6
-
5
+ import type { QueryFunctionContext } from '@tanstack/query-core'
6
+ import { vi } from 'vitest'
7
+ import type {
8
+ QueryFunction,
9
+ QueryKey,
10
+ QueryObserverResult,
11
+ UseQueryOptions,
12
+ UseQueryResult,
13
+ } from '..'
14
+ import { QueryCache, useQueries } from '..'
7
15
  import {
8
16
  createQueryClient,
9
17
  expectType,
@@ -12,15 +20,6 @@ import {
12
20
  renderWithClient,
13
21
  sleep,
14
22
  } from './utils'
15
- import type {
16
- QueryFunction,
17
- QueryKey,
18
- QueryObserverResult,
19
- UseQueryOptions,
20
- UseQueryResult,
21
- } from '..'
22
- import { QueriesObserver, QueryCache, useQueries } from '..'
23
- import type { QueryFunctionContext } from '@tanstack/query-core'
24
23
 
25
24
  describe('useQueries', () => {
26
25
  const queryCache = new QueryCache()
@@ -145,10 +144,6 @@ describe('useQueries', () => {
145
144
  expectTypeNotAny(a)
146
145
  return a.toLowerCase()
147
146
  },
148
- onSuccess: (a) => {
149
- expectType<string>(a)
150
- expectTypeNotAny(a)
151
- },
152
147
  placeholderData: 'string',
153
148
  // @ts-expect-error (initialData: string)
154
149
  initialData: 123,
@@ -161,14 +156,6 @@ describe('useQueries', () => {
161
156
  expectTypeNotAny(a)
162
157
  return parseInt(a)
163
158
  },
164
- onSuccess: (a) => {
165
- expectType<number>(a)
166
- expectTypeNotAny(a)
167
- },
168
- onError: (e) => {
169
- expectType<boolean>(e)
170
- expectTypeNotAny(e)
171
- },
172
159
  placeholderData: 'string',
173
160
  // @ts-expect-error (initialData: string)
174
161
  initialData: 123,
@@ -305,10 +292,6 @@ describe('useQueries', () => {
305
292
  expectTypeNotAny(a)
306
293
  return a.toLowerCase()
307
294
  },
308
- onSuccess: (a) => {
309
- expectType<string>(a)
310
- expectTypeNotAny(a)
311
- },
312
295
  placeholderData: 'string',
313
296
  // @ts-expect-error (initialData: string)
314
297
  initialData: 123,
@@ -321,14 +304,6 @@ describe('useQueries', () => {
321
304
  expectTypeNotAny(a)
322
305
  return parseInt(a)
323
306
  },
324
- onSuccess: (a) => {
325
- expectType<number>(a)
326
- expectTypeNotAny(a)
327
- },
328
- onError: (e) => {
329
- expectType<boolean>(e)
330
- expectTypeNotAny(e)
331
- },
332
307
  placeholderData: 'string',
333
308
  // @ts-expect-error (initialData: string)
334
309
  initialData: 123,
@@ -424,60 +399,38 @@ describe('useQueries', () => {
424
399
  ],
425
400
  })
426
401
 
427
- // select / onSuccess / onSettled params are "indirectly" enforced
402
+ // select params are "indirectly" enforced
428
403
  useQueries({
429
404
  queries: [
430
405
  // unfortunately TS will not suggest the type for you
431
406
  {
432
407
  queryKey: key1,
433
408
  queryFn: () => 'string',
434
- // @ts-expect-error (noImplicitAny)
435
- onSuccess: (a) => null,
436
- // @ts-expect-error (noImplicitAny)
437
- onSettled: (a) => null,
438
409
  },
439
410
  // however you can add a type to the callback
440
411
  {
441
412
  queryKey: key2,
442
413
  queryFn: () => 'string',
443
- onSuccess: (a: string) => {
444
- expectType<string>(a)
445
- expectTypeNotAny(a)
446
- },
447
- onSettled: (a: string | undefined) => {
448
- expectType<string | undefined>(a)
449
- expectTypeNotAny(a)
450
- },
451
414
  },
452
415
  // the type you do pass is enforced
453
416
  {
454
417
  queryKey: key3,
455
418
  queryFn: () => 'string',
456
- // @ts-expect-error (only accepts string)
457
- onSuccess: (a: number) => null,
458
419
  },
459
420
  {
460
421
  queryKey: key4,
461
422
  queryFn: () => 'string',
462
423
  select: (a: string) => parseInt(a),
463
- // @ts-expect-error (select is defined => only accepts number)
464
- onSuccess: (a: string) => null,
465
- onSettled: (a: number | undefined) => {
466
- expectType<number | undefined>(a)
467
- expectTypeNotAny(a)
468
- },
469
424
  },
470
425
  ],
471
426
  })
472
427
 
473
428
  // callbacks are also indirectly enforced with Array.map
474
429
  useQueries({
475
- // @ts-expect-error (onSuccess only accepts string)
476
430
  queries: Array(50).map((_, i) => ({
477
431
  queryKey: ['key', i] as const,
478
432
  queryFn: () => i + 10,
479
433
  select: (data: number) => data.toString(),
480
- onSuccess: (_data: number) => null,
481
434
  })),
482
435
  })
483
436
  useQueries({
@@ -485,7 +438,6 @@ describe('useQueries', () => {
485
438
  queryKey: ['key', i] as const,
486
439
  queryFn: () => i + 10,
487
440
  select: (data: number) => data.toString(),
488
- onSuccess: (_data: string) => null,
489
441
  })),
490
442
  })
491
443
 
@@ -495,32 +447,15 @@ describe('useQueries', () => {
495
447
  {
496
448
  queryKey: key1,
497
449
  queryFn: () => 'string',
498
- // @ts-expect-error (noImplicitAny)
499
- onSuccess: (a) => null,
500
- // @ts-expect-error (noImplicitAny)
501
- onSettled: (a) => null,
502
450
  },
503
451
  {
504
452
  queryKey: key2,
505
453
  queryFn: () => 'string',
506
- onSuccess: (a: string) => {
507
- expectType<string>(a)
508
- expectTypeNotAny(a)
509
- },
510
- onSettled: (a: string | undefined) => {
511
- expectType<string | undefined>(a)
512
- expectTypeNotAny(a)
513
- },
514
454
  },
515
455
  {
516
456
  queryKey: key4,
517
457
  queryFn: () => 'string',
518
458
  select: (a: string) => parseInt(a),
519
- onSuccess: (_a: number) => null,
520
- onSettled: (a: number | undefined) => {
521
- expectType<number | undefined>(a)
522
- expectTypeNotAny(a)
523
- },
524
459
  },
525
460
  ],
526
461
  })
@@ -534,12 +469,6 @@ describe('useQueries', () => {
534
469
  {
535
470
  queryKey: key1,
536
471
  queryFn: () => Promise.resolve('string'),
537
- onSuccess: (a: string) => {
538
- expectType<string>(a)
539
- expectTypeNotAny(a)
540
- },
541
- // @ts-expect-error (refuses to accept a Promise)
542
- onSettled: (a: Promise<string>) => null,
543
472
  },
544
473
  ],
545
474
  })
@@ -646,11 +575,10 @@ describe('useQueries', () => {
646
575
  queries: queries.map(
647
576
  // no need to type the mapped query
648
577
  (query) => {
649
- const { queryFn: fn, queryKey: key, onError: err } = query
578
+ const { queryFn: fn, queryKey: key } = query
650
579
  expectType<QueryFunction<TQueryFnData, TQueryKey> | undefined>(fn)
651
580
  return {
652
581
  queryKey: key,
653
- onError: err,
654
582
  queryFn: fn
655
583
  ? (ctx: QueryFunctionContext<TQueryKey>) => {
656
584
  expectType<TQueryKey>(ctx.queryKey)
@@ -716,67 +644,8 @@ describe('useQueries', () => {
716
644
  }
717
645
  })
718
646
 
719
- it('should not change state if unmounted', async () => {
720
- const key1 = queryKey()
721
-
722
- // We have to mock the QueriesObserver to not unsubscribe
723
- // the listener when the component is unmounted
724
- class QueriesObserverMock extends QueriesObserver {
725
- subscribe(listener: any) {
726
- super.subscribe(listener)
727
- return () => void 0
728
- }
729
- }
730
-
731
- const QueriesObserverSpy = jest
732
- .spyOn(QueriesObserverModule, 'QueriesObserver')
733
- .mockImplementation((fn) => {
734
- return new QueriesObserverMock(fn)
735
- })
736
-
737
- function Queries() {
738
- useQueries({
739
- queries: [
740
- {
741
- queryKey: key1,
742
- queryFn: async () => {
743
- await sleep(10)
744
- return 1
745
- },
746
- },
747
- ],
748
- })
749
-
750
- return (
751
- <div>
752
- <span>queries</span>
753
- </div>
754
- )
755
- }
756
-
757
- function Page() {
758
- const [mounted, setMounted] = React.useState(true)
759
-
760
- return (
761
- <div>
762
- <button onClick={() => setMounted(false)}>unmount</button>
763
- {mounted && <Queries />}
764
- </div>
765
- )
766
- }
767
-
768
- const { getByText } = renderWithClient(queryClient, <Page />)
769
- fireEvent.click(getByText('unmount'))
770
-
771
- // Should not display the console error
772
- // "Warning: Can't perform a React state update on an unmounted component"
773
-
774
- await sleep(20)
775
- QueriesObserverSpy.mockRestore()
776
- })
777
-
778
647
  it("should throw error if in one of queries' queryFn throws and throwErrors is in use", async () => {
779
- const consoleMock = jest
648
+ const consoleMock = vi
780
649
  .spyOn(console, 'error')
781
650
  .mockImplementation(() => undefined)
782
651
  const key1 = queryKey()
@@ -841,7 +710,7 @@ describe('useQueries', () => {
841
710
  })
842
711
 
843
712
  it("should throw error if in one of queries' queryFn throws and throwErrors function resolves to true", async () => {
844
- const consoleMock = jest
713
+ const consoleMock = vi
845
714
  .spyOn(console, 'error')
846
715
  .mockImplementation(() => undefined)
847
716
  const key1 = queryKey()
@@ -914,15 +783,17 @@ describe('useQueries', () => {
914
783
  }
915
784
 
916
785
  function Page() {
917
- const queries = useQueries({
918
- queries: [
919
- {
920
- queryKey: key,
921
- queryFn,
922
- },
923
- ],
786
+ const queries = useQueries(
787
+ {
788
+ queries: [
789
+ {
790
+ queryKey: key,
791
+ queryFn,
792
+ },
793
+ ],
794
+ },
924
795
  queryClient,
925
- })
796
+ )
926
797
 
927
798
  return <div>data: {queries[0].data}</div>
928
799
  }