@tanstack/solid-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 (54) hide show
  1. package/build/cjs/index.js +73 -34
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/esm/index.js +75 -37
  4. package/build/esm/index.js.map +1 -1
  5. package/build/source/QueryClient.js +6 -0
  6. package/build/source/__tests__/QueryClientProvider.test.jsx +2 -1
  7. package/build/source/__tests__/createInfiniteQuery.test.jsx +67 -20
  8. package/build/source/__tests__/createMutation.test.jsx +19 -18
  9. package/build/source/__tests__/createQueries.test.jsx +4 -91
  10. package/build/source/__tests__/createQuery.test.jsx +62 -271
  11. package/build/source/__tests__/suspense.test.jsx +3 -64
  12. package/build/source/__tests__/useIsFetching.test.jsx +2 -4
  13. package/build/source/__tests__/useIsMutating.test.jsx +25 -28
  14. package/build/source/__tests__/utils.jsx +4 -3
  15. package/build/source/createBaseQuery.js +45 -19
  16. package/build/source/createQueries.js +5 -5
  17. package/build/source/index.js +1 -0
  18. package/build/source/useIsFetching.js +5 -5
  19. package/build/source/useIsMutating.js +5 -5
  20. package/build/types/QueryClient.d.ts +29 -0
  21. package/build/types/QueryClientProvider.d.ts +1 -1
  22. package/build/types/__tests__/utils.d.ts +3 -4
  23. package/build/types/createBaseQuery.d.ts +3 -2
  24. package/build/types/createInfiniteQuery.d.ts +4 -2
  25. package/build/types/createMutation.d.ts +4 -2
  26. package/build/types/createQueries.d.ts +5 -4
  27. package/build/types/createQuery.d.ts +2 -1
  28. package/build/types/index.d.ts +2 -0
  29. package/build/types/types.d.ts +2 -1
  30. package/build/types/useIsFetching.d.ts +3 -7
  31. package/build/types/useIsMutating.d.ts +3 -7
  32. package/build/umd/index.js +1 -1
  33. package/build/umd/index.js.map +1 -1
  34. package/package.json +5 -5
  35. package/src/QueryClient.ts +84 -0
  36. package/src/QueryClientProvider.tsx +1 -1
  37. package/src/__tests__/QueryClientProvider.test.tsx +2 -1
  38. package/src/__tests__/createInfiniteQuery.test.tsx +95 -34
  39. package/src/__tests__/createMutation.test.tsx +19 -18
  40. package/src/__tests__/createQueries.test.tsx +4 -97
  41. package/src/__tests__/createQuery.test.tsx +78 -344
  42. package/src/__tests__/suspense.test.tsx +3 -85
  43. package/src/__tests__/useIsFetching.test.tsx +2 -4
  44. package/src/__tests__/useIsMutating.test.tsx +32 -40
  45. package/src/__tests__/utils.tsx +4 -3
  46. package/src/createBaseQuery.ts +70 -25
  47. package/src/createInfiniteQuery.ts +3 -2
  48. package/src/createMutation.ts +4 -2
  49. package/src/createQueries.ts +9 -8
  50. package/src/createQuery.ts +4 -2
  51. package/src/index.ts +7 -0
  52. package/src/types.ts +4 -2
  53. package/src/useIsFetching.ts +10 -13
  54. package/src/useIsMutating.ts +10 -11
@@ -33,6 +33,9 @@ import {
33
33
  setActTimeout,
34
34
  sleep,
35
35
  } from './utils'
36
+ import { vi } from 'vitest'
37
+ import type { Mock } from 'vitest'
38
+ import { reconcile } from 'solid-js/store'
36
39
 
37
40
  describe('createQuery', () => {
38
41
  const queryCache = new QueryCache()
@@ -77,21 +80,17 @@ describe('createQuery', () => {
77
80
  createQuery(() => ({
78
81
  queryKey: [key],
79
82
  queryFn: async () => true,
80
- onSuccess: (data) => expectType<boolean>(data),
81
- onSettled: (data) => expectType<boolean | undefined>(data),
82
83
  }))
83
84
 
84
85
  // it should be possible to specify a union type as result type
85
86
  const unionTypeSync = createQuery(() => ({
86
87
  queryKey: key,
87
88
  queryFn: () => (Math.random() > 0.5 ? 'a' : 'b'),
88
- onSuccess: (data) => expectType<'a' | 'b'>(data),
89
89
  }))
90
90
  expectType<'a' | 'b' | undefined>(unionTypeSync.data)
91
91
  const unionTypeAsync = createQuery<'a' | 'b'>(() => ({
92
92
  queryKey: key,
93
93
  queryFn: () => Promise.resolve(Math.random() > 0.5 ? 'a' : 'b'),
94
- onSuccess: (data) => expectType<'a' | 'b'>(data),
95
94
  }))
96
95
  expectType<'a' | 'b' | undefined>(unionTypeAsync.data)
97
96
 
@@ -488,241 +487,6 @@ describe('createQuery', () => {
488
487
  })
489
488
  })
490
489
 
491
- it('should call onSuccess after a query has been fetched', async () => {
492
- const key = queryKey()
493
- const states: CreateQueryResult<string>[] = []
494
- const onSuccess = jest.fn()
495
-
496
- function Page() {
497
- const state = createQuery(() => ({
498
- queryKey: key,
499
- queryFn: async () => {
500
- await sleep(10)
501
- return 'data'
502
- },
503
- onSuccess,
504
- }))
505
- createRenderEffect(() => {
506
- states.push({ ...state })
507
- })
508
- return <div>data: {state.data}</div>
509
- }
510
-
511
- render(() => (
512
- <QueryClientProvider client={queryClient}>
513
- <Page />
514
- </QueryClientProvider>
515
- ))
516
-
517
- await screen.findByText('data: data')
518
- expect(states.length).toBe(2)
519
- expect(onSuccess).toHaveBeenCalledTimes(1)
520
- expect(onSuccess).toHaveBeenCalledWith('data')
521
- })
522
-
523
- it('should call onSuccess after a disabled query has been fetched', async () => {
524
- const key = queryKey()
525
- const states: CreateQueryResult<string>[] = []
526
- const onSuccess = jest.fn()
527
-
528
- function Page() {
529
- const state = createQuery(() => ({
530
- queryKey: key,
531
- queryFn: () => 'data',
532
- enabled: false,
533
- onSuccess,
534
- }))
535
-
536
- createRenderEffect(() => {
537
- states.push({ ...state })
538
- })
539
-
540
- createEffect(() => {
541
- const refetch = state.refetch
542
- setActTimeout(() => {
543
- refetch()
544
- }, 10)
545
- })
546
-
547
- return null
548
- }
549
-
550
- render(() => (
551
- <QueryClientProvider client={queryClient}>
552
- <Page />
553
- </QueryClientProvider>
554
- ))
555
-
556
- await sleep(50)
557
- expect(onSuccess).toHaveBeenCalledTimes(1)
558
- expect(onSuccess).toHaveBeenCalledWith('data')
559
- })
560
-
561
- it('should not call onSuccess if a component has unmounted', async () => {
562
- const key = queryKey()
563
- const states: CreateQueryResult<string>[] = []
564
- const onSuccess = jest.fn()
565
-
566
- function Page() {
567
- const [show, setShow] = createSignal(true)
568
-
569
- createEffect(() => {
570
- setShow(false)
571
- })
572
- return <>{show() && <Component />}</>
573
- }
574
-
575
- function Component() {
576
- const state = createQuery(() => ({
577
- queryKey: key,
578
- queryFn: async () => {
579
- await sleep(10)
580
- return 'data'
581
- },
582
- onSuccess,
583
- }))
584
- createRenderEffect(() => {
585
- states.push({ ...state })
586
- })
587
- return null
588
- }
589
-
590
- render(() => (
591
- <QueryClientProvider client={queryClient}>
592
- <Page />
593
- </QueryClientProvider>
594
- ))
595
-
596
- await sleep(50)
597
- expect(states.length).toBe(1)
598
- expect(onSuccess).toHaveBeenCalledTimes(0)
599
- })
600
-
601
- it('should call onError after a query has been fetched with an error', async () => {
602
- const key = queryKey()
603
- const states: CreateQueryResult<unknown>[] = []
604
- const onError = jest.fn()
605
-
606
- function Page() {
607
- const state = createQuery(() => ({
608
- queryKey: key,
609
- queryFn: () => Promise.reject(new Error('error')),
610
- retry: false,
611
- onError,
612
- }))
613
-
614
- createRenderEffect(() => {
615
- states.push({ ...state })
616
- })
617
-
618
- return null
619
- }
620
-
621
- render(() => (
622
- <QueryClientProvider client={queryClient}>
623
- <Page />
624
- </QueryClientProvider>
625
- ))
626
-
627
- await sleep(10)
628
- expect(states.length).toBe(2)
629
- expect(onError).toHaveBeenCalledTimes(1)
630
- expect(onError).toHaveBeenCalledWith(new Error('error'))
631
- })
632
-
633
- it('should not call onError when receiving a CancelledError', async () => {
634
- const key = queryKey()
635
- const onError = jest.fn()
636
-
637
- function Page() {
638
- const state = createQuery(() => ({
639
- queryKey: key,
640
- queryFn: async () => {
641
- await sleep(10)
642
- return 23
643
- },
644
- onError,
645
- }))
646
- return (
647
- <span>
648
- status: {state.status}, fetchStatus: {state.fetchStatus}
649
- </span>
650
- )
651
- }
652
-
653
- render(() => (
654
- <QueryClientProvider client={queryClient}>
655
- <Page />
656
- </QueryClientProvider>
657
- ))
658
-
659
- await sleep(5)
660
- await queryClient.cancelQueries({ queryKey: key })
661
- // query cancellation will reset the query to it's initial state
662
- await waitFor(() => screen.getByText('status: pending, fetchStatus: idle'))
663
- expect(onError).not.toHaveBeenCalled()
664
- })
665
-
666
- it('should call onSettled after a query has been fetched', async () => {
667
- const key = queryKey()
668
- const states: CreateQueryResult<string>[] = []
669
- const onSettled = jest.fn()
670
-
671
- function Page() {
672
- const state = createQuery(() => ({
673
- queryKey: key,
674
- queryFn: () => 'data',
675
- onSettled,
676
- }))
677
-
678
- createRenderEffect(() => {
679
- states.push({ ...state })
680
- })
681
- return null
682
- }
683
-
684
- render(() => (
685
- <QueryClientProvider client={queryClient}>
686
- <Page />
687
- </QueryClientProvider>
688
- ))
689
-
690
- await sleep(10)
691
- expect(states.length).toBe(2)
692
- expect(onSettled).toHaveBeenCalledTimes(1)
693
- expect(onSettled).toHaveBeenCalledWith('data', null)
694
- })
695
-
696
- it('should call onSettled after a query has been fetched with an error', async () => {
697
- const key = queryKey()
698
- const states: CreateQueryResult<string>[] = []
699
- const onSettled = jest.fn()
700
-
701
- function Page() {
702
- const state = createQuery(() => ({
703
- queryKey: key,
704
- queryFn: () => Promise.reject<unknown>('error'),
705
- retry: false,
706
- onSettled,
707
- }))
708
- createRenderEffect(() => {
709
- states.push({ ...state })
710
- })
711
- return null
712
- }
713
-
714
- render(() => (
715
- <QueryClientProvider client={queryClient}>
716
- <Page />
717
- </QueryClientProvider>
718
- ))
719
-
720
- await sleep(10)
721
- expect(states.length).toBe(2)
722
- expect(onSettled).toHaveBeenCalledTimes(1)
723
- expect(onSettled).toHaveBeenCalledWith(undefined, 'error')
724
- })
725
-
726
490
  it('should not cancel an ongoing fetch when refetch is called with cancelRefetch=false if we have data already', async () => {
727
491
  const key = queryKey()
728
492
  let fetchCount = 0
@@ -1280,7 +1044,6 @@ describe('createQuery', () => {
1280
1044
  count++
1281
1045
  return count === 1 ? result1 : result2
1282
1046
  },
1283
- notifyOnChangeProps: 'all',
1284
1047
  }))
1285
1048
 
1286
1049
  createRenderEffect(() => {
@@ -1320,9 +1083,8 @@ describe('createQuery', () => {
1320
1083
 
1321
1084
  expect(todos).toEqual(result1)
1322
1085
  expect(newTodos).toEqual(result2)
1323
- expect(newTodos).not.toBe(todos)
1324
1086
  expect(newTodo1).toBe(todo1)
1325
- expect(newTodo2).not.toBe(todo2)
1087
+ expect(newTodo2).toBe(todo2)
1326
1088
 
1327
1089
  return null
1328
1090
  })
@@ -2273,56 +2035,6 @@ describe('createQuery', () => {
2273
2035
  expect(renders).toBe(1)
2274
2036
  })
2275
2037
 
2276
- it('should batch re-renders including hook callbacks', async () => {
2277
- const key = queryKey()
2278
-
2279
- let renders = 0
2280
- let callbackCount = 0
2281
-
2282
- const queryFn = async () => {
2283
- await sleep(10)
2284
- return 'data'
2285
- }
2286
-
2287
- function Page() {
2288
- const [count, setCount] = createSignal(0)
2289
- createQuery(() => ({
2290
- queryKey: key,
2291
- queryFn,
2292
- onSuccess: () => {
2293
- setCount((x) => x + 1)
2294
- },
2295
- }))
2296
- createQuery(() => ({
2297
- queryKey: key,
2298
- queryFn,
2299
- onSuccess: () => {
2300
- setCount((x) => x + 1)
2301
- },
2302
- }))
2303
-
2304
- createEffect(() => {
2305
- renders++
2306
- callbackCount = count()
2307
- })
2308
-
2309
- return <div>count: {count()}</div>
2310
- }
2311
-
2312
- render(() => (
2313
- <QueryClientProvider client={queryClient}>
2314
- <Page />
2315
- </QueryClientProvider>
2316
- ))
2317
-
2318
- await waitFor(() => screen.getByText('count: 2'))
2319
-
2320
- // Should be 3 instead of 5
2321
- expect(renders).toBe(3)
2322
- // Both callbacks should have been executed
2323
- expect(callbackCount).toBe(2)
2324
- })
2325
-
2326
2038
  it('should render latest data even if react has discarded certain renders', async () => {
2327
2039
  const key = queryKey()
2328
2040
 
@@ -2452,7 +2164,7 @@ describe('createQuery', () => {
2452
2164
 
2453
2165
  it('should not refetch query on focus when `enabled` is set to `false`', async () => {
2454
2166
  const key = queryKey()
2455
- const queryFn = jest.fn<string, unknown[]>().mockReturnValue('data')
2167
+ const queryFn = vi.fn<unknown[], string>().mockReturnValue('data')
2456
2168
 
2457
2169
  function Page() {
2458
2170
  const { data = 'default' } = createQuery(() => ({
@@ -3255,7 +2967,7 @@ describe('createQuery', () => {
3255
2967
 
3256
2968
  it('should keep initial data when the query key changes', async () => {
3257
2969
  const key = queryKey()
3258
- const states: DefinedCreateQueryResult<{ count: number }>[] = []
2970
+ const states: Partial<DefinedCreateQueryResult<{ count: number }>>[] = []
3259
2971
 
3260
2972
  function Page() {
3261
2973
  const [count, setCount] = createSignal(0)
@@ -3264,6 +2976,7 @@ describe('createQuery', () => {
3264
2976
  queryFn: () => ({ count: 10 }),
3265
2977
  staleTime: Infinity,
3266
2978
  initialData: () => ({ count: count() }),
2979
+ reconcile: false,
3267
2980
  }))
3268
2981
  createRenderEffect(() => {
3269
2982
  states.push({ ...state })
@@ -3296,7 +3009,7 @@ describe('createQuery', () => {
3296
3009
  it('should retry specified number of times', async () => {
3297
3010
  const key = queryKey()
3298
3011
 
3299
- const queryFn = jest.fn<unknown, unknown[]>()
3012
+ const queryFn = vi.fn<unknown[], unknown>()
3300
3013
  queryFn.mockImplementation(() => {
3301
3014
  return Promise.reject(new Error('Error test Barrett'))
3302
3015
  })
@@ -3337,7 +3050,7 @@ describe('createQuery', () => {
3337
3050
  it('should not retry if retry function `false`', async () => {
3338
3051
  const key = queryKey()
3339
3052
 
3340
- const queryFn = jest.fn<unknown, unknown[]>()
3053
+ const queryFn = vi.fn<unknown[], unknown>()
3341
3054
 
3342
3055
  queryFn.mockImplementationOnce(() => {
3343
3056
  return Promise.reject(new Error('Error test Tanner'))
@@ -3385,7 +3098,7 @@ describe('createQuery', () => {
3385
3098
 
3386
3099
  type DelayError = { delay: number }
3387
3100
 
3388
- const queryFn = jest.fn<unknown, unknown[]>()
3101
+ const queryFn = vi.fn<unknown[], unknown>()
3389
3102
  queryFn.mockImplementation(() => {
3390
3103
  return Promise.reject({ delay: 50 })
3391
3104
  })
@@ -3596,10 +3309,10 @@ describe('createQuery', () => {
3596
3309
  const key = queryKey()
3597
3310
  const states: CreateQueryResult<string>[] = []
3598
3311
 
3599
- const queryFn = jest.fn<string, unknown[]>()
3312
+ const queryFn = vi.fn<unknown[], string>()
3600
3313
  queryFn.mockImplementation(() => 'data')
3601
3314
 
3602
- const prefetchQueryFn = jest.fn<string, unknown[]>()
3315
+ const prefetchQueryFn = vi.fn<unknown[], string>()
3603
3316
  prefetchQueryFn.mockImplementation(() => 'not yet...')
3604
3317
 
3605
3318
  await queryClient.prefetchQuery({
@@ -3633,10 +3346,10 @@ describe('createQuery', () => {
3633
3346
  it('should not refetch if not stale after a prefetch', async () => {
3634
3347
  const key = queryKey()
3635
3348
 
3636
- const queryFn = jest.fn<string, unknown[]>()
3349
+ const queryFn = vi.fn<unknown[], string>()
3637
3350
  queryFn.mockImplementation(() => 'data')
3638
3351
 
3639
- const prefetchQueryFn = jest.fn<Promise<string>, unknown[]>()
3352
+ const prefetchQueryFn = vi.fn<unknown[], Promise<string>>()
3640
3353
  prefetchQueryFn.mockImplementation(async () => {
3641
3354
  await sleep(10)
3642
3355
  return 'not yet...'
@@ -3909,7 +3622,7 @@ describe('createQuery', () => {
3909
3622
 
3910
3623
  it('it should support enabled:false in query object syntax', async () => {
3911
3624
  const key = queryKey()
3912
- const queryFn = jest.fn<string, unknown[]>()
3625
+ const queryFn = vi.fn<unknown[], string>()
3913
3626
  queryFn.mockImplementation(() => 'data')
3914
3627
 
3915
3628
  function Page() {
@@ -3981,7 +3694,7 @@ describe('createQuery', () => {
3981
3694
  ))
3982
3695
 
3983
3696
  await waitFor(() => screen.getByText('fetched data'))
3984
- const setTimeoutSpy = jest.spyOn(window, 'setTimeout')
3697
+ const setTimeoutSpy = vi.spyOn(window, 'setTimeout')
3985
3698
 
3986
3699
  result.unmount()
3987
3700
 
@@ -4007,7 +3720,7 @@ describe('createQuery', () => {
4007
3720
  ))
4008
3721
 
4009
3722
  await waitFor(() => screen.getByText('fetched data'))
4010
- const setTimeoutSpy = jest.spyOn(window, 'setTimeout')
3723
+ const setTimeoutSpy = vi.spyOn(window, 'setTimeout')
4011
3724
 
4012
3725
  result.unmount()
4013
3726
 
@@ -4019,8 +3732,8 @@ describe('createQuery', () => {
4019
3732
 
4020
3733
  it('should not cause memo churn when data does not change', async () => {
4021
3734
  const key = queryKey()
4022
- const queryFn = jest.fn<string, unknown[]>().mockReturnValue('data')
4023
- const memoFn = jest.fn()
3735
+ const queryFn = vi.fn<unknown[], string>().mockReturnValue('data')
3736
+ const memoFn = vi.fn()
4024
3737
 
4025
3738
  function Page() {
4026
3739
  const result = createQuery(() => ({
@@ -4255,7 +3968,7 @@ describe('createQuery', () => {
4255
3968
  it('should refetch if any query instance becomes enabled', async () => {
4256
3969
  const key = queryKey()
4257
3970
 
4258
- const queryFn = jest.fn<string, unknown[]>().mockReturnValue('data')
3971
+ const queryFn = vi.fn<unknown[], string>().mockReturnValue('data')
4259
3972
 
4260
3973
  function Disabled() {
4261
3974
  createQuery(() => ({ queryKey: key, queryFn, enabled: false }))
@@ -4608,13 +4321,68 @@ describe('createQuery', () => {
4608
4321
  expect(states).toHaveLength(1)
4609
4322
  })
4610
4323
 
4324
+ it('The reconcile fn callback should correctly maintain referential equality', async () => {
4325
+ const key1 = queryKey()
4326
+ const states: Array<Array<number>> = []
4327
+
4328
+ function Page() {
4329
+ const [forceValue, setForceValue] = createSignal(1)
4330
+
4331
+ const state = createQuery(() => ({
4332
+ queryKey: key1,
4333
+ queryFn: async () => {
4334
+ await sleep(10)
4335
+ return [1, 2]
4336
+ },
4337
+ select: (res) => res.map((x) => x + 1),
4338
+ reconcile(oldData, newData) {
4339
+ return reconcile(newData)(oldData)
4340
+ },
4341
+ }))
4342
+
4343
+ createEffect(() => {
4344
+ if (state.data) {
4345
+ states.push(state.data)
4346
+ }
4347
+ })
4348
+
4349
+ const forceUpdate = () => {
4350
+ setForceValue((prev) => prev + 1)
4351
+ }
4352
+
4353
+ return (
4354
+ <div>
4355
+ <h2>Data: {JSON.stringify(state.data)}</h2>
4356
+ <h2>forceValue: {forceValue}</h2>
4357
+ <button onClick={forceUpdate}>forceUpdate</button>
4358
+ </div>
4359
+ )
4360
+ }
4361
+
4362
+ render(() => (
4363
+ <QueryClientProvider client={queryClient}>
4364
+ <Page />
4365
+ </QueryClientProvider>
4366
+ ))
4367
+ await waitFor(() => screen.getByText('Data: [2,3]'))
4368
+ expect(states).toHaveLength(1)
4369
+
4370
+ fireEvent.click(screen.getByRole('button', { name: /forceUpdate/i }))
4371
+
4372
+ await waitFor(() => screen.getByText('forceValue: 2'))
4373
+ await waitFor(() => screen.getByText('Data: [2,3]'))
4374
+
4375
+ // effect should not be triggered again due to structural sharing
4376
+ expect(states).toHaveLength(1)
4377
+ })
4378
+
4611
4379
  it('should cancel the query function when there are no more subscriptions', async () => {
4612
4380
  const key = queryKey()
4613
- let cancelFn: jest.Mock = jest.fn()
4381
+ let cancelFn: Mock = vi.fn()
4614
4382
 
4615
4383
  const queryFn = ({ signal }: { signal?: AbortSignal }) => {
4616
4384
  const promise = new Promise<string>((resolve, reject) => {
4617
- cancelFn = jest.fn(() => reject('Cancelled'))
4385
+ cancelFn = vi.fn(() => reject('Cancelled'))
4618
4386
  signal?.addEventListener('abort', cancelFn)
4619
4387
  sleep(20).then(() => resolve('OK'))
4620
4388
  })
@@ -4958,7 +4726,7 @@ describe('createQuery', () => {
4958
4726
  })
4959
4727
 
4960
4728
  it('should refetch when changed enabled to true in error state', async () => {
4961
- const queryFn = jest.fn<unknown, unknown[]>()
4729
+ const queryFn = vi.fn<unknown[], unknown>()
4962
4730
  queryFn.mockImplementation(async () => {
4963
4731
  await sleep(10)
4964
4732
  return Promise.reject(new Error('Suspense Error Bingo'))
@@ -6050,40 +5818,6 @@ describe('createQuery', () => {
6050
5818
  })
6051
5819
  })
6052
5820
 
6053
- it('setQueryData - should not call onSuccess callback of active observers', async () => {
6054
- const key = queryKey()
6055
- const onSuccess = jest.fn()
6056
-
6057
- function Page() {
6058
- const state = createQuery(() => ({
6059
- queryKey: key,
6060
- queryFn: () => 'data',
6061
- onSuccess,
6062
- }))
6063
- return (
6064
- <div>
6065
- <div>data: {state.data}</div>
6066
- <button onClick={() => queryClient.setQueryData(key, 'newData')}>
6067
- setQueryData
6068
- </button>
6069
- </div>
6070
- )
6071
- }
6072
-
6073
- render(() => (
6074
- <QueryClientProvider client={queryClient}>
6075
- <Page />
6076
- </QueryClientProvider>
6077
- ))
6078
-
6079
- await waitFor(() => screen.getByText('data: data'))
6080
- fireEvent.click(screen.getByRole('button', { name: /setQueryData/i }))
6081
- await waitFor(() => screen.getByText('data: newData'))
6082
-
6083
- expect(onSuccess).toHaveBeenCalledTimes(1)
6084
- expect(onSuccess).toHaveBeenCalledWith('data')
6085
- })
6086
-
6087
5821
  it('setQueryData - should respect updatedAt', async () => {
6088
5822
  const key = queryKey()
6089
5823
 
@@ -20,6 +20,7 @@ import {
20
20
  QueryClientProvider,
21
21
  } from '..'
22
22
  import { createQueryClient, queryKey, sleep } from './utils'
23
+ import { vi } from 'vitest'
23
24
 
24
25
  describe("useQuery's in Suspense mode", () => {
25
26
  const queryCache = new QueryCache()
@@ -142,7 +143,7 @@ describe("useQuery's in Suspense mode", () => {
142
143
  it('should not call the queryFn twice when used in Suspense mode', async () => {
143
144
  const key = queryKey()
144
145
 
145
- const queryFn = jest.fn<string, unknown[]>()
146
+ const queryFn = vi.fn<unknown[], string>()
146
147
  queryFn.mockImplementation(() => {
147
148
  sleep(10)
148
149
  return 'data'
@@ -216,89 +217,6 @@ describe("useQuery's in Suspense mode", () => {
216
217
  expect(queryCache.find({ queryKey: key })?.getObserversCount()).toBe(0)
217
218
  })
218
219
 
219
- it('should call onSuccess on the first successful call', async () => {
220
- const key = queryKey()
221
-
222
- const successFn = jest.fn()
223
-
224
- function Page() {
225
- createQuery(() => ({
226
- queryKey: [key],
227
- queryFn: async () => {
228
- await sleep(10)
229
- return key
230
- },
231
-
232
- suspense: true,
233
- select: () => 'selected',
234
- onSuccess: successFn,
235
- }))
236
-
237
- return <>rendered</>
238
- }
239
-
240
- render(() => (
241
- <QueryClientProvider client={queryClient}>
242
- <Suspense fallback="loading">
243
- <Page />
244
- </Suspense>
245
- </QueryClientProvider>
246
- ))
247
-
248
- await waitFor(() => screen.getByText('rendered'))
249
-
250
- await waitFor(() => expect(successFn).toHaveBeenCalledTimes(1))
251
- await waitFor(() => expect(successFn).toHaveBeenCalledWith('selected'))
252
- })
253
-
254
- it('should call every onSuccess handler within a suspense boundary', async () => {
255
- const key = queryKey()
256
-
257
- const successFn1 = jest.fn()
258
- const successFn2 = jest.fn()
259
-
260
- function FirstComponent() {
261
- createQuery(() => ({
262
- queryKey: key,
263
- queryFn: () => {
264
- sleep(10)
265
- return 'data'
266
- },
267
- onSuccess: successFn1,
268
- }))
269
-
270
- return <span>first</span>
271
- }
272
-
273
- function SecondComponent() {
274
- createQuery(() => ({
275
- queryKey: key,
276
- queryFn: () => {
277
- sleep(10)
278
- return 'data'
279
- },
280
- onSuccess: successFn2,
281
- }))
282
-
283
- return <span>second</span>
284
- }
285
-
286
- render(() => (
287
- <QueryClientProvider client={queryClient}>
288
- <Suspense fallback="loading">
289
- <FirstComponent />
290
- <SecondComponent />
291
- </Suspense>
292
- ,
293
- </QueryClientProvider>
294
- ))
295
-
296
- await waitFor(() => screen.getByText('second'))
297
-
298
- await waitFor(() => expect(successFn1).toHaveBeenCalledTimes(1))
299
- await waitFor(() => expect(successFn2).toHaveBeenCalledTimes(1))
300
- })
301
-
302
220
  // https://github.com/tannerlinsley/react-query/issues/468
303
221
  it('should reset error state if new component instances are mounted', async () => {
304
222
  const key = queryKey()
@@ -733,7 +651,7 @@ describe("useQuery's in Suspense mode", () => {
733
651
  it('should not call the queryFn when not enabled', async () => {
734
652
  const key = queryKey()
735
653
 
736
- const queryFn = jest.fn<Promise<string>, unknown[]>()
654
+ const queryFn = vi.fn<unknown[], Promise<string>>()
737
655
  queryFn.mockImplementation(async () => {
738
656
  await sleep(10)
739
657
  return '23'