@tanstack/solid-query 5.0.0-alpha.6 → 5.0.0-alpha.62
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/cjs/index.js → dist/cjs/index.cjs} +91 -31
- package/dist/cjs/index.cjs.map +1 -0
- package/{build → dist}/esm/index.js +91 -33
- package/dist/esm/index.js.map +1 -0
- package/dist/source/QueryClient.js +6 -0
- package/{build → dist}/source/createBaseQuery.js +49 -23
- package/{build → dist}/source/createMutation.js +1 -1
- package/{build → dist}/source/createQueries.js +13 -7
- package/{build → dist}/source/createQuery.js +3 -0
- package/{build → dist}/source/index.js +2 -1
- package/dist/types/QueryClient.d.ts +29 -0
- package/{build → dist}/types/QueryClientProvider.d.ts +3 -3
- package/{build → dist}/types/createBaseQuery.d.ts +2 -1
- package/{build → dist}/types/createInfiniteQuery.d.ts +2 -1
- package/{build → dist}/types/createMutation.d.ts +2 -1
- package/{build → dist}/types/createQueries.d.ts +11 -9
- package/dist/types/createQuery.d.ts +14 -0
- package/{build → dist}/types/index.d.ts +3 -1
- package/dist/types/types.d.ts +34 -0
- package/{build → dist}/types/useIsFetching.d.ts +2 -1
- package/{build → dist}/types/useIsMutating.d.ts +2 -1
- package/package.json +22 -26
- package/src/QueryClient.ts +84 -0
- package/src/QueryClientProvider.tsx +1 -1
- package/src/__tests__/QueryClientProvider.test.tsx +2 -3
- package/src/__tests__/createInfiniteQuery.test.tsx +83 -19
- package/src/__tests__/createMutation.test.tsx +5 -5
- package/src/__tests__/createQueries.test.tsx +6 -78
- package/src/__tests__/createQuery.test.tsx +66 -334
- package/src/__tests__/createQuery.types.test.tsx +21 -1
- package/src/__tests__/suspense.test.tsx +7 -90
- package/src/__tests__/transition.test.tsx +1 -1
- package/src/__tests__/useIsFetching.test.tsx +1 -1
- package/src/__tests__/useIsMutating.test.tsx +5 -7
- package/src/__tests__/utils.tsx +1 -1
- package/src/createBaseQuery.ts +73 -28
- package/src/createInfiniteQuery.ts +1 -1
- package/src/createMutation.ts +3 -2
- package/src/createQueries.ts +32 -14
- package/src/createQuery.ts +24 -1
- package/src/index.ts +8 -1
- package/src/types.ts +4 -2
- package/src/useIsFetching.ts +2 -1
- package/src/useIsMutating.ts +2 -1
- package/build/cjs/index.js.map +0 -1
- package/build/esm/index.js.map +0 -1
- package/build/source/__tests__/QueryClientProvider.test.jsx +0 -121
- package/build/source/__tests__/createInfiniteQuery.test.jsx +0 -1315
- package/build/source/__tests__/createMutation.test.jsx +0 -867
- package/build/source/__tests__/createQueries.test.jsx +0 -661
- package/build/source/__tests__/createQuery.test.jsx +0 -4608
- package/build/source/__tests__/createQuery.types.test.jsx +0 -135
- package/build/source/__tests__/suspense.test.jsx +0 -721
- package/build/source/__tests__/transition.test.jsx +0 -42
- package/build/source/__tests__/useIsFetching.test.jsx +0 -190
- package/build/source/__tests__/useIsMutating.test.jsx +0 -198
- package/build/source/__tests__/utils.jsx +0 -50
- package/build/types/__tests__/QueryClientProvider.test.d.ts +0 -1
- package/build/types/__tests__/createInfiniteQuery.test.d.ts +0 -1
- package/build/types/__tests__/createMutation.test.d.ts +0 -1
- package/build/types/__tests__/createQueries.test.d.ts +0 -1
- package/build/types/__tests__/createQuery.test.d.ts +0 -1
- package/build/types/__tests__/createQuery.types.test.d.ts +0 -2
- package/build/types/__tests__/suspense.test.d.ts +0 -1
- package/build/types/__tests__/transition.test.d.ts +0 -1
- package/build/types/__tests__/useIsFetching.test.d.ts +0 -1
- package/build/types/__tests__/useIsMutating.test.d.ts +0 -1
- package/build/types/__tests__/utils.d.ts +0 -21
- package/build/types/createQuery.d.ts +0 -11
- package/build/types/types.d.ts +0 -33
- package/build/umd/index.js +0 -2
- package/build/umd/index.js.map +0 -1
- /package/{build → dist}/source/QueryClientProvider.jsx +0 -0
- /package/{build → dist}/source/createInfiniteQuery.js +0 -0
- /package/{build → dist}/source/setBatchUpdatesFn.js +0 -0
- /package/{build → dist}/source/types.js +0 -0
- /package/{build → dist}/source/useIsFetching.js +0 -0
- /package/{build → dist}/source/useIsMutating.js +0 -0
- /package/{build → dist}/source/utils.js +0 -0
- /package/{build → dist}/types/setBatchUpdatesFn.d.ts +0 -0
- /package/{build → dist}/types/utils.d.ts +0 -0
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
on,
|
|
11
11
|
Switch,
|
|
12
12
|
} from 'solid-js'
|
|
13
|
-
import { fireEvent, render, screen, waitFor } from '
|
|
13
|
+
import { fireEvent, render, screen, waitFor } from '@solidjs/testing-library'
|
|
14
14
|
import type {
|
|
15
15
|
CreateQueryOptions,
|
|
16
16
|
CreateQueryResult,
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
} from './utils'
|
|
36
36
|
import { vi } from 'vitest'
|
|
37
37
|
import type { Mock } from 'vitest'
|
|
38
|
+
import { reconcile } from 'solid-js/store'
|
|
38
39
|
|
|
39
40
|
describe('createQuery', () => {
|
|
40
41
|
const queryCache = new QueryCache()
|
|
@@ -79,21 +80,17 @@ describe('createQuery', () => {
|
|
|
79
80
|
createQuery(() => ({
|
|
80
81
|
queryKey: [key],
|
|
81
82
|
queryFn: async () => true,
|
|
82
|
-
onSuccess: (data) => expectType<boolean>(data),
|
|
83
|
-
onSettled: (data) => expectType<boolean | undefined>(data),
|
|
84
83
|
}))
|
|
85
84
|
|
|
86
85
|
// it should be possible to specify a union type as result type
|
|
87
86
|
const unionTypeSync = createQuery(() => ({
|
|
88
87
|
queryKey: key,
|
|
89
88
|
queryFn: () => (Math.random() > 0.5 ? 'a' : 'b'),
|
|
90
|
-
onSuccess: (data) => expectType<'a' | 'b'>(data),
|
|
91
89
|
}))
|
|
92
90
|
expectType<'a' | 'b' | undefined>(unionTypeSync.data)
|
|
93
91
|
const unionTypeAsync = createQuery<'a' | 'b'>(() => ({
|
|
94
92
|
queryKey: key,
|
|
95
93
|
queryFn: () => Promise.resolve(Math.random() > 0.5 ? 'a' : 'b'),
|
|
96
|
-
onSuccess: (data) => expectType<'a' | 'b'>(data),
|
|
97
94
|
}))
|
|
98
95
|
expectType<'a' | 'b' | undefined>(unionTypeAsync.data)
|
|
99
96
|
|
|
@@ -490,241 +487,6 @@ describe('createQuery', () => {
|
|
|
490
487
|
})
|
|
491
488
|
})
|
|
492
489
|
|
|
493
|
-
it('should call onSuccess after a query has been fetched', async () => {
|
|
494
|
-
const key = queryKey()
|
|
495
|
-
const states: CreateQueryResult<string>[] = []
|
|
496
|
-
const onSuccess = vi.fn()
|
|
497
|
-
|
|
498
|
-
function Page() {
|
|
499
|
-
const state = createQuery(() => ({
|
|
500
|
-
queryKey: key,
|
|
501
|
-
queryFn: async () => {
|
|
502
|
-
await sleep(10)
|
|
503
|
-
return 'data'
|
|
504
|
-
},
|
|
505
|
-
onSuccess,
|
|
506
|
-
}))
|
|
507
|
-
createRenderEffect(() => {
|
|
508
|
-
states.push({ ...state })
|
|
509
|
-
})
|
|
510
|
-
return <div>data: {state.data}</div>
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
render(() => (
|
|
514
|
-
<QueryClientProvider client={queryClient}>
|
|
515
|
-
<Page />
|
|
516
|
-
</QueryClientProvider>
|
|
517
|
-
))
|
|
518
|
-
|
|
519
|
-
await screen.findByText('data: data')
|
|
520
|
-
expect(states.length).toBe(2)
|
|
521
|
-
expect(onSuccess).toHaveBeenCalledTimes(1)
|
|
522
|
-
expect(onSuccess).toHaveBeenCalledWith('data')
|
|
523
|
-
})
|
|
524
|
-
|
|
525
|
-
it('should call onSuccess after a disabled query has been fetched', async () => {
|
|
526
|
-
const key = queryKey()
|
|
527
|
-
const states: CreateQueryResult<string>[] = []
|
|
528
|
-
const onSuccess = vi.fn()
|
|
529
|
-
|
|
530
|
-
function Page() {
|
|
531
|
-
const state = createQuery(() => ({
|
|
532
|
-
queryKey: key,
|
|
533
|
-
queryFn: () => 'data',
|
|
534
|
-
enabled: false,
|
|
535
|
-
onSuccess,
|
|
536
|
-
}))
|
|
537
|
-
|
|
538
|
-
createRenderEffect(() => {
|
|
539
|
-
states.push({ ...state })
|
|
540
|
-
})
|
|
541
|
-
|
|
542
|
-
createEffect(() => {
|
|
543
|
-
const refetch = state.refetch
|
|
544
|
-
setActTimeout(() => {
|
|
545
|
-
refetch()
|
|
546
|
-
}, 10)
|
|
547
|
-
})
|
|
548
|
-
|
|
549
|
-
return null
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
render(() => (
|
|
553
|
-
<QueryClientProvider client={queryClient}>
|
|
554
|
-
<Page />
|
|
555
|
-
</QueryClientProvider>
|
|
556
|
-
))
|
|
557
|
-
|
|
558
|
-
await sleep(50)
|
|
559
|
-
expect(onSuccess).toHaveBeenCalledTimes(1)
|
|
560
|
-
expect(onSuccess).toHaveBeenCalledWith('data')
|
|
561
|
-
})
|
|
562
|
-
|
|
563
|
-
it('should not call onSuccess if a component has unmounted', async () => {
|
|
564
|
-
const key = queryKey()
|
|
565
|
-
const states: CreateQueryResult<string>[] = []
|
|
566
|
-
const onSuccess = vi.fn()
|
|
567
|
-
|
|
568
|
-
function Page() {
|
|
569
|
-
const [show, setShow] = createSignal(true)
|
|
570
|
-
|
|
571
|
-
createEffect(() => {
|
|
572
|
-
setShow(false)
|
|
573
|
-
})
|
|
574
|
-
return <>{show() && <Component />}</>
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
function Component() {
|
|
578
|
-
const state = createQuery(() => ({
|
|
579
|
-
queryKey: key,
|
|
580
|
-
queryFn: async () => {
|
|
581
|
-
await sleep(10)
|
|
582
|
-
return 'data'
|
|
583
|
-
},
|
|
584
|
-
onSuccess,
|
|
585
|
-
}))
|
|
586
|
-
createRenderEffect(() => {
|
|
587
|
-
states.push({ ...state })
|
|
588
|
-
})
|
|
589
|
-
return null
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
render(() => (
|
|
593
|
-
<QueryClientProvider client={queryClient}>
|
|
594
|
-
<Page />
|
|
595
|
-
</QueryClientProvider>
|
|
596
|
-
))
|
|
597
|
-
|
|
598
|
-
await sleep(50)
|
|
599
|
-
expect(states.length).toBe(1)
|
|
600
|
-
expect(onSuccess).toHaveBeenCalledTimes(0)
|
|
601
|
-
})
|
|
602
|
-
|
|
603
|
-
it('should call onError after a query has been fetched with an error', async () => {
|
|
604
|
-
const key = queryKey()
|
|
605
|
-
const states: CreateQueryResult<unknown>[] = []
|
|
606
|
-
const onError = vi.fn()
|
|
607
|
-
|
|
608
|
-
function Page() {
|
|
609
|
-
const state = createQuery(() => ({
|
|
610
|
-
queryKey: key,
|
|
611
|
-
queryFn: () => Promise.reject(new Error('error')),
|
|
612
|
-
retry: false,
|
|
613
|
-
onError,
|
|
614
|
-
}))
|
|
615
|
-
|
|
616
|
-
createRenderEffect(() => {
|
|
617
|
-
states.push({ ...state })
|
|
618
|
-
})
|
|
619
|
-
|
|
620
|
-
return null
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
render(() => (
|
|
624
|
-
<QueryClientProvider client={queryClient}>
|
|
625
|
-
<Page />
|
|
626
|
-
</QueryClientProvider>
|
|
627
|
-
))
|
|
628
|
-
|
|
629
|
-
await sleep(10)
|
|
630
|
-
expect(states.length).toBe(2)
|
|
631
|
-
expect(onError).toHaveBeenCalledTimes(1)
|
|
632
|
-
expect(onError).toHaveBeenCalledWith(new Error('error'))
|
|
633
|
-
})
|
|
634
|
-
|
|
635
|
-
it('should not call onError when receiving a CancelledError', async () => {
|
|
636
|
-
const key = queryKey()
|
|
637
|
-
const onError = vi.fn()
|
|
638
|
-
|
|
639
|
-
function Page() {
|
|
640
|
-
const state = createQuery(() => ({
|
|
641
|
-
queryKey: key,
|
|
642
|
-
queryFn: async () => {
|
|
643
|
-
await sleep(10)
|
|
644
|
-
return 23
|
|
645
|
-
},
|
|
646
|
-
onError,
|
|
647
|
-
}))
|
|
648
|
-
return (
|
|
649
|
-
<span>
|
|
650
|
-
status: {state.status}, fetchStatus: {state.fetchStatus}
|
|
651
|
-
</span>
|
|
652
|
-
)
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
render(() => (
|
|
656
|
-
<QueryClientProvider client={queryClient}>
|
|
657
|
-
<Page />
|
|
658
|
-
</QueryClientProvider>
|
|
659
|
-
))
|
|
660
|
-
|
|
661
|
-
await sleep(5)
|
|
662
|
-
await queryClient.cancelQueries({ queryKey: key })
|
|
663
|
-
// query cancellation will reset the query to it's initial state
|
|
664
|
-
await waitFor(() => screen.getByText('status: pending, fetchStatus: idle'))
|
|
665
|
-
expect(onError).not.toHaveBeenCalled()
|
|
666
|
-
})
|
|
667
|
-
|
|
668
|
-
it('should call onSettled after a query has been fetched', async () => {
|
|
669
|
-
const key = queryKey()
|
|
670
|
-
const states: CreateQueryResult<string>[] = []
|
|
671
|
-
const onSettled = vi.fn()
|
|
672
|
-
|
|
673
|
-
function Page() {
|
|
674
|
-
const state = createQuery(() => ({
|
|
675
|
-
queryKey: key,
|
|
676
|
-
queryFn: () => 'data',
|
|
677
|
-
onSettled,
|
|
678
|
-
}))
|
|
679
|
-
|
|
680
|
-
createRenderEffect(() => {
|
|
681
|
-
states.push({ ...state })
|
|
682
|
-
})
|
|
683
|
-
return null
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
render(() => (
|
|
687
|
-
<QueryClientProvider client={queryClient}>
|
|
688
|
-
<Page />
|
|
689
|
-
</QueryClientProvider>
|
|
690
|
-
))
|
|
691
|
-
|
|
692
|
-
await sleep(10)
|
|
693
|
-
expect(states.length).toBe(2)
|
|
694
|
-
expect(onSettled).toHaveBeenCalledTimes(1)
|
|
695
|
-
expect(onSettled).toHaveBeenCalledWith('data', null)
|
|
696
|
-
})
|
|
697
|
-
|
|
698
|
-
it('should call onSettled after a query has been fetched with an error', async () => {
|
|
699
|
-
const key = queryKey()
|
|
700
|
-
const states: CreateQueryResult<string>[] = []
|
|
701
|
-
const onSettled = vi.fn()
|
|
702
|
-
|
|
703
|
-
function Page() {
|
|
704
|
-
const state = createQuery(() => ({
|
|
705
|
-
queryKey: key,
|
|
706
|
-
queryFn: () => Promise.reject<unknown>('error'),
|
|
707
|
-
retry: false,
|
|
708
|
-
onSettled,
|
|
709
|
-
}))
|
|
710
|
-
createRenderEffect(() => {
|
|
711
|
-
states.push({ ...state })
|
|
712
|
-
})
|
|
713
|
-
return null
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
render(() => (
|
|
717
|
-
<QueryClientProvider client={queryClient}>
|
|
718
|
-
<Page />
|
|
719
|
-
</QueryClientProvider>
|
|
720
|
-
))
|
|
721
|
-
|
|
722
|
-
await sleep(10)
|
|
723
|
-
expect(states.length).toBe(2)
|
|
724
|
-
expect(onSettled).toHaveBeenCalledTimes(1)
|
|
725
|
-
expect(onSettled).toHaveBeenCalledWith(undefined, 'error')
|
|
726
|
-
})
|
|
727
|
-
|
|
728
490
|
it('should not cancel an ongoing fetch when refetch is called with cancelRefetch=false if we have data already', async () => {
|
|
729
491
|
const key = queryKey()
|
|
730
492
|
let fetchCount = 0
|
|
@@ -1282,7 +1044,6 @@ describe('createQuery', () => {
|
|
|
1282
1044
|
count++
|
|
1283
1045
|
return count === 1 ? result1 : result2
|
|
1284
1046
|
},
|
|
1285
|
-
notifyOnChangeProps: 'all',
|
|
1286
1047
|
}))
|
|
1287
1048
|
|
|
1288
1049
|
createRenderEffect(() => {
|
|
@@ -1322,9 +1083,8 @@ describe('createQuery', () => {
|
|
|
1322
1083
|
|
|
1323
1084
|
expect(todos).toEqual(result1)
|
|
1324
1085
|
expect(newTodos).toEqual(result2)
|
|
1325
|
-
expect(newTodos).not.toBe(todos)
|
|
1326
1086
|
expect(newTodo1).toBe(todo1)
|
|
1327
|
-
expect(newTodo2).
|
|
1087
|
+
expect(newTodo2).toBe(todo2)
|
|
1328
1088
|
|
|
1329
1089
|
return null
|
|
1330
1090
|
})
|
|
@@ -2275,56 +2035,6 @@ describe('createQuery', () => {
|
|
|
2275
2035
|
expect(renders).toBe(1)
|
|
2276
2036
|
})
|
|
2277
2037
|
|
|
2278
|
-
it('should batch re-renders including hook callbacks', async () => {
|
|
2279
|
-
const key = queryKey()
|
|
2280
|
-
|
|
2281
|
-
let renders = 0
|
|
2282
|
-
let callbackCount = 0
|
|
2283
|
-
|
|
2284
|
-
const queryFn = async () => {
|
|
2285
|
-
await sleep(10)
|
|
2286
|
-
return 'data'
|
|
2287
|
-
}
|
|
2288
|
-
|
|
2289
|
-
function Page() {
|
|
2290
|
-
const [count, setCount] = createSignal(0)
|
|
2291
|
-
createQuery(() => ({
|
|
2292
|
-
queryKey: key,
|
|
2293
|
-
queryFn,
|
|
2294
|
-
onSuccess: () => {
|
|
2295
|
-
setCount((x) => x + 1)
|
|
2296
|
-
},
|
|
2297
|
-
}))
|
|
2298
|
-
createQuery(() => ({
|
|
2299
|
-
queryKey: key,
|
|
2300
|
-
queryFn,
|
|
2301
|
-
onSuccess: () => {
|
|
2302
|
-
setCount((x) => x + 1)
|
|
2303
|
-
},
|
|
2304
|
-
}))
|
|
2305
|
-
|
|
2306
|
-
createEffect(() => {
|
|
2307
|
-
renders++
|
|
2308
|
-
callbackCount = count()
|
|
2309
|
-
})
|
|
2310
|
-
|
|
2311
|
-
return <div>count: {count()}</div>
|
|
2312
|
-
}
|
|
2313
|
-
|
|
2314
|
-
render(() => (
|
|
2315
|
-
<QueryClientProvider client={queryClient}>
|
|
2316
|
-
<Page />
|
|
2317
|
-
</QueryClientProvider>
|
|
2318
|
-
))
|
|
2319
|
-
|
|
2320
|
-
await waitFor(() => screen.getByText('count: 2'))
|
|
2321
|
-
|
|
2322
|
-
// Should be 3 instead of 5
|
|
2323
|
-
expect(renders).toBe(3)
|
|
2324
|
-
// Both callbacks should have been executed
|
|
2325
|
-
expect(callbackCount).toBe(2)
|
|
2326
|
-
})
|
|
2327
|
-
|
|
2328
2038
|
it('should render latest data even if react has discarded certain renders', async () => {
|
|
2329
2039
|
const key = queryKey()
|
|
2330
2040
|
|
|
@@ -2796,7 +2506,7 @@ describe('createQuery', () => {
|
|
|
2796
2506
|
await waitFor(() => screen.getByText('Error test jaylen'))
|
|
2797
2507
|
})
|
|
2798
2508
|
|
|
2799
|
-
it('should throw error if queryFn throws and
|
|
2509
|
+
it('should throw error if queryFn throws and throwOnError is in use', async () => {
|
|
2800
2510
|
const key = queryKey()
|
|
2801
2511
|
|
|
2802
2512
|
function Page() {
|
|
@@ -2804,7 +2514,7 @@ describe('createQuery', () => {
|
|
|
2804
2514
|
queryKey: key,
|
|
2805
2515
|
queryFn: () => Promise.reject(new Error('Error test jaylen')),
|
|
2806
2516
|
retry: false,
|
|
2807
|
-
|
|
2517
|
+
throwOnError: true,
|
|
2808
2518
|
}))
|
|
2809
2519
|
|
|
2810
2520
|
return (
|
|
@@ -2826,7 +2536,7 @@ describe('createQuery', () => {
|
|
|
2826
2536
|
await waitFor(() => screen.getByText('error boundary'))
|
|
2827
2537
|
})
|
|
2828
2538
|
|
|
2829
|
-
it('should update with data if we observe no properties and
|
|
2539
|
+
it('should update with data if we observe no properties and throwOnError', async () => {
|
|
2830
2540
|
const key = queryKey()
|
|
2831
2541
|
|
|
2832
2542
|
let result: CreateQueryResult<string> | undefined
|
|
@@ -2835,7 +2545,7 @@ describe('createQuery', () => {
|
|
|
2835
2545
|
const query = createQuery(() => ({
|
|
2836
2546
|
queryKey: key,
|
|
2837
2547
|
queryFn: () => Promise.resolve('data'),
|
|
2838
|
-
|
|
2548
|
+
throwOnError: true,
|
|
2839
2549
|
}))
|
|
2840
2550
|
|
|
2841
2551
|
createEffect(() => {
|
|
@@ -2864,7 +2574,7 @@ describe('createQuery', () => {
|
|
|
2864
2574
|
queryKey: key,
|
|
2865
2575
|
queryFn: () => Promise.reject(new Error('Local Error')),
|
|
2866
2576
|
retry: false,
|
|
2867
|
-
|
|
2577
|
+
throwOnError: (err) => err.message !== 'Local Error',
|
|
2868
2578
|
}))
|
|
2869
2579
|
|
|
2870
2580
|
return (
|
|
@@ -2895,7 +2605,7 @@ describe('createQuery', () => {
|
|
|
2895
2605
|
queryKey: key,
|
|
2896
2606
|
queryFn: () => Promise.reject(new Error('Remote Error')),
|
|
2897
2607
|
retry: false,
|
|
2898
|
-
|
|
2608
|
+
throwOnError: (err) => err.message !== 'Local Error',
|
|
2899
2609
|
}))
|
|
2900
2610
|
|
|
2901
2611
|
return (
|
|
@@ -3257,7 +2967,7 @@ describe('createQuery', () => {
|
|
|
3257
2967
|
|
|
3258
2968
|
it('should keep initial data when the query key changes', async () => {
|
|
3259
2969
|
const key = queryKey()
|
|
3260
|
-
const states: DefinedCreateQueryResult<{ count: number }
|
|
2970
|
+
const states: Partial<DefinedCreateQueryResult<{ count: number }>>[] = []
|
|
3261
2971
|
|
|
3262
2972
|
function Page() {
|
|
3263
2973
|
const [count, setCount] = createSignal(0)
|
|
@@ -3266,6 +2976,7 @@ describe('createQuery', () => {
|
|
|
3266
2976
|
queryFn: () => ({ count: 10 }),
|
|
3267
2977
|
staleTime: Infinity,
|
|
3268
2978
|
initialData: () => ({ count: count() }),
|
|
2979
|
+
reconcile: false,
|
|
3269
2980
|
}))
|
|
3270
2981
|
createRenderEffect(() => {
|
|
3271
2982
|
states.push({ ...state })
|
|
@@ -4610,6 +4321,61 @@ describe('createQuery', () => {
|
|
|
4610
4321
|
expect(states).toHaveLength(1)
|
|
4611
4322
|
})
|
|
4612
4323
|
|
|
4324
|
+
it('The reconcile fn callback should correctly maintain referential equality', async () => {
|
|
4325
|
+
const key1 = queryKey()
|
|
4326
|
+
const states: Array<Array<number>> = []
|
|
4327
|
+
|
|
4328
|
+
function Page() {
|
|
4329
|
+
const [forceValue, setForceValue] = createSignal(1)
|
|
4330
|
+
|
|
4331
|
+
const state = createQuery(() => ({
|
|
4332
|
+
queryKey: key1,
|
|
4333
|
+
queryFn: async () => {
|
|
4334
|
+
await sleep(10)
|
|
4335
|
+
return [1, 2]
|
|
4336
|
+
},
|
|
4337
|
+
select: (res) => res.map((x) => x + 1),
|
|
4338
|
+
reconcile(oldData, newData) {
|
|
4339
|
+
return reconcile(newData)(oldData)
|
|
4340
|
+
},
|
|
4341
|
+
}))
|
|
4342
|
+
|
|
4343
|
+
createEffect(() => {
|
|
4344
|
+
if (state.data) {
|
|
4345
|
+
states.push(state.data)
|
|
4346
|
+
}
|
|
4347
|
+
})
|
|
4348
|
+
|
|
4349
|
+
const forceUpdate = () => {
|
|
4350
|
+
setForceValue((prev) => prev + 1)
|
|
4351
|
+
}
|
|
4352
|
+
|
|
4353
|
+
return (
|
|
4354
|
+
<div>
|
|
4355
|
+
<h2>Data: {JSON.stringify(state.data)}</h2>
|
|
4356
|
+
<h2>forceValue: {forceValue}</h2>
|
|
4357
|
+
<button onClick={forceUpdate}>forceUpdate</button>
|
|
4358
|
+
</div>
|
|
4359
|
+
)
|
|
4360
|
+
}
|
|
4361
|
+
|
|
4362
|
+
render(() => (
|
|
4363
|
+
<QueryClientProvider client={queryClient}>
|
|
4364
|
+
<Page />
|
|
4365
|
+
</QueryClientProvider>
|
|
4366
|
+
))
|
|
4367
|
+
await waitFor(() => screen.getByText('Data: [2,3]'))
|
|
4368
|
+
expect(states).toHaveLength(1)
|
|
4369
|
+
|
|
4370
|
+
fireEvent.click(screen.getByRole('button', { name: /forceUpdate/i }))
|
|
4371
|
+
|
|
4372
|
+
await waitFor(() => screen.getByText('forceValue: 2'))
|
|
4373
|
+
await waitFor(() => screen.getByText('Data: [2,3]'))
|
|
4374
|
+
|
|
4375
|
+
// effect should not be triggered again due to structural sharing
|
|
4376
|
+
expect(states).toHaveLength(1)
|
|
4377
|
+
})
|
|
4378
|
+
|
|
4613
4379
|
it('should cancel the query function when there are no more subscriptions', async () => {
|
|
4614
4380
|
const key = queryKey()
|
|
4615
4381
|
let cancelFn: Mock = vi.fn()
|
|
@@ -6052,40 +5818,6 @@ describe('createQuery', () => {
|
|
|
6052
5818
|
})
|
|
6053
5819
|
})
|
|
6054
5820
|
|
|
6055
|
-
it('setQueryData - should not call onSuccess callback of active observers', async () => {
|
|
6056
|
-
const key = queryKey()
|
|
6057
|
-
const onSuccess = vi.fn()
|
|
6058
|
-
|
|
6059
|
-
function Page() {
|
|
6060
|
-
const state = createQuery(() => ({
|
|
6061
|
-
queryKey: key,
|
|
6062
|
-
queryFn: () => 'data',
|
|
6063
|
-
onSuccess,
|
|
6064
|
-
}))
|
|
6065
|
-
return (
|
|
6066
|
-
<div>
|
|
6067
|
-
<div>data: {state.data}</div>
|
|
6068
|
-
<button onClick={() => queryClient.setQueryData(key, 'newData')}>
|
|
6069
|
-
setQueryData
|
|
6070
|
-
</button>
|
|
6071
|
-
</div>
|
|
6072
|
-
)
|
|
6073
|
-
}
|
|
6074
|
-
|
|
6075
|
-
render(() => (
|
|
6076
|
-
<QueryClientProvider client={queryClient}>
|
|
6077
|
-
<Page />
|
|
6078
|
-
</QueryClientProvider>
|
|
6079
|
-
))
|
|
6080
|
-
|
|
6081
|
-
await waitFor(() => screen.getByText('data: data'))
|
|
6082
|
-
fireEvent.click(screen.getByRole('button', { name: /setQueryData/i }))
|
|
6083
|
-
await waitFor(() => screen.getByText('data: newData'))
|
|
6084
|
-
|
|
6085
|
-
expect(onSuccess).toHaveBeenCalledTimes(1)
|
|
6086
|
-
expect(onSuccess).toHaveBeenCalledWith('data')
|
|
6087
|
-
})
|
|
6088
|
-
|
|
6089
5821
|
it('setQueryData - should respect updatedAt', async () => {
|
|
6090
5822
|
const key = queryKey()
|
|
6091
5823
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createQuery } from '../index'
|
|
1
|
+
import { createQuery, queryOptions } from '../index'
|
|
2
2
|
|
|
3
3
|
export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <
|
|
4
4
|
T,
|
|
@@ -31,6 +31,26 @@ describe('initialData', () => {
|
|
|
31
31
|
})
|
|
32
32
|
})
|
|
33
33
|
|
|
34
|
+
it('TData should be defined when passed through queryOptions', () => {
|
|
35
|
+
doNotExecute(() => {
|
|
36
|
+
const options = queryOptions(() => ({
|
|
37
|
+
queryKey: ['key'],
|
|
38
|
+
queryFn: () => {
|
|
39
|
+
return {
|
|
40
|
+
wow: true,
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
initialData: {
|
|
44
|
+
wow: true,
|
|
45
|
+
},
|
|
46
|
+
}))
|
|
47
|
+
const { data } = createQuery(options)
|
|
48
|
+
|
|
49
|
+
const result: Expect<Equal<{ wow: boolean }, typeof data>> = true
|
|
50
|
+
return result
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
34
54
|
it('TData should always be defined when initialData is provided as a function which ALWAYS returns the data', () => {
|
|
35
55
|
doNotExecute(() => {
|
|
36
56
|
const { data } = createQuery(() => ({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fireEvent, render, screen, waitFor } from '
|
|
1
|
+
import { fireEvent, render, screen, waitFor } from '@solidjs/testing-library'
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
createRenderEffect,
|
|
@@ -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()
|
|
@@ -582,7 +499,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
582
499
|
await waitFor(() => screen.getByText('error boundary'))
|
|
583
500
|
})
|
|
584
501
|
|
|
585
|
-
it('should not throw errors to the error boundary when
|
|
502
|
+
it('should not throw errors to the error boundary when throwOnError: false', async () => {
|
|
586
503
|
const key = queryKey()
|
|
587
504
|
|
|
588
505
|
function Page() {
|
|
@@ -593,7 +510,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
593
510
|
throw new Error('Suspense Error a2x')
|
|
594
511
|
},
|
|
595
512
|
retry: false,
|
|
596
|
-
|
|
513
|
+
throwOnError: false,
|
|
597
514
|
}))
|
|
598
515
|
|
|
599
516
|
// read state.data to trigger suspense.
|
|
@@ -631,7 +548,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
631
548
|
await waitFor(() => screen.getByText('rendered'))
|
|
632
549
|
})
|
|
633
550
|
|
|
634
|
-
it('should throw errors to the error boundary when a
|
|
551
|
+
it('should throw errors to the error boundary when a throwOnError function returns true', async () => {
|
|
635
552
|
const key = queryKey()
|
|
636
553
|
|
|
637
554
|
function Page() {
|
|
@@ -642,7 +559,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
642
559
|
return Promise.reject(new Error('Remote Error'))
|
|
643
560
|
},
|
|
644
561
|
retry: false,
|
|
645
|
-
|
|
562
|
+
throwOnError: (err) => err.message !== 'Local Error',
|
|
646
563
|
}))
|
|
647
564
|
|
|
648
565
|
// read state.data to trigger suspense.
|
|
@@ -680,7 +597,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
680
597
|
await waitFor(() => screen.getByText('error boundary'))
|
|
681
598
|
})
|
|
682
599
|
|
|
683
|
-
it('should not throw errors to the error boundary when a
|
|
600
|
+
it('should not throw errors to the error boundary when a throwOnError function returns false', async () => {
|
|
684
601
|
const key = queryKey()
|
|
685
602
|
|
|
686
603
|
function Page() {
|
|
@@ -693,7 +610,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
693
610
|
|
|
694
611
|
retry: false,
|
|
695
612
|
suspense: true,
|
|
696
|
-
|
|
613
|
+
throwOnError: (err) => err.message !== 'Local Error',
|
|
697
614
|
}))
|
|
698
615
|
|
|
699
616
|
// read state.data to trigger suspense.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fireEvent, render, screen, waitFor } from '
|
|
1
|
+
import { fireEvent, render, screen, waitFor } from '@solidjs/testing-library'
|
|
2
2
|
|
|
3
3
|
import { createSignal, Show, startTransition, Suspense } from 'solid-js'
|
|
4
4
|
import { createQuery, QueryCache, QueryClientProvider } from '..'
|