@tanstack/solid-query 5.0.0-alpha.3 → 5.0.0-alpha.32

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 (94) hide show
  1. package/build/cjs/index.js +81 -37
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/esm/index.js +82 -40
  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 +23 -22
  9. package/build/source/__tests__/createQueries.test.jsx +4 -91
  10. package/build/source/__tests__/createQuery.test.jsx +68 -277
  11. package/build/source/__tests__/createQuery.types.test.jsx +19 -1
  12. package/build/source/__tests__/suspense.test.jsx +9 -70
  13. package/build/source/__tests__/useIsFetching.test.jsx +2 -4
  14. package/build/source/__tests__/useIsMutating.test.jsx +25 -28
  15. package/build/source/__tests__/utils.jsx +4 -3
  16. package/build/source/createBaseQuery.js +48 -21
  17. package/build/source/createMutation.js +1 -1
  18. package/build/source/createQueries.js +5 -5
  19. package/build/source/createQuery.js +3 -0
  20. package/build/source/index.js +2 -1
  21. package/build/source/useIsFetching.js +5 -5
  22. package/build/source/useIsMutating.js +5 -5
  23. package/build/types/QueryClient.d.ts +30 -0
  24. package/build/types/QueryClient.d.ts.map +1 -0
  25. package/build/types/QueryClientProvider.d.ts +2 -1
  26. package/build/types/QueryClientProvider.d.ts.map +1 -0
  27. package/build/types/__tests__/QueryClientProvider.test.d.ts +1 -0
  28. package/build/types/__tests__/QueryClientProvider.test.d.ts.map +1 -0
  29. package/build/types/__tests__/createInfiniteQuery.test.d.ts +1 -0
  30. package/build/types/__tests__/createInfiniteQuery.test.d.ts.map +1 -0
  31. package/build/types/__tests__/createMutation.test.d.ts +1 -0
  32. package/build/types/__tests__/createMutation.test.d.ts.map +1 -0
  33. package/build/types/__tests__/createQueries.test.d.ts +1 -0
  34. package/build/types/__tests__/createQueries.test.d.ts.map +1 -0
  35. package/build/types/__tests__/createQuery.test.d.ts +1 -0
  36. package/build/types/__tests__/createQuery.test.d.ts.map +1 -0
  37. package/build/types/__tests__/createQuery.types.test.d.ts +1 -0
  38. package/build/types/__tests__/createQuery.types.test.d.ts.map +1 -0
  39. package/build/types/__tests__/suspense.test.d.ts +1 -0
  40. package/build/types/__tests__/suspense.test.d.ts.map +1 -0
  41. package/build/types/__tests__/transition.test.d.ts +1 -0
  42. package/build/types/__tests__/transition.test.d.ts.map +1 -0
  43. package/build/types/__tests__/useIsFetching.test.d.ts +1 -0
  44. package/build/types/__tests__/useIsFetching.test.d.ts.map +1 -0
  45. package/build/types/__tests__/useIsMutating.test.d.ts +1 -0
  46. package/build/types/__tests__/useIsMutating.test.d.ts.map +1 -0
  47. package/build/types/__tests__/utils.d.ts +4 -4
  48. package/build/types/__tests__/utils.d.ts.map +1 -0
  49. package/build/types/createBaseQuery.d.ts +4 -2
  50. package/build/types/createBaseQuery.d.ts.map +1 -0
  51. package/build/types/createInfiniteQuery.d.ts +5 -2
  52. package/build/types/createInfiniteQuery.d.ts.map +1 -0
  53. package/build/types/createMutation.d.ts +5 -2
  54. package/build/types/createMutation.d.ts.map +1 -0
  55. package/build/types/createQueries.d.ts +6 -4
  56. package/build/types/createQueries.d.ts.map +1 -0
  57. package/build/types/createQuery.d.ts +5 -1
  58. package/build/types/createQuery.d.ts.map +1 -0
  59. package/build/types/index.d.ts +4 -1
  60. package/build/types/index.d.ts.map +1 -0
  61. package/build/types/setBatchUpdatesFn.d.ts +1 -0
  62. package/build/types/setBatchUpdatesFn.d.ts.map +1 -0
  63. package/build/types/types.d.ts +3 -1
  64. package/build/types/types.d.ts.map +1 -0
  65. package/build/types/useIsFetching.d.ts +4 -7
  66. package/build/types/useIsFetching.d.ts.map +1 -0
  67. package/build/types/useIsMutating.d.ts +4 -7
  68. package/build/types/useIsMutating.d.ts.map +1 -0
  69. package/build/types/utils.d.ts +1 -0
  70. package/build/types/utils.d.ts.map +1 -0
  71. package/build/umd/index.js +1 -1
  72. package/build/umd/index.js.map +1 -1
  73. package/package.json +5 -5
  74. package/src/QueryClient.ts +84 -0
  75. package/src/QueryClientProvider.tsx +1 -1
  76. package/src/__tests__/QueryClientProvider.test.tsx +2 -1
  77. package/src/__tests__/createInfiniteQuery.test.tsx +95 -34
  78. package/src/__tests__/createMutation.test.tsx +23 -22
  79. package/src/__tests__/createQueries.test.tsx +4 -97
  80. package/src/__tests__/createQuery.test.tsx +84 -350
  81. package/src/__tests__/createQuery.types.test.tsx +21 -1
  82. package/src/__tests__/suspense.test.tsx +9 -91
  83. package/src/__tests__/useIsFetching.test.tsx +2 -4
  84. package/src/__tests__/useIsMutating.test.tsx +32 -40
  85. package/src/__tests__/utils.tsx +4 -3
  86. package/src/createBaseQuery.ts +73 -27
  87. package/src/createInfiniteQuery.ts +3 -2
  88. package/src/createMutation.ts +5 -3
  89. package/src/createQueries.ts +9 -8
  90. package/src/createQuery.ts +26 -2
  91. package/src/index.ts +8 -1
  92. package/src/types.ts +4 -2
  93. package/src/useIsFetching.ts +10 -13
  94. package/src/useIsMutating.ts +10 -11
@@ -3,6 +3,8 @@ import { createEffect, createMemo, createRenderEffect, createSignal, ErrorBounda
3
3
  import { fireEvent, render, screen, waitFor } from 'solid-testing-library';
4
4
  import { createQuery, QueryCache, QueryClientProvider, keepPreviousData, } from '..';
5
5
  import { Blink, createQueryClient, expectType, mockNavigatorOnLine, mockVisibilityState, queryKey, setActTimeout, sleep, } from './utils';
6
+ import { vi } from 'vitest';
7
+ import { reconcile } from 'solid-js/store';
6
8
  describe('createQuery', () => {
7
9
  const queryCache = new QueryCache();
8
10
  const queryClient = createQueryClient({ queryCache });
@@ -40,20 +42,16 @@ describe('createQuery', () => {
40
42
  createQuery(() => ({
41
43
  queryKey: [key],
42
44
  queryFn: async () => true,
43
- onSuccess: (data) => expectType(data),
44
- onSettled: (data) => expectType(data),
45
45
  }));
46
46
  // it should be possible to specify a union type as result type
47
47
  const unionTypeSync = createQuery(() => ({
48
48
  queryKey: key,
49
49
  queryFn: () => (Math.random() > 0.5 ? 'a' : 'b'),
50
- onSuccess: (data) => expectType(data),
51
50
  }));
52
51
  expectType(unionTypeSync.data);
53
52
  const unionTypeAsync = createQuery(() => ({
54
53
  queryKey: key,
55
54
  queryFn: () => Promise.resolve(Math.random() > 0.5 ? 'a' : 'b'),
56
- onSuccess: (data) => expectType(data),
57
55
  }));
58
56
  expectType(unionTypeAsync.data);
59
57
  // should error when the query function result does not match with the specified type
@@ -358,189 +356,6 @@ describe('createQuery', () => {
358
356
  isFetchedAfterMount: true,
359
357
  });
360
358
  });
361
- it('should call onSuccess after a query has been fetched', async () => {
362
- const key = queryKey();
363
- const states = [];
364
- const onSuccess = jest.fn();
365
- function Page() {
366
- const state = createQuery(() => ({
367
- queryKey: key,
368
- queryFn: async () => {
369
- await sleep(10);
370
- return 'data';
371
- },
372
- onSuccess,
373
- }));
374
- createRenderEffect(() => {
375
- states.push({ ...state });
376
- });
377
- return <div>data: {state.data}</div>;
378
- }
379
- render(() => (<QueryClientProvider client={queryClient}>
380
- <Page />
381
- </QueryClientProvider>));
382
- await screen.findByText('data: data');
383
- expect(states.length).toBe(2);
384
- expect(onSuccess).toHaveBeenCalledTimes(1);
385
- expect(onSuccess).toHaveBeenCalledWith('data');
386
- });
387
- it('should call onSuccess after a disabled query has been fetched', async () => {
388
- const key = queryKey();
389
- const states = [];
390
- const onSuccess = jest.fn();
391
- function Page() {
392
- const state = createQuery(() => ({
393
- queryKey: key,
394
- queryFn: () => 'data',
395
- enabled: false,
396
- onSuccess,
397
- }));
398
- createRenderEffect(() => {
399
- states.push({ ...state });
400
- });
401
- createEffect(() => {
402
- const refetch = state.refetch;
403
- setActTimeout(() => {
404
- refetch();
405
- }, 10);
406
- });
407
- return null;
408
- }
409
- render(() => (<QueryClientProvider client={queryClient}>
410
- <Page />
411
- </QueryClientProvider>));
412
- await sleep(50);
413
- expect(onSuccess).toHaveBeenCalledTimes(1);
414
- expect(onSuccess).toHaveBeenCalledWith('data');
415
- });
416
- it('should not call onSuccess if a component has unmounted', async () => {
417
- const key = queryKey();
418
- const states = [];
419
- const onSuccess = jest.fn();
420
- function Page() {
421
- const [show, setShow] = createSignal(true);
422
- createEffect(() => {
423
- setShow(false);
424
- });
425
- return <>{show() && <Component />}</>;
426
- }
427
- function Component() {
428
- const state = createQuery(() => ({
429
- queryKey: key,
430
- queryFn: async () => {
431
- await sleep(10);
432
- return 'data';
433
- },
434
- onSuccess,
435
- }));
436
- createRenderEffect(() => {
437
- states.push({ ...state });
438
- });
439
- return null;
440
- }
441
- render(() => (<QueryClientProvider client={queryClient}>
442
- <Page />
443
- </QueryClientProvider>));
444
- await sleep(50);
445
- expect(states.length).toBe(1);
446
- expect(onSuccess).toHaveBeenCalledTimes(0);
447
- });
448
- it('should call onError after a query has been fetched with an error', async () => {
449
- const key = queryKey();
450
- const states = [];
451
- const onError = jest.fn();
452
- function Page() {
453
- const state = createQuery(() => ({
454
- queryKey: key,
455
- queryFn: () => Promise.reject(new Error('error')),
456
- retry: false,
457
- onError,
458
- }));
459
- createRenderEffect(() => {
460
- states.push({ ...state });
461
- });
462
- return null;
463
- }
464
- render(() => (<QueryClientProvider client={queryClient}>
465
- <Page />
466
- </QueryClientProvider>));
467
- await sleep(10);
468
- expect(states.length).toBe(2);
469
- expect(onError).toHaveBeenCalledTimes(1);
470
- expect(onError).toHaveBeenCalledWith(new Error('error'));
471
- });
472
- it('should not call onError when receiving a CancelledError', async () => {
473
- const key = queryKey();
474
- const onError = jest.fn();
475
- function Page() {
476
- const state = createQuery(() => ({
477
- queryKey: key,
478
- queryFn: async () => {
479
- await sleep(10);
480
- return 23;
481
- },
482
- onError,
483
- }));
484
- return (<span>
485
- status: {state.status}, fetchStatus: {state.fetchStatus}
486
- </span>);
487
- }
488
- render(() => (<QueryClientProvider client={queryClient}>
489
- <Page />
490
- </QueryClientProvider>));
491
- await sleep(5);
492
- await queryClient.cancelQueries({ queryKey: key });
493
- // query cancellation will reset the query to it's initial state
494
- await waitFor(() => screen.getByText('status: pending, fetchStatus: idle'));
495
- expect(onError).not.toHaveBeenCalled();
496
- });
497
- it('should call onSettled after a query has been fetched', async () => {
498
- const key = queryKey();
499
- const states = [];
500
- const onSettled = jest.fn();
501
- function Page() {
502
- const state = createQuery(() => ({
503
- queryKey: key,
504
- queryFn: () => 'data',
505
- onSettled,
506
- }));
507
- createRenderEffect(() => {
508
- states.push({ ...state });
509
- });
510
- return null;
511
- }
512
- render(() => (<QueryClientProvider client={queryClient}>
513
- <Page />
514
- </QueryClientProvider>));
515
- await sleep(10);
516
- expect(states.length).toBe(2);
517
- expect(onSettled).toHaveBeenCalledTimes(1);
518
- expect(onSettled).toHaveBeenCalledWith('data', null);
519
- });
520
- it('should call onSettled after a query has been fetched with an error', async () => {
521
- const key = queryKey();
522
- const states = [];
523
- const onSettled = jest.fn();
524
- function Page() {
525
- const state = createQuery(() => ({
526
- queryKey: key,
527
- queryFn: () => Promise.reject('error'),
528
- retry: false,
529
- onSettled,
530
- }));
531
- createRenderEffect(() => {
532
- states.push({ ...state });
533
- });
534
- return null;
535
- }
536
- render(() => (<QueryClientProvider client={queryClient}>
537
- <Page />
538
- </QueryClientProvider>));
539
- await sleep(10);
540
- expect(states.length).toBe(2);
541
- expect(onSettled).toHaveBeenCalledTimes(1);
542
- expect(onSettled).toHaveBeenCalledWith(undefined, 'error');
543
- });
544
359
  it('should not cancel an ongoing fetch when refetch is called with cancelRefetch=false if we have data already', async () => {
545
360
  const key = queryKey();
546
361
  let fetchCount = 0;
@@ -964,7 +779,6 @@ describe('createQuery', () => {
964
779
  count++;
965
780
  return count === 1 ? result1 : result2;
966
781
  },
967
- notifyOnChangeProps: 'all',
968
782
  }));
969
783
  createRenderEffect(() => {
970
784
  states.push({ ...state });
@@ -991,9 +805,8 @@ describe('createQuery', () => {
991
805
  const newTodo2 = newTodos?.[1];
992
806
  expect(todos).toEqual(result1);
993
807
  expect(newTodos).toEqual(result2);
994
- expect(newTodos).not.toBe(todos);
995
808
  expect(newTodo1).toBe(todo1);
996
- expect(newTodo2).not.toBe(todo2);
809
+ expect(newTodo2).toBe(todo2);
997
810
  return null;
998
811
  });
999
812
  it('should use query function from hook when the existing query does not have a query function', async () => {
@@ -1751,45 +1564,6 @@ describe('createQuery', () => {
1751
1564
  // There wiil only be one pass
1752
1565
  expect(renders).toBe(1);
1753
1566
  });
1754
- it('should batch re-renders including hook callbacks', async () => {
1755
- const key = queryKey();
1756
- let renders = 0;
1757
- let callbackCount = 0;
1758
- const queryFn = async () => {
1759
- await sleep(10);
1760
- return 'data';
1761
- };
1762
- function Page() {
1763
- const [count, setCount] = createSignal(0);
1764
- createQuery(() => ({
1765
- queryKey: key,
1766
- queryFn,
1767
- onSuccess: () => {
1768
- setCount((x) => x + 1);
1769
- },
1770
- }));
1771
- createQuery(() => ({
1772
- queryKey: key,
1773
- queryFn,
1774
- onSuccess: () => {
1775
- setCount((x) => x + 1);
1776
- },
1777
- }));
1778
- createEffect(() => {
1779
- renders++;
1780
- callbackCount = count();
1781
- });
1782
- return <div>count: {count()}</div>;
1783
- }
1784
- render(() => (<QueryClientProvider client={queryClient}>
1785
- <Page />
1786
- </QueryClientProvider>));
1787
- await waitFor(() => screen.getByText('count: 2'));
1788
- // Should be 3 instead of 5
1789
- expect(renders).toBe(3);
1790
- // Both callbacks should have been executed
1791
- expect(callbackCount).toBe(2);
1792
- });
1793
1567
  it('should render latest data even if react has discarded certain renders', async () => {
1794
1568
  const key = queryKey();
1795
1569
  function Page() {
@@ -1887,7 +1661,7 @@ describe('createQuery', () => {
1887
1661
  });
1888
1662
  it('should not refetch query on focus when `enabled` is set to `false`', async () => {
1889
1663
  const key = queryKey();
1890
- const queryFn = jest.fn().mockReturnValue('data');
1664
+ const queryFn = vi.fn().mockReturnValue('data');
1891
1665
  function Page() {
1892
1666
  const { data = 'default' } = createQuery(() => ({
1893
1667
  queryKey: key,
@@ -2143,14 +1917,14 @@ describe('createQuery', () => {
2143
1917
  await waitFor(() => screen.getByText('error'));
2144
1918
  await waitFor(() => screen.getByText('Error test jaylen'));
2145
1919
  });
2146
- it('should throw error if queryFn throws and throwErrors is in use', async () => {
1920
+ it('should throw error if queryFn throws and throwOnError is in use', async () => {
2147
1921
  const key = queryKey();
2148
1922
  function Page() {
2149
1923
  const state = createQuery(() => ({
2150
1924
  queryKey: key,
2151
1925
  queryFn: () => Promise.reject(new Error('Error test jaylen')),
2152
1926
  retry: false,
2153
- throwErrors: true,
1927
+ throwOnError: true,
2154
1928
  }));
2155
1929
  return (<div>
2156
1930
  <h1>{state.status}</h1>
@@ -2164,14 +1938,14 @@ describe('createQuery', () => {
2164
1938
  </QueryClientProvider>));
2165
1939
  await waitFor(() => screen.getByText('error boundary'));
2166
1940
  });
2167
- it('should update with data if we observe no properties and throwErrors', async () => {
1941
+ it('should update with data if we observe no properties and throwOnError', async () => {
2168
1942
  const key = queryKey();
2169
1943
  let result;
2170
1944
  function Page() {
2171
1945
  const query = createQuery(() => ({
2172
1946
  queryKey: key,
2173
1947
  queryFn: () => Promise.resolve('data'),
2174
- throwErrors: true,
1948
+ throwOnError: true,
2175
1949
  }));
2176
1950
  createEffect(() => {
2177
1951
  result = query;
@@ -2191,7 +1965,7 @@ describe('createQuery', () => {
2191
1965
  queryKey: key,
2192
1966
  queryFn: () => Promise.reject(new Error('Local Error')),
2193
1967
  retry: false,
2194
- throwErrors: (err) => err.message !== 'Local Error',
1968
+ throwOnError: (err) => err.message !== 'Local Error',
2195
1969
  }));
2196
1970
  return (<div>
2197
1971
  <h1>{state.status}</h1>
@@ -2213,7 +1987,7 @@ describe('createQuery', () => {
2213
1987
  queryKey: key,
2214
1988
  queryFn: () => Promise.reject(new Error('Remote Error')),
2215
1989
  retry: false,
2216
- throwErrors: (err) => err.message !== 'Local Error',
1990
+ throwOnError: (err) => err.message !== 'Local Error',
2217
1991
  }));
2218
1992
  return (<div>
2219
1993
  <h1>{state.status}</h1>
@@ -2500,6 +2274,7 @@ describe('createQuery', () => {
2500
2274
  queryFn: () => ({ count: 10 }),
2501
2275
  staleTime: Infinity,
2502
2276
  initialData: () => ({ count: count() }),
2277
+ reconcile: false,
2503
2278
  }));
2504
2279
  createRenderEffect(() => {
2505
2280
  states.push({ ...state });
@@ -2523,7 +2298,7 @@ describe('createQuery', () => {
2523
2298
  });
2524
2299
  it('should retry specified number of times', async () => {
2525
2300
  const key = queryKey();
2526
- const queryFn = jest.fn();
2301
+ const queryFn = vi.fn();
2527
2302
  queryFn.mockImplementation(() => {
2528
2303
  return Promise.reject(new Error('Error test Barrett'));
2529
2304
  });
@@ -2552,7 +2327,7 @@ describe('createQuery', () => {
2552
2327
  });
2553
2328
  it('should not retry if retry function `false`', async () => {
2554
2329
  const key = queryKey();
2555
- const queryFn = jest.fn();
2330
+ const queryFn = vi.fn();
2556
2331
  queryFn.mockImplementationOnce(() => {
2557
2332
  return Promise.reject(new Error('Error test Tanner'));
2558
2333
  });
@@ -2585,7 +2360,7 @@ describe('createQuery', () => {
2585
2360
  });
2586
2361
  it('should extract retryDelay from error', async () => {
2587
2362
  const key = queryKey();
2588
- const queryFn = jest.fn();
2363
+ const queryFn = vi.fn();
2589
2364
  queryFn.mockImplementation(() => {
2590
2365
  return Promise.reject({ delay: 50 });
2591
2366
  });
@@ -2747,9 +2522,9 @@ describe('createQuery', () => {
2747
2522
  it('should refetch if stale after a prefetch', async () => {
2748
2523
  const key = queryKey();
2749
2524
  const states = [];
2750
- const queryFn = jest.fn();
2525
+ const queryFn = vi.fn();
2751
2526
  queryFn.mockImplementation(() => 'data');
2752
- const prefetchQueryFn = jest.fn();
2527
+ const prefetchQueryFn = vi.fn();
2753
2528
  prefetchQueryFn.mockImplementation(() => 'not yet...');
2754
2529
  await queryClient.prefetchQuery({
2755
2530
  queryKey: key,
@@ -2773,9 +2548,9 @@ describe('createQuery', () => {
2773
2548
  });
2774
2549
  it('should not refetch if not stale after a prefetch', async () => {
2775
2550
  const key = queryKey();
2776
- const queryFn = jest.fn();
2551
+ const queryFn = vi.fn();
2777
2552
  queryFn.mockImplementation(() => 'data');
2778
- const prefetchQueryFn = jest.fn();
2553
+ const prefetchQueryFn = vi.fn();
2779
2554
  prefetchQueryFn.mockImplementation(async () => {
2780
2555
  await sleep(10);
2781
2556
  return 'not yet...';
@@ -2977,7 +2752,7 @@ describe('createQuery', () => {
2977
2752
  });
2978
2753
  it('it should support enabled:false in query object syntax', async () => {
2979
2754
  const key = queryKey();
2980
- const queryFn = jest.fn();
2755
+ const queryFn = vi.fn();
2981
2756
  queryFn.mockImplementation(() => 'data');
2982
2757
  function Page() {
2983
2758
  const { fetchStatus } = createQuery(() => ({
@@ -3028,7 +2803,7 @@ describe('createQuery', () => {
3028
2803
  <Page />
3029
2804
  </QueryClientProvider>));
3030
2805
  await waitFor(() => screen.getByText('fetched data'));
3031
- const setTimeoutSpy = jest.spyOn(window, 'setTimeout');
2806
+ const setTimeoutSpy = vi.spyOn(window, 'setTimeout');
3032
2807
  result.unmount();
3033
2808
  expect(setTimeoutSpy).not.toHaveBeenCalled();
3034
2809
  });
@@ -3046,14 +2821,14 @@ describe('createQuery', () => {
3046
2821
  <Page />
3047
2822
  </QueryClientProvider>));
3048
2823
  await waitFor(() => screen.getByText('fetched data'));
3049
- const setTimeoutSpy = jest.spyOn(window, 'setTimeout');
2824
+ const setTimeoutSpy = vi.spyOn(window, 'setTimeout');
3050
2825
  result.unmount();
3051
2826
  expect(setTimeoutSpy).toHaveBeenLastCalledWith(expect.any(Function), 1000 * 60 * 10);
3052
2827
  });
3053
2828
  it('should not cause memo churn when data does not change', async () => {
3054
2829
  const key = queryKey();
3055
- const queryFn = jest.fn().mockReturnValue('data');
3056
- const memoFn = jest.fn();
2830
+ const queryFn = vi.fn().mockReturnValue('data');
2831
+ const memoFn = vi.fn();
3057
2832
  function Page() {
3058
2833
  const result = createQuery(() => ({
3059
2834
  queryKey: key,
@@ -3234,7 +3009,7 @@ describe('createQuery', () => {
3234
3009
  });
3235
3010
  it('should refetch if any query instance becomes enabled', async () => {
3236
3011
  const key = queryKey();
3237
- const queryFn = jest.fn().mockReturnValue('data');
3012
+ const queryFn = vi.fn().mockReturnValue('data');
3238
3013
  function Disabled() {
3239
3014
  createQuery(() => ({ queryKey: key, queryFn, enabled: false }));
3240
3015
  return null;
@@ -3502,12 +3277,53 @@ describe('createQuery', () => {
3502
3277
  // effect should not be triggered again due to structural sharing
3503
3278
  expect(states).toHaveLength(1);
3504
3279
  });
3280
+ it('The reconcile fn callback should correctly maintain referential equality', async () => {
3281
+ const key1 = queryKey();
3282
+ const states = [];
3283
+ function Page() {
3284
+ const [forceValue, setForceValue] = createSignal(1);
3285
+ const state = createQuery(() => ({
3286
+ queryKey: key1,
3287
+ queryFn: async () => {
3288
+ await sleep(10);
3289
+ return [1, 2];
3290
+ },
3291
+ select: (res) => res.map((x) => x + 1),
3292
+ reconcile(oldData, newData) {
3293
+ return reconcile(newData)(oldData);
3294
+ },
3295
+ }));
3296
+ createEffect(() => {
3297
+ if (state.data) {
3298
+ states.push(state.data);
3299
+ }
3300
+ });
3301
+ const forceUpdate = () => {
3302
+ setForceValue((prev) => prev + 1);
3303
+ };
3304
+ return (<div>
3305
+ <h2>Data: {JSON.stringify(state.data)}</h2>
3306
+ <h2>forceValue: {forceValue}</h2>
3307
+ <button onClick={forceUpdate}>forceUpdate</button>
3308
+ </div>);
3309
+ }
3310
+ render(() => (<QueryClientProvider client={queryClient}>
3311
+ <Page />
3312
+ </QueryClientProvider>));
3313
+ await waitFor(() => screen.getByText('Data: [2,3]'));
3314
+ expect(states).toHaveLength(1);
3315
+ fireEvent.click(screen.getByRole('button', { name: /forceUpdate/i }));
3316
+ await waitFor(() => screen.getByText('forceValue: 2'));
3317
+ await waitFor(() => screen.getByText('Data: [2,3]'));
3318
+ // effect should not be triggered again due to structural sharing
3319
+ expect(states).toHaveLength(1);
3320
+ });
3505
3321
  it('should cancel the query function when there are no more subscriptions', async () => {
3506
3322
  const key = queryKey();
3507
- let cancelFn = jest.fn();
3323
+ let cancelFn = vi.fn();
3508
3324
  const queryFn = ({ signal }) => {
3509
3325
  const promise = new Promise((resolve, reject) => {
3510
- cancelFn = jest.fn(() => reject('Cancelled'));
3326
+ cancelFn = vi.fn(() => reject('Cancelled'));
3511
3327
  signal?.addEventListener('abort', cancelFn);
3512
3328
  sleep(20).then(() => resolve('OK'));
3513
3329
  });
@@ -3767,7 +3583,7 @@ describe('createQuery', () => {
3767
3583
  expect(renders).toBe(hashes);
3768
3584
  });
3769
3585
  it('should refetch when changed enabled to true in error state', async () => {
3770
- const queryFn = jest.fn();
3586
+ const queryFn = vi.fn();
3771
3587
  queryFn.mockImplementation(async () => {
3772
3588
  await sleep(10);
3773
3589
  return Promise.reject(new Error('Suspense Error Bingo'));
@@ -4512,31 +4328,6 @@ describe('createQuery', () => {
4512
4328
  error,
4513
4329
  });
4514
4330
  });
4515
- it('setQueryData - should not call onSuccess callback of active observers', async () => {
4516
- const key = queryKey();
4517
- const onSuccess = jest.fn();
4518
- function Page() {
4519
- const state = createQuery(() => ({
4520
- queryKey: key,
4521
- queryFn: () => 'data',
4522
- onSuccess,
4523
- }));
4524
- return (<div>
4525
- <div>data: {state.data}</div>
4526
- <button onClick={() => queryClient.setQueryData(key, 'newData')}>
4527
- setQueryData
4528
- </button>
4529
- </div>);
4530
- }
4531
- render(() => (<QueryClientProvider client={queryClient}>
4532
- <Page />
4533
- </QueryClientProvider>));
4534
- await waitFor(() => screen.getByText('data: data'));
4535
- fireEvent.click(screen.getByRole('button', { name: /setQueryData/i }));
4536
- await waitFor(() => screen.getByText('data: newData'));
4537
- expect(onSuccess).toHaveBeenCalledTimes(1);
4538
- expect(onSuccess).toHaveBeenCalledWith('data');
4539
- });
4540
4331
  it('setQueryData - should respect updatedAt', async () => {
4541
4332
  const key = queryKey();
4542
4333
  function Page() {
@@ -1,4 +1,4 @@
1
- import { createQuery } from '../index';
1
+ import { createQuery, queryOptions } from '../index';
2
2
  const doNotExecute = (_func) => true;
3
3
  describe('initialData', () => {
4
4
  describe('Config object overload', () => {
@@ -19,6 +19,24 @@ describe('initialData', () => {
19
19
  return result;
20
20
  });
21
21
  });
22
+ it('TData should be defined when passed through queryOptions', () => {
23
+ doNotExecute(() => {
24
+ const options = queryOptions(() => ({
25
+ queryKey: ['key'],
26
+ queryFn: () => {
27
+ return {
28
+ wow: true,
29
+ };
30
+ },
31
+ initialData: {
32
+ wow: true,
33
+ },
34
+ }));
35
+ const { data } = createQuery(options);
36
+ const result = true;
37
+ return result;
38
+ });
39
+ });
22
40
  it('TData should always be defined when initialData is provided as a function which ALWAYS returns the data', () => {
23
41
  doNotExecute(() => {
24
42
  const { data } = createQuery(() => ({