@tanstack/solid-query 5.0.0-alpha.20 → 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.
@@ -117,10 +117,6 @@ describe('useQueries', () => {
117
117
  expectTypeNotAny(a);
118
118
  return a.toLowerCase();
119
119
  },
120
- onSuccess: (a) => {
121
- expectType(a);
122
- expectTypeNotAny(a);
123
- },
124
120
  placeholderData: 'string',
125
121
  // @ts-expect-error (initialData: string)
126
122
  initialData: 123,
@@ -133,14 +129,6 @@ describe('useQueries', () => {
133
129
  expectTypeNotAny(a);
134
130
  return parseInt(a);
135
131
  },
136
- onSuccess: (a) => {
137
- expectType(a);
138
- expectTypeNotAny(a);
139
- },
140
- onError: (e) => {
141
- expectType(e);
142
- expectTypeNotAny(e);
143
- },
144
132
  placeholderData: 'string',
145
133
  // @ts-expect-error (initialData: string)
146
134
  initialData: 123,
@@ -253,10 +241,6 @@ describe('useQueries', () => {
253
241
  expectTypeNotAny(a);
254
242
  return a.toLowerCase();
255
243
  },
256
- onSuccess: (a) => {
257
- expectType(a);
258
- expectTypeNotAny(a);
259
- },
260
244
  placeholderData: 'string',
261
245
  // @ts-expect-error (initialData: string)
262
246
  initialData: 123,
@@ -269,14 +253,6 @@ describe('useQueries', () => {
269
253
  expectTypeNotAny(a);
270
254
  return parseInt(a);
271
255
  },
272
- onSuccess: (a) => {
273
- expectType(a);
274
- expectTypeNotAny(a);
275
- },
276
- onError: (e) => {
277
- expectType(e);
278
- expectTypeNotAny(e);
279
- },
280
256
  placeholderData: 'string',
281
257
  // @ts-expect-error (initialData: string)
282
258
  initialData: 123,
@@ -363,59 +339,37 @@ describe('useQueries', () => {
363
339
  },
364
340
  ],
365
341
  }));
366
- // select / onSuccess / onSettled params are "indirectly" enforced
342
+ // select params are "indirectly" enforced
367
343
  createQueries(() => ({
368
344
  queries: [
369
345
  // unfortunately TS will not suggest the type for you
370
346
  {
371
347
  queryKey: key1,
372
348
  queryFn: () => 'string',
373
- // @ts-expect-error (noImplicitAny)
374
- onSuccess: (a) => null,
375
- // @ts-expect-error (noImplicitAny)
376
- onSettled: (a) => null,
377
349
  },
378
350
  // however you can add a type to the callback
379
351
  {
380
352
  queryKey: key2,
381
353
  queryFn: () => 'string',
382
- onSuccess: (a) => {
383
- expectType(a);
384
- expectTypeNotAny(a);
385
- },
386
- onSettled: (a) => {
387
- expectType(a);
388
- expectTypeNotAny(a);
389
- },
390
354
  },
391
355
  // the type you do pass is enforced
392
356
  {
393
357
  queryKey: key3,
394
358
  queryFn: () => 'string',
395
- // @ts-expect-error (only accepts string)
396
- onSuccess: (a) => null,
397
359
  },
398
360
  {
399
361
  queryKey: key4,
400
362
  queryFn: () => 'string',
401
363
  select: (a) => parseInt(a),
402
- // @ts-expect-error (select is defined => only accepts number)
403
- onSuccess: (a) => null,
404
- onSettled: (a) => {
405
- expectType(a);
406
- expectTypeNotAny(a);
407
- },
408
364
  },
409
365
  ],
410
366
  }));
411
367
  // callbacks are also indirectly enforced with Array.map
412
368
  createQueries(() => ({
413
- // @ts-expect-error (onSuccess only accepts string)
414
369
  queries: Array(50).map((_, i) => ({
415
370
  queryKey: ['key', i],
416
371
  queryFn: () => i + 10,
417
372
  select: (data) => data.toString(),
418
- onSuccess: (_data) => null,
419
373
  })),
420
374
  }));
421
375
  createQueries(() => ({
@@ -423,7 +377,6 @@ describe('useQueries', () => {
423
377
  queryKey: ['key', i],
424
378
  queryFn: () => i + 10,
425
379
  select: (data) => data.toString(),
426
- onSuccess: (_data) => null,
427
380
  })),
428
381
  }));
429
382
  // results inference works when all the handlers are defined
@@ -432,32 +385,15 @@ describe('useQueries', () => {
432
385
  {
433
386
  queryKey: key1,
434
387
  queryFn: () => 'string',
435
- // @ts-expect-error (noImplicitAny)
436
- onSuccess: (a) => null,
437
- // @ts-expect-error (noImplicitAny)
438
- onSettled: (a) => null,
439
388
  },
440
389
  {
441
390
  queryKey: key2,
442
391
  queryFn: () => 'string',
443
- onSuccess: (a) => {
444
- expectType(a);
445
- expectTypeNotAny(a);
446
- },
447
- onSettled: (a) => {
448
- expectType(a);
449
- expectTypeNotAny(a);
450
- },
451
392
  },
452
393
  {
453
394
  queryKey: key4,
454
395
  queryFn: () => 'string',
455
396
  select: (a) => parseInt(a),
456
- onSuccess: (_a) => null,
457
- onSettled: (a) => {
458
- expectType(a);
459
- expectTypeNotAny(a);
460
- },
461
397
  },
462
398
  ],
463
399
  }));
@@ -470,12 +406,6 @@ describe('useQueries', () => {
470
406
  {
471
407
  queryKey: key1,
472
408
  queryFn: () => Promise.resolve('string'),
473
- onSuccess: (a) => {
474
- expectType(a);
475
- expectTypeNotAny(a);
476
- },
477
- // @ts-expect-error (refuses to accept a Promise)
478
- onSettled: (a) => null,
479
409
  },
480
410
  ],
481
411
  }));
@@ -555,11 +485,10 @@ describe('useQueries', () => {
555
485
  queries: queries.map(
556
486
  // no need to type the mapped query
557
487
  (query) => {
558
- const { queryFn: fn, queryKey: key, onError: err } = query;
488
+ const { queryFn: fn, queryKey: key } = query;
559
489
  expectType(fn);
560
490
  return {
561
491
  queryKey: key,
562
- onError: err,
563
492
  queryFn: fn
564
493
  ? (ctx) => {
565
494
  expectType(ctx.queryKey);
@@ -42,20 +42,16 @@ describe('createQuery', () => {
42
42
  createQuery(() => ({
43
43
  queryKey: [key],
44
44
  queryFn: async () => true,
45
- onSuccess: (data) => expectType(data),
46
- onSettled: (data) => expectType(data),
47
45
  }));
48
46
  // it should be possible to specify a union type as result type
49
47
  const unionTypeSync = createQuery(() => ({
50
48
  queryKey: key,
51
49
  queryFn: () => (Math.random() > 0.5 ? 'a' : 'b'),
52
- onSuccess: (data) => expectType(data),
53
50
  }));
54
51
  expectType(unionTypeSync.data);
55
52
  const unionTypeAsync = createQuery(() => ({
56
53
  queryKey: key,
57
54
  queryFn: () => Promise.resolve(Math.random() > 0.5 ? 'a' : 'b'),
58
- onSuccess: (data) => expectType(data),
59
55
  }));
60
56
  expectType(unionTypeAsync.data);
61
57
  // should error when the query function result does not match with the specified type
@@ -360,189 +356,6 @@ describe('createQuery', () => {
360
356
  isFetchedAfterMount: true,
361
357
  });
362
358
  });
363
- it('should call onSuccess after a query has been fetched', async () => {
364
- const key = queryKey();
365
- const states = [];
366
- const onSuccess = vi.fn();
367
- function Page() {
368
- const state = createQuery(() => ({
369
- queryKey: key,
370
- queryFn: async () => {
371
- await sleep(10);
372
- return 'data';
373
- },
374
- onSuccess,
375
- }));
376
- createRenderEffect(() => {
377
- states.push({ ...state });
378
- });
379
- return <div>data: {state.data}</div>;
380
- }
381
- render(() => (<QueryClientProvider client={queryClient}>
382
- <Page />
383
- </QueryClientProvider>));
384
- await screen.findByText('data: data');
385
- expect(states.length).toBe(2);
386
- expect(onSuccess).toHaveBeenCalledTimes(1);
387
- expect(onSuccess).toHaveBeenCalledWith('data');
388
- });
389
- it('should call onSuccess after a disabled query has been fetched', async () => {
390
- const key = queryKey();
391
- const states = [];
392
- const onSuccess = vi.fn();
393
- function Page() {
394
- const state = createQuery(() => ({
395
- queryKey: key,
396
- queryFn: () => 'data',
397
- enabled: false,
398
- onSuccess,
399
- }));
400
- createRenderEffect(() => {
401
- states.push({ ...state });
402
- });
403
- createEffect(() => {
404
- const refetch = state.refetch;
405
- setActTimeout(() => {
406
- refetch();
407
- }, 10);
408
- });
409
- return null;
410
- }
411
- render(() => (<QueryClientProvider client={queryClient}>
412
- <Page />
413
- </QueryClientProvider>));
414
- await sleep(50);
415
- expect(onSuccess).toHaveBeenCalledTimes(1);
416
- expect(onSuccess).toHaveBeenCalledWith('data');
417
- });
418
- it('should not call onSuccess if a component has unmounted', async () => {
419
- const key = queryKey();
420
- const states = [];
421
- const onSuccess = vi.fn();
422
- function Page() {
423
- const [show, setShow] = createSignal(true);
424
- createEffect(() => {
425
- setShow(false);
426
- });
427
- return <>{show() && <Component />}</>;
428
- }
429
- function Component() {
430
- const state = createQuery(() => ({
431
- queryKey: key,
432
- queryFn: async () => {
433
- await sleep(10);
434
- return 'data';
435
- },
436
- onSuccess,
437
- }));
438
- createRenderEffect(() => {
439
- states.push({ ...state });
440
- });
441
- return null;
442
- }
443
- render(() => (<QueryClientProvider client={queryClient}>
444
- <Page />
445
- </QueryClientProvider>));
446
- await sleep(50);
447
- expect(states.length).toBe(1);
448
- expect(onSuccess).toHaveBeenCalledTimes(0);
449
- });
450
- it('should call onError after a query has been fetched with an error', async () => {
451
- const key = queryKey();
452
- const states = [];
453
- const onError = vi.fn();
454
- function Page() {
455
- const state = createQuery(() => ({
456
- queryKey: key,
457
- queryFn: () => Promise.reject(new Error('error')),
458
- retry: false,
459
- onError,
460
- }));
461
- createRenderEffect(() => {
462
- states.push({ ...state });
463
- });
464
- return null;
465
- }
466
- render(() => (<QueryClientProvider client={queryClient}>
467
- <Page />
468
- </QueryClientProvider>));
469
- await sleep(10);
470
- expect(states.length).toBe(2);
471
- expect(onError).toHaveBeenCalledTimes(1);
472
- expect(onError).toHaveBeenCalledWith(new Error('error'));
473
- });
474
- it('should not call onError when receiving a CancelledError', async () => {
475
- const key = queryKey();
476
- const onError = vi.fn();
477
- function Page() {
478
- const state = createQuery(() => ({
479
- queryKey: key,
480
- queryFn: async () => {
481
- await sleep(10);
482
- return 23;
483
- },
484
- onError,
485
- }));
486
- return (<span>
487
- status: {state.status}, fetchStatus: {state.fetchStatus}
488
- </span>);
489
- }
490
- render(() => (<QueryClientProvider client={queryClient}>
491
- <Page />
492
- </QueryClientProvider>));
493
- await sleep(5);
494
- await queryClient.cancelQueries({ queryKey: key });
495
- // query cancellation will reset the query to it's initial state
496
- await waitFor(() => screen.getByText('status: pending, fetchStatus: idle'));
497
- expect(onError).not.toHaveBeenCalled();
498
- });
499
- it('should call onSettled after a query has been fetched', async () => {
500
- const key = queryKey();
501
- const states = [];
502
- const onSettled = vi.fn();
503
- function Page() {
504
- const state = createQuery(() => ({
505
- queryKey: key,
506
- queryFn: () => 'data',
507
- onSettled,
508
- }));
509
- createRenderEffect(() => {
510
- states.push({ ...state });
511
- });
512
- return null;
513
- }
514
- render(() => (<QueryClientProvider client={queryClient}>
515
- <Page />
516
- </QueryClientProvider>));
517
- await sleep(10);
518
- expect(states.length).toBe(2);
519
- expect(onSettled).toHaveBeenCalledTimes(1);
520
- expect(onSettled).toHaveBeenCalledWith('data', null);
521
- });
522
- it('should call onSettled after a query has been fetched with an error', async () => {
523
- const key = queryKey();
524
- const states = [];
525
- const onSettled = vi.fn();
526
- function Page() {
527
- const state = createQuery(() => ({
528
- queryKey: key,
529
- queryFn: () => Promise.reject('error'),
530
- retry: false,
531
- onSettled,
532
- }));
533
- createRenderEffect(() => {
534
- states.push({ ...state });
535
- });
536
- return null;
537
- }
538
- render(() => (<QueryClientProvider client={queryClient}>
539
- <Page />
540
- </QueryClientProvider>));
541
- await sleep(10);
542
- expect(states.length).toBe(2);
543
- expect(onSettled).toHaveBeenCalledTimes(1);
544
- expect(onSettled).toHaveBeenCalledWith(undefined, 'error');
545
- });
546
359
  it('should not cancel an ongoing fetch when refetch is called with cancelRefetch=false if we have data already', async () => {
547
360
  const key = queryKey();
548
361
  let fetchCount = 0;
@@ -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() {
@@ -4554,31 +4328,6 @@ describe('createQuery', () => {
4554
4328
  error,
4555
4329
  });
4556
4330
  });
4557
- it('setQueryData - should not call onSuccess callback of active observers', async () => {
4558
- const key = queryKey();
4559
- const onSuccess = vi.fn();
4560
- function Page() {
4561
- const state = createQuery(() => ({
4562
- queryKey: key,
4563
- queryFn: () => 'data',
4564
- onSuccess,
4565
- }));
4566
- return (<div>
4567
- <div>data: {state.data}</div>
4568
- <button onClick={() => queryClient.setQueryData(key, 'newData')}>
4569
- setQueryData
4570
- </button>
4571
- </div>);
4572
- }
4573
- render(() => (<QueryClientProvider client={queryClient}>
4574
- <Page />
4575
- </QueryClientProvider>));
4576
- await waitFor(() => screen.getByText('data: data'));
4577
- fireEvent.click(screen.getByRole('button', { name: /setQueryData/i }));
4578
- await waitFor(() => screen.getByText('data: newData'));
4579
- expect(onSuccess).toHaveBeenCalledTimes(1);
4580
- expect(onSuccess).toHaveBeenCalledWith('data');
4581
- });
4582
4331
  it('setQueryData - should respect updatedAt', async () => {
4583
4332
  const key = queryKey();
4584
4333
  function Page() {
@@ -140,68 +140,6 @@ describe("useQuery's in Suspense mode", () => {
140
140
  expect(screen.queryByText('rendered')).toBeNull();
141
141
  expect(queryCache.find({ queryKey: key })?.getObserversCount()).toBe(0);
142
142
  });
143
- it('should call onSuccess on the first successful call', async () => {
144
- const key = queryKey();
145
- const successFn = vi.fn();
146
- function Page() {
147
- createQuery(() => ({
148
- queryKey: [key],
149
- queryFn: async () => {
150
- await sleep(10);
151
- return key;
152
- },
153
- suspense: true,
154
- select: () => 'selected',
155
- onSuccess: successFn,
156
- }));
157
- return <>rendered</>;
158
- }
159
- render(() => (<QueryClientProvider client={queryClient}>
160
- <Suspense fallback="loading">
161
- <Page />
162
- </Suspense>
163
- </QueryClientProvider>));
164
- await waitFor(() => screen.getByText('rendered'));
165
- await waitFor(() => expect(successFn).toHaveBeenCalledTimes(1));
166
- await waitFor(() => expect(successFn).toHaveBeenCalledWith('selected'));
167
- });
168
- it('should call every onSuccess handler within a suspense boundary', async () => {
169
- const key = queryKey();
170
- const successFn1 = vi.fn();
171
- const successFn2 = vi.fn();
172
- function FirstComponent() {
173
- createQuery(() => ({
174
- queryKey: key,
175
- queryFn: () => {
176
- sleep(10);
177
- return 'data';
178
- },
179
- onSuccess: successFn1,
180
- }));
181
- return <span>first</span>;
182
- }
183
- function SecondComponent() {
184
- createQuery(() => ({
185
- queryKey: key,
186
- queryFn: () => {
187
- sleep(10);
188
- return 'data';
189
- },
190
- onSuccess: successFn2,
191
- }));
192
- return <span>second</span>;
193
- }
194
- render(() => (<QueryClientProvider client={queryClient}>
195
- <Suspense fallback="loading">
196
- <FirstComponent />
197
- <SecondComponent />
198
- </Suspense>
199
- ,
200
- </QueryClientProvider>));
201
- await waitFor(() => screen.getByText('second'));
202
- await waitFor(() => expect(successFn1).toHaveBeenCalledTimes(1));
203
- await waitFor(() => expect(successFn2).toHaveBeenCalledTimes(1));
204
- });
205
143
  // https://github.com/tannerlinsley/react-query/issues/468
206
144
  it('should reset error state if new component instances are mounted', async () => {
207
145
  const key = queryKey();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/solid-query",
3
- "version": "5.0.0-alpha.20",
3
+ "version": "5.0.0-alpha.21",
4
4
  "description": "Primitives for managing, caching and syncing asynchronous and remote data in Solid",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -43,7 +43,7 @@
43
43
  "vite-plugin-solid": "^2.3.9"
44
44
  },
45
45
  "dependencies": {
46
- "@tanstack/query-core": "5.0.0-alpha.19"
46
+ "@tanstack/query-core": "5.0.0-alpha.21"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "solid-js": "^1.6.13"
@@ -158,10 +158,6 @@ describe('useQueries', () => {
158
158
  expectTypeNotAny(a)
159
159
  return a.toLowerCase()
160
160
  },
161
- onSuccess: (a) => {
162
- expectType<string>(a)
163
- expectTypeNotAny(a)
164
- },
165
161
  placeholderData: 'string',
166
162
  // @ts-expect-error (initialData: string)
167
163
  initialData: 123,
@@ -174,14 +170,6 @@ describe('useQueries', () => {
174
170
  expectTypeNotAny(a)
175
171
  return parseInt(a)
176
172
  },
177
- onSuccess: (a) => {
178
- expectType<number>(a)
179
- expectTypeNotAny(a)
180
- },
181
- onError: (e) => {
182
- expectType<boolean>(e)
183
- expectTypeNotAny(e)
184
- },
185
173
  placeholderData: 'string',
186
174
  // @ts-expect-error (initialData: string)
187
175
  initialData: 123,
@@ -319,10 +307,6 @@ describe('useQueries', () => {
319
307
  expectTypeNotAny(a)
320
308
  return a.toLowerCase()
321
309
  },
322
- onSuccess: (a) => {
323
- expectType<string>(a)
324
- expectTypeNotAny(a)
325
- },
326
310
  placeholderData: 'string',
327
311
  // @ts-expect-error (initialData: string)
328
312
  initialData: 123,
@@ -335,14 +319,6 @@ describe('useQueries', () => {
335
319
  expectTypeNotAny(a)
336
320
  return parseInt(a)
337
321
  },
338
- onSuccess: (a) => {
339
- expectType<number>(a)
340
- expectTypeNotAny(a)
341
- },
342
- onError: (e) => {
343
- expectType<boolean>(e)
344
- expectTypeNotAny(e)
345
- },
346
322
  placeholderData: 'string',
347
323
  // @ts-expect-error (initialData: string)
348
324
  initialData: 123,
@@ -436,60 +412,38 @@ describe('useQueries', () => {
436
412
  ],
437
413
  }))
438
414
 
439
- // select / onSuccess / onSettled params are "indirectly" enforced
415
+ // select params are "indirectly" enforced
440
416
  createQueries(() => ({
441
417
  queries: [
442
418
  // unfortunately TS will not suggest the type for you
443
419
  {
444
420
  queryKey: key1,
445
421
  queryFn: () => 'string',
446
- // @ts-expect-error (noImplicitAny)
447
- onSuccess: (a) => null,
448
- // @ts-expect-error (noImplicitAny)
449
- onSettled: (a) => null,
450
422
  },
451
423
  // however you can add a type to the callback
452
424
  {
453
425
  queryKey: key2,
454
426
  queryFn: () => 'string',
455
- onSuccess: (a: string) => {
456
- expectType<string>(a)
457
- expectTypeNotAny(a)
458
- },
459
- onSettled: (a: string | undefined) => {
460
- expectType<string | undefined>(a)
461
- expectTypeNotAny(a)
462
- },
463
427
  },
464
428
  // the type you do pass is enforced
465
429
  {
466
430
  queryKey: key3,
467
431
  queryFn: () => 'string',
468
- // @ts-expect-error (only accepts string)
469
- onSuccess: (a: number) => null,
470
432
  },
471
433
  {
472
434
  queryKey: key4,
473
435
  queryFn: () => 'string',
474
436
  select: (a: string) => parseInt(a),
475
- // @ts-expect-error (select is defined => only accepts number)
476
- onSuccess: (a: string) => null,
477
- onSettled: (a: number | undefined) => {
478
- expectType<number | undefined>(a)
479
- expectTypeNotAny(a)
480
- },
481
437
  },
482
438
  ],
483
439
  }))
484
440
 
485
441
  // callbacks are also indirectly enforced with Array.map
486
442
  createQueries(() => ({
487
- // @ts-expect-error (onSuccess only accepts string)
488
443
  queries: Array(50).map((_, i) => ({
489
444
  queryKey: ['key', i] as const,
490
445
  queryFn: () => i + 10,
491
446
  select: (data: number) => data.toString(),
492
- onSuccess: (_data: number) => null,
493
447
  })),
494
448
  }))
495
449
 
@@ -498,7 +452,6 @@ describe('useQueries', () => {
498
452
  queryKey: ['key', i] as const,
499
453
  queryFn: () => i + 10,
500
454
  select: (data: number) => data.toString(),
501
- onSuccess: (_data: string) => null,
502
455
  })),
503
456
  }))
504
457
 
@@ -508,32 +461,15 @@ describe('useQueries', () => {
508
461
  {
509
462
  queryKey: key1,
510
463
  queryFn: () => 'string',
511
- // @ts-expect-error (noImplicitAny)
512
- onSuccess: (a) => null,
513
- // @ts-expect-error (noImplicitAny)
514
- onSettled: (a) => null,
515
464
  },
516
465
  {
517
466
  queryKey: key2,
518
467
  queryFn: () => 'string',
519
- onSuccess: (a: string) => {
520
- expectType<string>(a)
521
- expectTypeNotAny(a)
522
- },
523
- onSettled: (a: string | undefined) => {
524
- expectType<string | undefined>(a)
525
- expectTypeNotAny(a)
526
- },
527
468
  },
528
469
  {
529
470
  queryKey: key4,
530
471
  queryFn: () => 'string',
531
472
  select: (a: string) => parseInt(a),
532
- onSuccess: (_a: number) => null,
533
- onSettled: (a: number | undefined) => {
534
- expectType<number | undefined>(a)
535
- expectTypeNotAny(a)
536
- },
537
473
  },
538
474
  ],
539
475
  }))
@@ -547,12 +483,6 @@ describe('useQueries', () => {
547
483
  {
548
484
  queryKey: key1,
549
485
  queryFn: () => Promise.resolve('string'),
550
- onSuccess: (a: string) => {
551
- expectType<string>(a)
552
- expectTypeNotAny(a)
553
- },
554
- // @ts-expect-error (refuses to accept a Promise)
555
- onSettled: (a: Promise<string>) => null,
556
486
  },
557
487
  ],
558
488
  }))
@@ -658,11 +588,10 @@ describe('useQueries', () => {
658
588
  queries: queries.map(
659
589
  // no need to type the mapped query
660
590
  (query) => {
661
- const { queryFn: fn, queryKey: key, onError: err } = query
591
+ const { queryFn: fn, queryKey: key } = query
662
592
  expectType<QueryFunction<TQueryFnData, TQueryKey> | undefined>(fn)
663
593
  return {
664
594
  queryKey: key,
665
- onError: err,
666
595
  queryFn: fn
667
596
  ? (ctx: QueryFunctionContext<TQueryKey>) => {
668
597
  expectType<TQueryKey>(ctx.queryKey)
@@ -80,21 +80,17 @@ describe('createQuery', () => {
80
80
  createQuery(() => ({
81
81
  queryKey: [key],
82
82
  queryFn: async () => true,
83
- onSuccess: (data) => expectType<boolean>(data),
84
- onSettled: (data) => expectType<boolean | undefined>(data),
85
83
  }))
86
84
 
87
85
  // it should be possible to specify a union type as result type
88
86
  const unionTypeSync = createQuery(() => ({
89
87
  queryKey: key,
90
88
  queryFn: () => (Math.random() > 0.5 ? 'a' : 'b'),
91
- onSuccess: (data) => expectType<'a' | 'b'>(data),
92
89
  }))
93
90
  expectType<'a' | 'b' | undefined>(unionTypeSync.data)
94
91
  const unionTypeAsync = createQuery<'a' | 'b'>(() => ({
95
92
  queryKey: key,
96
93
  queryFn: () => Promise.resolve(Math.random() > 0.5 ? 'a' : 'b'),
97
- onSuccess: (data) => expectType<'a' | 'b'>(data),
98
94
  }))
99
95
  expectType<'a' | 'b' | undefined>(unionTypeAsync.data)
100
96
 
@@ -491,241 +487,6 @@ describe('createQuery', () => {
491
487
  })
492
488
  })
493
489
 
494
- it('should call onSuccess after a query has been fetched', async () => {
495
- const key = queryKey()
496
- const states: CreateQueryResult<string>[] = []
497
- const onSuccess = vi.fn()
498
-
499
- function Page() {
500
- const state = createQuery(() => ({
501
- queryKey: key,
502
- queryFn: async () => {
503
- await sleep(10)
504
- return 'data'
505
- },
506
- onSuccess,
507
- }))
508
- createRenderEffect(() => {
509
- states.push({ ...state })
510
- })
511
- return <div>data: {state.data}</div>
512
- }
513
-
514
- render(() => (
515
- <QueryClientProvider client={queryClient}>
516
- <Page />
517
- </QueryClientProvider>
518
- ))
519
-
520
- await screen.findByText('data: data')
521
- expect(states.length).toBe(2)
522
- expect(onSuccess).toHaveBeenCalledTimes(1)
523
- expect(onSuccess).toHaveBeenCalledWith('data')
524
- })
525
-
526
- it('should call onSuccess after a disabled query has been fetched', async () => {
527
- const key = queryKey()
528
- const states: CreateQueryResult<string>[] = []
529
- const onSuccess = vi.fn()
530
-
531
- function Page() {
532
- const state = createQuery(() => ({
533
- queryKey: key,
534
- queryFn: () => 'data',
535
- enabled: false,
536
- onSuccess,
537
- }))
538
-
539
- createRenderEffect(() => {
540
- states.push({ ...state })
541
- })
542
-
543
- createEffect(() => {
544
- const refetch = state.refetch
545
- setActTimeout(() => {
546
- refetch()
547
- }, 10)
548
- })
549
-
550
- return null
551
- }
552
-
553
- render(() => (
554
- <QueryClientProvider client={queryClient}>
555
- <Page />
556
- </QueryClientProvider>
557
- ))
558
-
559
- await sleep(50)
560
- expect(onSuccess).toHaveBeenCalledTimes(1)
561
- expect(onSuccess).toHaveBeenCalledWith('data')
562
- })
563
-
564
- it('should not call onSuccess if a component has unmounted', async () => {
565
- const key = queryKey()
566
- const states: CreateQueryResult<string>[] = []
567
- const onSuccess = vi.fn()
568
-
569
- function Page() {
570
- const [show, setShow] = createSignal(true)
571
-
572
- createEffect(() => {
573
- setShow(false)
574
- })
575
- return <>{show() && <Component />}</>
576
- }
577
-
578
- function Component() {
579
- const state = createQuery(() => ({
580
- queryKey: key,
581
- queryFn: async () => {
582
- await sleep(10)
583
- return 'data'
584
- },
585
- onSuccess,
586
- }))
587
- createRenderEffect(() => {
588
- states.push({ ...state })
589
- })
590
- return null
591
- }
592
-
593
- render(() => (
594
- <QueryClientProvider client={queryClient}>
595
- <Page />
596
- </QueryClientProvider>
597
- ))
598
-
599
- await sleep(50)
600
- expect(states.length).toBe(1)
601
- expect(onSuccess).toHaveBeenCalledTimes(0)
602
- })
603
-
604
- it('should call onError after a query has been fetched with an error', async () => {
605
- const key = queryKey()
606
- const states: CreateQueryResult<unknown>[] = []
607
- const onError = vi.fn()
608
-
609
- function Page() {
610
- const state = createQuery(() => ({
611
- queryKey: key,
612
- queryFn: () => Promise.reject(new Error('error')),
613
- retry: false,
614
- onError,
615
- }))
616
-
617
- createRenderEffect(() => {
618
- states.push({ ...state })
619
- })
620
-
621
- return null
622
- }
623
-
624
- render(() => (
625
- <QueryClientProvider client={queryClient}>
626
- <Page />
627
- </QueryClientProvider>
628
- ))
629
-
630
- await sleep(10)
631
- expect(states.length).toBe(2)
632
- expect(onError).toHaveBeenCalledTimes(1)
633
- expect(onError).toHaveBeenCalledWith(new Error('error'))
634
- })
635
-
636
- it('should not call onError when receiving a CancelledError', async () => {
637
- const key = queryKey()
638
- const onError = vi.fn()
639
-
640
- function Page() {
641
- const state = createQuery(() => ({
642
- queryKey: key,
643
- queryFn: async () => {
644
- await sleep(10)
645
- return 23
646
- },
647
- onError,
648
- }))
649
- return (
650
- <span>
651
- status: {state.status}, fetchStatus: {state.fetchStatus}
652
- </span>
653
- )
654
- }
655
-
656
- render(() => (
657
- <QueryClientProvider client={queryClient}>
658
- <Page />
659
- </QueryClientProvider>
660
- ))
661
-
662
- await sleep(5)
663
- await queryClient.cancelQueries({ queryKey: key })
664
- // query cancellation will reset the query to it's initial state
665
- await waitFor(() => screen.getByText('status: pending, fetchStatus: idle'))
666
- expect(onError).not.toHaveBeenCalled()
667
- })
668
-
669
- it('should call onSettled after a query has been fetched', async () => {
670
- const key = queryKey()
671
- const states: CreateQueryResult<string>[] = []
672
- const onSettled = vi.fn()
673
-
674
- function Page() {
675
- const state = createQuery(() => ({
676
- queryKey: key,
677
- queryFn: () => 'data',
678
- onSettled,
679
- }))
680
-
681
- createRenderEffect(() => {
682
- states.push({ ...state })
683
- })
684
- return null
685
- }
686
-
687
- render(() => (
688
- <QueryClientProvider client={queryClient}>
689
- <Page />
690
- </QueryClientProvider>
691
- ))
692
-
693
- await sleep(10)
694
- expect(states.length).toBe(2)
695
- expect(onSettled).toHaveBeenCalledTimes(1)
696
- expect(onSettled).toHaveBeenCalledWith('data', null)
697
- })
698
-
699
- it('should call onSettled after a query has been fetched with an error', async () => {
700
- const key = queryKey()
701
- const states: CreateQueryResult<string>[] = []
702
- const onSettled = vi.fn()
703
-
704
- function Page() {
705
- const state = createQuery(() => ({
706
- queryKey: key,
707
- queryFn: () => Promise.reject<unknown>('error'),
708
- retry: false,
709
- onSettled,
710
- }))
711
- createRenderEffect(() => {
712
- states.push({ ...state })
713
- })
714
- return null
715
- }
716
-
717
- render(() => (
718
- <QueryClientProvider client={queryClient}>
719
- <Page />
720
- </QueryClientProvider>
721
- ))
722
-
723
- await sleep(10)
724
- expect(states.length).toBe(2)
725
- expect(onSettled).toHaveBeenCalledTimes(1)
726
- expect(onSettled).toHaveBeenCalledWith(undefined, 'error')
727
- })
728
-
729
490
  it('should not cancel an ongoing fetch when refetch is called with cancelRefetch=false if we have data already', async () => {
730
491
  const key = queryKey()
731
492
  let fetchCount = 0
@@ -2274,56 +2035,6 @@ describe('createQuery', () => {
2274
2035
  expect(renders).toBe(1)
2275
2036
  })
2276
2037
 
2277
- it('should batch re-renders including hook callbacks', async () => {
2278
- const key = queryKey()
2279
-
2280
- let renders = 0
2281
- let callbackCount = 0
2282
-
2283
- const queryFn = async () => {
2284
- await sleep(10)
2285
- return 'data'
2286
- }
2287
-
2288
- function Page() {
2289
- const [count, setCount] = createSignal(0)
2290
- createQuery(() => ({
2291
- queryKey: key,
2292
- queryFn,
2293
- onSuccess: () => {
2294
- setCount((x) => x + 1)
2295
- },
2296
- }))
2297
- createQuery(() => ({
2298
- queryKey: key,
2299
- queryFn,
2300
- onSuccess: () => {
2301
- setCount((x) => x + 1)
2302
- },
2303
- }))
2304
-
2305
- createEffect(() => {
2306
- renders++
2307
- callbackCount = count()
2308
- })
2309
-
2310
- return <div>count: {count()}</div>
2311
- }
2312
-
2313
- render(() => (
2314
- <QueryClientProvider client={queryClient}>
2315
- <Page />
2316
- </QueryClientProvider>
2317
- ))
2318
-
2319
- await waitFor(() => screen.getByText('count: 2'))
2320
-
2321
- // Should be 3 instead of 5
2322
- expect(renders).toBe(3)
2323
- // Both callbacks should have been executed
2324
- expect(callbackCount).toBe(2)
2325
- })
2326
-
2327
2038
  it('should render latest data even if react has discarded certain renders', async () => {
2328
2039
  const key = queryKey()
2329
2040
 
@@ -6107,40 +5818,6 @@ describe('createQuery', () => {
6107
5818
  })
6108
5819
  })
6109
5820
 
6110
- it('setQueryData - should not call onSuccess callback of active observers', async () => {
6111
- const key = queryKey()
6112
- const onSuccess = vi.fn()
6113
-
6114
- function Page() {
6115
- const state = createQuery(() => ({
6116
- queryKey: key,
6117
- queryFn: () => 'data',
6118
- onSuccess,
6119
- }))
6120
- return (
6121
- <div>
6122
- <div>data: {state.data}</div>
6123
- <button onClick={() => queryClient.setQueryData(key, 'newData')}>
6124
- setQueryData
6125
- </button>
6126
- </div>
6127
- )
6128
- }
6129
-
6130
- render(() => (
6131
- <QueryClientProvider client={queryClient}>
6132
- <Page />
6133
- </QueryClientProvider>
6134
- ))
6135
-
6136
- await waitFor(() => screen.getByText('data: data'))
6137
- fireEvent.click(screen.getByRole('button', { name: /setQueryData/i }))
6138
- await waitFor(() => screen.getByText('data: newData'))
6139
-
6140
- expect(onSuccess).toHaveBeenCalledTimes(1)
6141
- expect(onSuccess).toHaveBeenCalledWith('data')
6142
- })
6143
-
6144
5821
  it('setQueryData - should respect updatedAt', async () => {
6145
5822
  const key = queryKey()
6146
5823
 
@@ -217,89 +217,6 @@ describe("useQuery's in Suspense mode", () => {
217
217
  expect(queryCache.find({ queryKey: key })?.getObserversCount()).toBe(0)
218
218
  })
219
219
 
220
- it('should call onSuccess on the first successful call', async () => {
221
- const key = queryKey()
222
-
223
- const successFn = vi.fn()
224
-
225
- function Page() {
226
- createQuery(() => ({
227
- queryKey: [key],
228
- queryFn: async () => {
229
- await sleep(10)
230
- return key
231
- },
232
-
233
- suspense: true,
234
- select: () => 'selected',
235
- onSuccess: successFn,
236
- }))
237
-
238
- return <>rendered</>
239
- }
240
-
241
- render(() => (
242
- <QueryClientProvider client={queryClient}>
243
- <Suspense fallback="loading">
244
- <Page />
245
- </Suspense>
246
- </QueryClientProvider>
247
- ))
248
-
249
- await waitFor(() => screen.getByText('rendered'))
250
-
251
- await waitFor(() => expect(successFn).toHaveBeenCalledTimes(1))
252
- await waitFor(() => expect(successFn).toHaveBeenCalledWith('selected'))
253
- })
254
-
255
- it('should call every onSuccess handler within a suspense boundary', async () => {
256
- const key = queryKey()
257
-
258
- const successFn1 = vi.fn()
259
- const successFn2 = vi.fn()
260
-
261
- function FirstComponent() {
262
- createQuery(() => ({
263
- queryKey: key,
264
- queryFn: () => {
265
- sleep(10)
266
- return 'data'
267
- },
268
- onSuccess: successFn1,
269
- }))
270
-
271
- return <span>first</span>
272
- }
273
-
274
- function SecondComponent() {
275
- createQuery(() => ({
276
- queryKey: key,
277
- queryFn: () => {
278
- sleep(10)
279
- return 'data'
280
- },
281
- onSuccess: successFn2,
282
- }))
283
-
284
- return <span>second</span>
285
- }
286
-
287
- render(() => (
288
- <QueryClientProvider client={queryClient}>
289
- <Suspense fallback="loading">
290
- <FirstComponent />
291
- <SecondComponent />
292
- </Suspense>
293
- ,
294
- </QueryClientProvider>
295
- ))
296
-
297
- await waitFor(() => screen.getByText('second'))
298
-
299
- await waitFor(() => expect(successFn1).toHaveBeenCalledTimes(1))
300
- await waitFor(() => expect(successFn2).toHaveBeenCalledTimes(1))
301
- })
302
-
303
220
  // https://github.com/tannerlinsley/react-query/issues/468
304
221
  it('should reset error state if new component instances are mounted', async () => {
305
222
  const key = queryKey()