@tanstack/solid-query 5.0.0-alpha.19 → 5.0.0-alpha.20
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 +35 -6
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.js +37 -9
- package/build/esm/index.js.map +1 -1
- package/build/source/QueryClient.js +6 -0
- package/build/source/__tests__/createInfiniteQuery.test.jsx +56 -10
- package/build/source/__tests__/createQuery.test.jsx +44 -3
- package/build/source/__tests__/utils.jsx +1 -1
- package/build/source/createBaseQuery.js +22 -7
- package/build/source/index.js +1 -0
- package/build/types/QueryClient.d.ts +29 -0
- package/build/types/QueryClientProvider.d.ts +1 -1
- package/build/types/__tests__/utils.d.ts +1 -1
- package/build/types/createBaseQuery.d.ts +2 -1
- package/build/types/createInfiniteQuery.d.ts +2 -1
- package/build/types/createMutation.d.ts +2 -1
- package/build/types/createQueries.d.ts +2 -1
- package/build/types/createQuery.d.ts +2 -1
- package/build/types/index.d.ts +2 -0
- package/build/types/types.d.ts +2 -1
- package/build/types/useIsFetching.d.ts +2 -1
- package/build/types/useIsMutating.d.ts +2 -1
- package/build/umd/index.js +1 -1
- package/build/umd/index.js.map +1 -1
- package/package.json +1 -1
- package/src/QueryClient.ts +84 -0
- package/src/QueryClientProvider.tsx +1 -1
- package/src/__tests__/createInfiniteQuery.test.tsx +75 -16
- package/src/__tests__/createQuery.test.tsx +59 -4
- package/src/__tests__/utils.tsx +1 -1
- package/src/createBaseQuery.ts +38 -10
- package/src/createInfiniteQuery.ts +1 -1
- package/src/createMutation.ts +2 -1
- package/src/createQueries.ts +1 -1
- package/src/createQuery.ts +2 -1
- package/src/index.ts +7 -0
- package/src/types.ts +4 -2
- package/src/useIsFetching.ts +2 -1
- package/src/useIsMutating.ts +2 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
QueryClientConfig as QueryCoreClientConfig,
|
|
3
|
+
DefaultOptions as CoreDefaultOptions,
|
|
4
|
+
QueryObserverOptions as QueryCoreObserverOptions,
|
|
5
|
+
InfiniteQueryObserverOptions as QueryCoreInfiniteQueryObserverOptions,
|
|
6
|
+
DefaultError,
|
|
7
|
+
QueryKey,
|
|
8
|
+
} from '@tanstack/query-core'
|
|
9
|
+
import { QueryClient as QueryCoreClient } from '@tanstack/query-core'
|
|
10
|
+
|
|
11
|
+
export interface QueryObserverOptions<
|
|
12
|
+
TQueryFnData = unknown,
|
|
13
|
+
TError = DefaultError,
|
|
14
|
+
TData = TQueryFnData,
|
|
15
|
+
TQueryData = TQueryFnData,
|
|
16
|
+
TQueryKey extends QueryKey = QueryKey,
|
|
17
|
+
TPageParam = never,
|
|
18
|
+
> extends Omit<
|
|
19
|
+
QueryCoreObserverOptions<
|
|
20
|
+
TQueryFnData,
|
|
21
|
+
TError,
|
|
22
|
+
TData,
|
|
23
|
+
TQueryData,
|
|
24
|
+
TQueryKey,
|
|
25
|
+
TPageParam
|
|
26
|
+
>,
|
|
27
|
+
'structuralSharing'
|
|
28
|
+
> {
|
|
29
|
+
/**
|
|
30
|
+
* Set this to a reconciliation key to enable reconciliation between query results.
|
|
31
|
+
* Set this to `false` to disable reconciliation between query results.
|
|
32
|
+
* Set this to a function which accepts the old and new data and returns resolved data of the same type to implement custom reconciliation logic.
|
|
33
|
+
* Defaults reconciliation key to `id`.
|
|
34
|
+
*/
|
|
35
|
+
reconcile?:
|
|
36
|
+
| string
|
|
37
|
+
| false
|
|
38
|
+
| ((oldData: TData | undefined, newData: TData) => TData)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface InfiniteQueryObserverOptions<
|
|
42
|
+
TQueryFnData = unknown,
|
|
43
|
+
TError = DefaultError,
|
|
44
|
+
TData = TQueryFnData,
|
|
45
|
+
TQueryData = TQueryFnData,
|
|
46
|
+
TQueryKey extends QueryKey = QueryKey,
|
|
47
|
+
TPageParam = unknown,
|
|
48
|
+
> extends Omit<
|
|
49
|
+
QueryCoreInfiniteQueryObserverOptions<
|
|
50
|
+
TQueryFnData,
|
|
51
|
+
TError,
|
|
52
|
+
TData,
|
|
53
|
+
TQueryData,
|
|
54
|
+
TQueryKey,
|
|
55
|
+
TPageParam
|
|
56
|
+
>,
|
|
57
|
+
'structuralSharing'
|
|
58
|
+
> {
|
|
59
|
+
/**
|
|
60
|
+
* Set this to a reconciliation key to enable reconciliation between query results.
|
|
61
|
+
* Set this to `false` to disable reconciliation between query results.
|
|
62
|
+
* Set this to a function which accepts the old and new data and returns resolved data of the same type to implement custom reconciliation logic.
|
|
63
|
+
* Defaults reconciliation key to `id`.
|
|
64
|
+
*/
|
|
65
|
+
reconcile?:
|
|
66
|
+
| string
|
|
67
|
+
| false
|
|
68
|
+
| ((oldData: TData | undefined, newData: TData) => TData)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface DefaultOptions<TError = DefaultError>
|
|
72
|
+
extends CoreDefaultOptions<TError> {
|
|
73
|
+
queries?: QueryObserverOptions<unknown, TError>
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface QueryClientConfig extends QueryCoreClientConfig {
|
|
77
|
+
defaultOptions?: DefaultOptions
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export class QueryClient extends QueryCoreClient {
|
|
81
|
+
constructor(config: QueryClientConfig = {}) {
|
|
82
|
+
super(config)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
Index,
|
|
11
11
|
Match,
|
|
12
12
|
Switch,
|
|
13
|
+
on,
|
|
13
14
|
} from 'solid-js'
|
|
14
15
|
import type {
|
|
15
16
|
CreateInfiniteQueryResult,
|
|
@@ -193,7 +194,8 @@ describe('useInfiniteQuery', () => {
|
|
|
193
194
|
|
|
194
195
|
it('should keep the previous data when placeholderData is set', async () => {
|
|
195
196
|
const key = queryKey()
|
|
196
|
-
const states: CreateInfiniteQueryResult<InfiniteData<string
|
|
197
|
+
const states: Partial<CreateInfiniteQueryResult<InfiniteData<string>>>[] =
|
|
198
|
+
[]
|
|
197
199
|
|
|
198
200
|
function Page() {
|
|
199
201
|
const [order, setOrder] = createSignal('desc')
|
|
@@ -212,7 +214,16 @@ describe('useInfiniteQuery', () => {
|
|
|
212
214
|
}))
|
|
213
215
|
|
|
214
216
|
createRenderEffect(() => {
|
|
215
|
-
states.push({
|
|
217
|
+
states.push({
|
|
218
|
+
data: state.data ? JSON.parse(JSON.stringify(state.data)) : undefined,
|
|
219
|
+
hasNextPage: state.hasNextPage,
|
|
220
|
+
hasPreviousPage: state.hasPreviousPage,
|
|
221
|
+
isFetching: state.isFetching,
|
|
222
|
+
isFetchingNextPage: state.isFetchingNextPage,
|
|
223
|
+
isFetchingPreviousPage: state.isFetchingPreviousPage,
|
|
224
|
+
isSuccess: state.isSuccess,
|
|
225
|
+
isPlaceholderData: state.isPlaceholderData,
|
|
226
|
+
})
|
|
216
227
|
})
|
|
217
228
|
|
|
218
229
|
return (
|
|
@@ -375,7 +386,8 @@ describe('useInfiniteQuery', () => {
|
|
|
375
386
|
|
|
376
387
|
it('should be able to reverse the data', async () => {
|
|
377
388
|
const key = queryKey()
|
|
378
|
-
const states: CreateInfiniteQueryResult<InfiniteData<number
|
|
389
|
+
const states: Partial<CreateInfiniteQueryResult<InfiniteData<number>>>[] =
|
|
390
|
+
[]
|
|
379
391
|
|
|
380
392
|
function Page() {
|
|
381
393
|
const state = createInfiniteQuery(() => ({
|
|
@@ -394,9 +406,19 @@ describe('useInfiniteQuery', () => {
|
|
|
394
406
|
defaultPageParam: 0,
|
|
395
407
|
}))
|
|
396
408
|
|
|
397
|
-
createRenderEffect(
|
|
398
|
-
|
|
399
|
-
|
|
409
|
+
createRenderEffect(
|
|
410
|
+
on(
|
|
411
|
+
() => ({ ...state }),
|
|
412
|
+
() => {
|
|
413
|
+
states.push({
|
|
414
|
+
data: state.data
|
|
415
|
+
? JSON.parse(JSON.stringify(state.data))
|
|
416
|
+
: undefined,
|
|
417
|
+
isSuccess: state.isSuccess,
|
|
418
|
+
})
|
|
419
|
+
},
|
|
420
|
+
),
|
|
421
|
+
)
|
|
400
422
|
|
|
401
423
|
return (
|
|
402
424
|
<div>
|
|
@@ -439,7 +461,8 @@ describe('useInfiniteQuery', () => {
|
|
|
439
461
|
|
|
440
462
|
it('should be able to fetch a previous page', async () => {
|
|
441
463
|
const key = queryKey()
|
|
442
|
-
const states: CreateInfiniteQueryResult<InfiniteData<number
|
|
464
|
+
const states: Partial<CreateInfiniteQueryResult<InfiniteData<number>>>[] =
|
|
465
|
+
[]
|
|
443
466
|
|
|
444
467
|
function Page() {
|
|
445
468
|
const start = 10
|
|
@@ -456,7 +479,15 @@ describe('useInfiniteQuery', () => {
|
|
|
456
479
|
}))
|
|
457
480
|
|
|
458
481
|
createRenderEffect(() => {
|
|
459
|
-
states.push({
|
|
482
|
+
states.push({
|
|
483
|
+
data: state.data ? JSON.parse(JSON.stringify(state.data)) : undefined,
|
|
484
|
+
hasNextPage: state.hasNextPage,
|
|
485
|
+
hasPreviousPage: state.hasPreviousPage,
|
|
486
|
+
isFetching: state.isFetching,
|
|
487
|
+
isFetchingNextPage: state.isFetchingNextPage,
|
|
488
|
+
isFetchingPreviousPage: state.isFetchingPreviousPage,
|
|
489
|
+
isSuccess: state.isSuccess,
|
|
490
|
+
})
|
|
460
491
|
})
|
|
461
492
|
|
|
462
493
|
createEffect(() => {
|
|
@@ -518,7 +549,8 @@ describe('useInfiniteQuery', () => {
|
|
|
518
549
|
|
|
519
550
|
it('should be able to refetch when providing page params automatically', async () => {
|
|
520
551
|
const key = queryKey()
|
|
521
|
-
const states: CreateInfiniteQueryResult<InfiniteData<number
|
|
552
|
+
const states: Partial<CreateInfiniteQueryResult<InfiniteData<number>>>[] =
|
|
553
|
+
[]
|
|
522
554
|
|
|
523
555
|
function Page() {
|
|
524
556
|
const state = createInfiniteQuery(() => ({
|
|
@@ -535,7 +567,13 @@ describe('useInfiniteQuery', () => {
|
|
|
535
567
|
}))
|
|
536
568
|
|
|
537
569
|
createRenderEffect(() => {
|
|
538
|
-
states.push({
|
|
570
|
+
states.push({
|
|
571
|
+
data: state.data ? JSON.parse(JSON.stringify(state.data)) : undefined,
|
|
572
|
+
isFetching: state.isFetching,
|
|
573
|
+
isFetchingNextPage: state.isFetchingNextPage,
|
|
574
|
+
isRefetching: state.isRefetching,
|
|
575
|
+
isFetchingPreviousPage: state.isFetchingPreviousPage,
|
|
576
|
+
})
|
|
539
577
|
})
|
|
540
578
|
|
|
541
579
|
return (
|
|
@@ -632,7 +670,8 @@ describe('useInfiniteQuery', () => {
|
|
|
632
670
|
|
|
633
671
|
it('should silently cancel any ongoing fetch when fetching more', async () => {
|
|
634
672
|
const key = queryKey()
|
|
635
|
-
const states: CreateInfiniteQueryResult<InfiniteData<number
|
|
673
|
+
const states: Partial<CreateInfiniteQueryResult<InfiniteData<number>>>[] =
|
|
674
|
+
[]
|
|
636
675
|
|
|
637
676
|
function Page() {
|
|
638
677
|
const start = 10
|
|
@@ -649,7 +688,13 @@ describe('useInfiniteQuery', () => {
|
|
|
649
688
|
}))
|
|
650
689
|
|
|
651
690
|
createRenderEffect(() => {
|
|
652
|
-
states.push({
|
|
691
|
+
states.push({
|
|
692
|
+
hasNextPage: state.hasNextPage,
|
|
693
|
+
data: state.data ? JSON.parse(JSON.stringify(state.data)) : undefined,
|
|
694
|
+
isFetching: state.isFetching,
|
|
695
|
+
isFetchingNextPage: state.isFetchingNextPage,
|
|
696
|
+
isSuccess: state.isSuccess,
|
|
697
|
+
})
|
|
653
698
|
})
|
|
654
699
|
|
|
655
700
|
createEffect(() => {
|
|
@@ -978,7 +1023,8 @@ describe('useInfiniteQuery', () => {
|
|
|
978
1023
|
|
|
979
1024
|
it('should be able to set new pages with the query client', async () => {
|
|
980
1025
|
const key = queryKey()
|
|
981
|
-
const states: CreateInfiniteQueryResult<InfiniteData<number
|
|
1026
|
+
const states: Partial<CreateInfiniteQueryResult<InfiniteData<number>>>[] =
|
|
1027
|
+
[]
|
|
982
1028
|
|
|
983
1029
|
function Page() {
|
|
984
1030
|
const [firstPage, setFirstPage] = createSignal(0)
|
|
@@ -996,7 +1042,13 @@ describe('useInfiniteQuery', () => {
|
|
|
996
1042
|
}))
|
|
997
1043
|
|
|
998
1044
|
createRenderEffect(() => {
|
|
999
|
-
states.push({
|
|
1045
|
+
states.push({
|
|
1046
|
+
hasNextPage: state.hasNextPage,
|
|
1047
|
+
data: state.data ? JSON.parse(JSON.stringify(state.data)) : undefined,
|
|
1048
|
+
isFetching: state.isFetching,
|
|
1049
|
+
isFetchingNextPage: state.isFetchingNextPage,
|
|
1050
|
+
isSuccess: state.isSuccess,
|
|
1051
|
+
})
|
|
1000
1052
|
})
|
|
1001
1053
|
|
|
1002
1054
|
createEffect(() => {
|
|
@@ -1066,7 +1118,8 @@ describe('useInfiniteQuery', () => {
|
|
|
1066
1118
|
|
|
1067
1119
|
it('should only refetch the first page when initialData is provided', async () => {
|
|
1068
1120
|
const key = queryKey()
|
|
1069
|
-
const states: CreateInfiniteQueryResult<InfiniteData<number
|
|
1121
|
+
const states: Partial<CreateInfiniteQueryResult<InfiniteData<number>>>[] =
|
|
1122
|
+
[]
|
|
1070
1123
|
|
|
1071
1124
|
function Page() {
|
|
1072
1125
|
const state = createInfiniteQuery(() => ({
|
|
@@ -1083,7 +1136,13 @@ describe('useInfiniteQuery', () => {
|
|
|
1083
1136
|
}))
|
|
1084
1137
|
|
|
1085
1138
|
createRenderEffect(() => {
|
|
1086
|
-
states.push({
|
|
1139
|
+
states.push({
|
|
1140
|
+
data: JSON.parse(JSON.stringify(state.data)),
|
|
1141
|
+
hasNextPage: state.hasNextPage,
|
|
1142
|
+
isFetching: state.isFetching,
|
|
1143
|
+
isFetchingNextPage: state.isFetchingNextPage,
|
|
1144
|
+
isSuccess: state.isSuccess,
|
|
1145
|
+
})
|
|
1087
1146
|
})
|
|
1088
1147
|
|
|
1089
1148
|
createEffect(() => {
|
|
@@ -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()
|
|
@@ -1282,7 +1283,6 @@ describe('createQuery', () => {
|
|
|
1282
1283
|
count++
|
|
1283
1284
|
return count === 1 ? result1 : result2
|
|
1284
1285
|
},
|
|
1285
|
-
notifyOnChangeProps: 'all',
|
|
1286
1286
|
}))
|
|
1287
1287
|
|
|
1288
1288
|
createRenderEffect(() => {
|
|
@@ -1322,9 +1322,8 @@ describe('createQuery', () => {
|
|
|
1322
1322
|
|
|
1323
1323
|
expect(todos).toEqual(result1)
|
|
1324
1324
|
expect(newTodos).toEqual(result2)
|
|
1325
|
-
expect(newTodos).not.toBe(todos)
|
|
1326
1325
|
expect(newTodo1).toBe(todo1)
|
|
1327
|
-
expect(newTodo2).
|
|
1326
|
+
expect(newTodo2).toBe(todo2)
|
|
1328
1327
|
|
|
1329
1328
|
return null
|
|
1330
1329
|
})
|
|
@@ -3257,7 +3256,7 @@ describe('createQuery', () => {
|
|
|
3257
3256
|
|
|
3258
3257
|
it('should keep initial data when the query key changes', async () => {
|
|
3259
3258
|
const key = queryKey()
|
|
3260
|
-
const states: DefinedCreateQueryResult<{ count: number }
|
|
3259
|
+
const states: Partial<DefinedCreateQueryResult<{ count: number }>>[] = []
|
|
3261
3260
|
|
|
3262
3261
|
function Page() {
|
|
3263
3262
|
const [count, setCount] = createSignal(0)
|
|
@@ -3266,6 +3265,7 @@ describe('createQuery', () => {
|
|
|
3266
3265
|
queryFn: () => ({ count: 10 }),
|
|
3267
3266
|
staleTime: Infinity,
|
|
3268
3267
|
initialData: () => ({ count: count() }),
|
|
3268
|
+
reconcile: false,
|
|
3269
3269
|
}))
|
|
3270
3270
|
createRenderEffect(() => {
|
|
3271
3271
|
states.push({ ...state })
|
|
@@ -4610,6 +4610,61 @@ describe('createQuery', () => {
|
|
|
4610
4610
|
expect(states).toHaveLength(1)
|
|
4611
4611
|
})
|
|
4612
4612
|
|
|
4613
|
+
it('The reconcile fn callback should correctly maintain referential equality', async () => {
|
|
4614
|
+
const key1 = queryKey()
|
|
4615
|
+
const states: Array<Array<number>> = []
|
|
4616
|
+
|
|
4617
|
+
function Page() {
|
|
4618
|
+
const [forceValue, setForceValue] = createSignal(1)
|
|
4619
|
+
|
|
4620
|
+
const state = createQuery(() => ({
|
|
4621
|
+
queryKey: key1,
|
|
4622
|
+
queryFn: async () => {
|
|
4623
|
+
await sleep(10)
|
|
4624
|
+
return [1, 2]
|
|
4625
|
+
},
|
|
4626
|
+
select: (res) => res.map((x) => x + 1),
|
|
4627
|
+
reconcile(oldData, newData) {
|
|
4628
|
+
return reconcile(newData)(oldData)
|
|
4629
|
+
},
|
|
4630
|
+
}))
|
|
4631
|
+
|
|
4632
|
+
createEffect(() => {
|
|
4633
|
+
if (state.data) {
|
|
4634
|
+
states.push(state.data)
|
|
4635
|
+
}
|
|
4636
|
+
})
|
|
4637
|
+
|
|
4638
|
+
const forceUpdate = () => {
|
|
4639
|
+
setForceValue((prev) => prev + 1)
|
|
4640
|
+
}
|
|
4641
|
+
|
|
4642
|
+
return (
|
|
4643
|
+
<div>
|
|
4644
|
+
<h2>Data: {JSON.stringify(state.data)}</h2>
|
|
4645
|
+
<h2>forceValue: {forceValue}</h2>
|
|
4646
|
+
<button onClick={forceUpdate}>forceUpdate</button>
|
|
4647
|
+
</div>
|
|
4648
|
+
)
|
|
4649
|
+
}
|
|
4650
|
+
|
|
4651
|
+
render(() => (
|
|
4652
|
+
<QueryClientProvider client={queryClient}>
|
|
4653
|
+
<Page />
|
|
4654
|
+
</QueryClientProvider>
|
|
4655
|
+
))
|
|
4656
|
+
await waitFor(() => screen.getByText('Data: [2,3]'))
|
|
4657
|
+
expect(states).toHaveLength(1)
|
|
4658
|
+
|
|
4659
|
+
fireEvent.click(screen.getByRole('button', { name: /forceUpdate/i }))
|
|
4660
|
+
|
|
4661
|
+
await waitFor(() => screen.getByText('forceValue: 2'))
|
|
4662
|
+
await waitFor(() => screen.getByText('Data: [2,3]'))
|
|
4663
|
+
|
|
4664
|
+
// effect should not be triggered again due to structural sharing
|
|
4665
|
+
expect(states).toHaveLength(1)
|
|
4666
|
+
})
|
|
4667
|
+
|
|
4613
4668
|
it('should cancel the query function when there are no more subscriptions', async () => {
|
|
4614
4669
|
const key = queryKey()
|
|
4615
4670
|
let cancelFn: Mock = vi.fn()
|
package/src/__tests__/utils.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { QueryClientConfig } from '@tanstack/query-core'
|
|
2
|
-
import { QueryClient } from '
|
|
2
|
+
import { QueryClient } from '../QueryClient'
|
|
3
3
|
import type { ParentProps } from 'solid-js'
|
|
4
4
|
import { createEffect, createSignal, onCleanup, Show } from 'solid-js'
|
|
5
5
|
import { vi } from 'vitest'
|
package/src/createBaseQuery.ts
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
// in solid-js/web package. I'll create a GitHub issue with them to see
|
|
4
4
|
// why that happens.
|
|
5
5
|
import type {
|
|
6
|
-
QueryClient,
|
|
7
6
|
QueryKey,
|
|
8
7
|
QueryObserver,
|
|
9
8
|
QueryObserverResult,
|
|
10
9
|
} from '@tanstack/query-core'
|
|
10
|
+
import type { QueryClient } from './QueryClient'
|
|
11
11
|
import { hydrate } from '@tanstack/query-core'
|
|
12
12
|
import { notifyManager } from '@tanstack/query-core'
|
|
13
13
|
import type { Accessor } from 'solid-js'
|
|
@@ -19,11 +19,28 @@ import {
|
|
|
19
19
|
on,
|
|
20
20
|
onCleanup,
|
|
21
21
|
} from 'solid-js'
|
|
22
|
-
import { createStore, unwrap } from 'solid-js/store'
|
|
22
|
+
import { createStore, reconcile, unwrap } from 'solid-js/store'
|
|
23
23
|
import { useQueryClient } from './QueryClientProvider'
|
|
24
24
|
import type { CreateBaseQueryOptions } from './types'
|
|
25
25
|
import { shouldThrowError } from './utils'
|
|
26
26
|
|
|
27
|
+
function reconcileFn<TData, TError>(
|
|
28
|
+
store: QueryObserverResult<TData, TError>,
|
|
29
|
+
result: QueryObserverResult<TData, TError>,
|
|
30
|
+
reconcileOption:
|
|
31
|
+
| string
|
|
32
|
+
| false
|
|
33
|
+
| ((oldData: TData | undefined, newData: TData) => TData),
|
|
34
|
+
): QueryObserverResult<TData, TError> {
|
|
35
|
+
if (reconcileOption === false) return result
|
|
36
|
+
if (typeof reconcileOption === 'function') {
|
|
37
|
+
const newData = reconcileOption(store.data, result.data as TData)
|
|
38
|
+
return { ...result, data: newData } as typeof result
|
|
39
|
+
}
|
|
40
|
+
const newData = reconcile(result.data, { key: reconcileOption })(store.data)
|
|
41
|
+
return { ...result, data: newData } as typeof result
|
|
42
|
+
}
|
|
43
|
+
|
|
27
44
|
// Base Query Function that is used to create the query.
|
|
28
45
|
export function createBaseQuery<
|
|
29
46
|
TQueryFnData,
|
|
@@ -42,6 +59,7 @@ export function createBaseQuery<
|
|
|
42
59
|
|
|
43
60
|
const defaultedOptions = client().defaultQueryOptions(options())
|
|
44
61
|
defaultedOptions._optimisticResults = 'optimistic'
|
|
62
|
+
defaultedOptions.structuralSharing = false
|
|
45
63
|
if (isServer) {
|
|
46
64
|
defaultedOptions.retry = false
|
|
47
65
|
defaultedOptions.throwErrors = true
|
|
@@ -96,18 +114,28 @@ export function createBaseQuery<
|
|
|
96
114
|
const createClientSubscriber = () => {
|
|
97
115
|
return observer.subscribe((result) => {
|
|
98
116
|
notifyManager.batchCalls(() => {
|
|
99
|
-
|
|
117
|
+
// @ts-expect-error - This will error because the reconcile option does not
|
|
118
|
+
// exist on the query-core QueryObserverResult type
|
|
119
|
+
const reconcileOptions = observer.options.reconcile
|
|
100
120
|
// If the query has data we dont suspend but instead mutate the resource
|
|
101
121
|
// This could happen when placeholderData/initialData is defined
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
122
|
+
if (queryResource()?.data && result.data && !queryResource.loading) {
|
|
123
|
+
setState((store) => {
|
|
124
|
+
return reconcileFn(
|
|
125
|
+
store,
|
|
126
|
+
result,
|
|
127
|
+
reconcileOptions === undefined ? 'id' : reconcileOptions,
|
|
128
|
+
)
|
|
129
|
+
})
|
|
108
130
|
mutate(state)
|
|
109
131
|
} else {
|
|
110
|
-
setState(
|
|
132
|
+
setState((store) => {
|
|
133
|
+
return reconcileFn(
|
|
134
|
+
store,
|
|
135
|
+
result,
|
|
136
|
+
reconcileOptions === undefined ? 'id' : reconcileOptions,
|
|
137
|
+
)
|
|
138
|
+
})
|
|
111
139
|
refetch()
|
|
112
140
|
}
|
|
113
141
|
})()
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
QueryObserver,
|
|
3
3
|
QueryKey,
|
|
4
|
-
QueryClient,
|
|
5
4
|
DefaultError,
|
|
6
5
|
InfiniteData,
|
|
7
6
|
} from '@tanstack/query-core'
|
|
7
|
+
import type { QueryClient } from './QueryClient'
|
|
8
8
|
import { InfiniteQueryObserver } from '@tanstack/query-core'
|
|
9
9
|
import type {
|
|
10
10
|
CreateInfiniteQueryOptions,
|
package/src/createMutation.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DefaultError } from '@tanstack/query-core'
|
|
2
|
+
import type { QueryClient } from './QueryClient'
|
|
2
3
|
import { MutationObserver } from '@tanstack/query-core'
|
|
3
4
|
import { useQueryClient } from './QueryClientProvider'
|
|
4
5
|
import type {
|
package/src/createQueries.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
QueriesPlaceholderDataFunction,
|
|
3
|
-
QueryClient,
|
|
4
3
|
QueryFunction,
|
|
5
4
|
QueryKey,
|
|
6
5
|
DefaultError,
|
|
7
6
|
} from '@tanstack/query-core'
|
|
8
7
|
import { notifyManager, QueriesObserver } from '@tanstack/query-core'
|
|
8
|
+
import type { QueryClient } from './QueryClient'
|
|
9
9
|
import type { Accessor } from 'solid-js'
|
|
10
10
|
import { createComputed, onCleanup, onMount } from 'solid-js'
|
|
11
11
|
import { createStore, unwrap } from 'solid-js/store'
|
package/src/createQuery.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { QueryKey, DefaultError } from '@tanstack/query-core'
|
|
2
2
|
import { QueryObserver } from '@tanstack/query-core'
|
|
3
|
+
import type { QueryClient } from './QueryClient'
|
|
3
4
|
import type { Accessor } from 'solid-js'
|
|
4
5
|
import { createMemo } from 'solid-js'
|
|
5
6
|
import { createBaseQuery } from './createBaseQuery'
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,13 @@ export * from '@tanstack/query-core'
|
|
|
8
8
|
|
|
9
9
|
// Solid Query
|
|
10
10
|
export * from './types'
|
|
11
|
+
export { QueryClient } from './QueryClient'
|
|
12
|
+
export type {
|
|
13
|
+
QueryObserverOptions,
|
|
14
|
+
DefaultOptions,
|
|
15
|
+
QueryClientConfig,
|
|
16
|
+
InfiniteQueryObserverOptions,
|
|
17
|
+
} from './QueryClient'
|
|
11
18
|
export { createQuery } from './createQuery'
|
|
12
19
|
export {
|
|
13
20
|
QueryClientContext,
|
package/src/types.ts
CHANGED
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
4
|
QueryKey,
|
|
5
|
-
QueryObserverOptions,
|
|
6
5
|
QueryObserverResult,
|
|
7
6
|
MutateFunction,
|
|
8
7
|
MutationObserverOptions,
|
|
9
8
|
MutationObserverResult,
|
|
10
9
|
DefinedQueryObserverResult,
|
|
11
|
-
InfiniteQueryObserverOptions,
|
|
12
10
|
InfiniteQueryObserverResult,
|
|
13
11
|
WithRequired,
|
|
14
12
|
DefaultError,
|
|
15
13
|
} from '@tanstack/query-core'
|
|
14
|
+
import type {
|
|
15
|
+
QueryObserverOptions,
|
|
16
|
+
InfiniteQueryObserverOptions,
|
|
17
|
+
} from './QueryClient'
|
|
16
18
|
|
|
17
19
|
export type FunctionedParams<T> = () => T
|
|
18
20
|
|
package/src/useIsFetching.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { QueryFilters } from '@tanstack/query-core'
|
|
2
|
+
import type { QueryClient } from './QueryClient'
|
|
2
3
|
import type { Accessor } from 'solid-js'
|
|
3
4
|
import { createMemo, createSignal, onCleanup } from 'solid-js'
|
|
4
5
|
import { useQueryClient } from './QueryClientProvider'
|
package/src/useIsMutating.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { MutationFilters
|
|
1
|
+
import type { MutationFilters } from '@tanstack/query-core'
|
|
2
|
+
import type { QueryClient } from './QueryClient'
|
|
2
3
|
import { useQueryClient } from './QueryClientProvider'
|
|
3
4
|
import type { Accessor } from 'solid-js'
|
|
4
5
|
import { createSignal, onCleanup, createMemo } from 'solid-js'
|