@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.
- package/build/source/__tests__/createQueries.test.jsx +2 -73
- package/build/source/__tests__/createQuery.test.jsx +0 -251
- package/build/source/__tests__/suspense.test.jsx +0 -62
- package/package.json +2 -2
- package/src/__tests__/createQueries.test.tsx +2 -73
- package/src/__tests__/createQuery.test.tsx +0 -323
- package/src/__tests__/suspense.test.tsx +0 -83
|
@@ -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
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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()
|