@tanstack/query-core 4.0.11-beta.0 → 4.0.11-beta.1
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/lib/index.js +19 -0
- package/build/lib/index.js.map +1 -1
- package/build/lib/index.mjs +19 -0
- package/build/lib/index.mjs.map +1 -1
- package/build/lib/mutationCache.d.ts +6 -1
- package/build/lib/queryCache.d.ts +6 -1
- package/build/lib/types.d.ts +10 -8
- package/build/umd/index.development.js +19 -0
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +1 -1
- package/src/mutationCache.ts +7 -0
- package/src/mutationObserver.ts +9 -0
- package/src/queryCache.ts +7 -0
- package/src/queryObserver.ts +8 -0
- package/src/tests/queryClient.test.tsx +33 -0
- package/src/tests/queryObserver.test.tsx +19 -0
- package/src/types.ts +15 -9
- package/src/utils.ts +2 -0
package/package.json
CHANGED
package/src/mutationCache.ts
CHANGED
|
@@ -48,6 +48,12 @@ interface NotifyEventMutationObserverRemoved {
|
|
|
48
48
|
observer: MutationObserver<any, any, any>
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
interface NotifyEventMutationObserverOptionsUpdated {
|
|
52
|
+
type: 'observerOptionsUpdated'
|
|
53
|
+
mutation?: Mutation<any, any, any, any>
|
|
54
|
+
observer: MutationObserver<any, any, any, any>
|
|
55
|
+
}
|
|
56
|
+
|
|
51
57
|
interface NotifyEventMutationUpdated {
|
|
52
58
|
type: 'updated'
|
|
53
59
|
mutation: Mutation<any, any, any, any>
|
|
@@ -59,6 +65,7 @@ type MutationCacheNotifyEvent =
|
|
|
59
65
|
| NotifyEventMutationRemoved
|
|
60
66
|
| NotifyEventMutationObserverAdded
|
|
61
67
|
| NotifyEventMutationObserverRemoved
|
|
68
|
+
| NotifyEventMutationObserverOptionsUpdated
|
|
62
69
|
| NotifyEventMutationUpdated
|
|
63
70
|
|
|
64
71
|
type MutationCacheListener = (event: MutationCacheNotifyEvent) => void
|
package/src/mutationObserver.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
MutationObserverResult,
|
|
9
9
|
MutationObserverOptions,
|
|
10
10
|
} from './types'
|
|
11
|
+
import { shallowEqualObjects } from './utils'
|
|
11
12
|
|
|
12
13
|
// TYPES
|
|
13
14
|
|
|
@@ -63,7 +64,15 @@ export class MutationObserver<
|
|
|
63
64
|
setOptions(
|
|
64
65
|
options?: MutationObserverOptions<TData, TError, TVariables, TContext>,
|
|
65
66
|
) {
|
|
67
|
+
const prevOptions = this.options
|
|
66
68
|
this.options = this.client.defaultMutationOptions(options)
|
|
69
|
+
if (!shallowEqualObjects(prevOptions, this.options)) {
|
|
70
|
+
this.client.getMutationCache().notify({
|
|
71
|
+
type: 'observerOptionsUpdated',
|
|
72
|
+
mutation: this.currentMutation,
|
|
73
|
+
observer: this,
|
|
74
|
+
})
|
|
75
|
+
}
|
|
67
76
|
}
|
|
68
77
|
|
|
69
78
|
protected onUnsubscribe(): void {
|
package/src/queryCache.ts
CHANGED
|
@@ -55,6 +55,12 @@ interface NotifyEventQueryObserverResultsUpdated {
|
|
|
55
55
|
query: Query<any, any, any, any>
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
interface NotifyEventQueryObserverOptionsUpdated {
|
|
59
|
+
type: 'observerOptionsUpdated'
|
|
60
|
+
query: Query<any, any, any, any>
|
|
61
|
+
observer: QueryObserver<any, any, any, any, any>
|
|
62
|
+
}
|
|
63
|
+
|
|
58
64
|
type QueryCacheNotifyEvent =
|
|
59
65
|
| NotifyEventQueryAdded
|
|
60
66
|
| NotifyEventQueryRemoved
|
|
@@ -62,6 +68,7 @@ type QueryCacheNotifyEvent =
|
|
|
62
68
|
| NotifyEventQueryObserverAdded
|
|
63
69
|
| NotifyEventQueryObserverRemoved
|
|
64
70
|
| NotifyEventQueryObserverResultsUpdated
|
|
71
|
+
| NotifyEventQueryObserverOptionsUpdated
|
|
65
72
|
|
|
66
73
|
type QueryCacheListener = (event: QueryCacheNotifyEvent) => void
|
|
67
74
|
|
package/src/queryObserver.ts
CHANGED
|
@@ -155,6 +155,14 @@ export class QueryObserver<
|
|
|
155
155
|
|
|
156
156
|
this.options = this.client.defaultQueryOptions(options)
|
|
157
157
|
|
|
158
|
+
if (!shallowEqualObjects(prevOptions, this.options)) {
|
|
159
|
+
this.client.getQueryCache().notify({
|
|
160
|
+
type: 'observerOptionsUpdated',
|
|
161
|
+
query: this.currentQuery,
|
|
162
|
+
observer: this,
|
|
163
|
+
})
|
|
164
|
+
}
|
|
165
|
+
|
|
158
166
|
if (
|
|
159
167
|
typeof this.options.enabled !== 'undefined' &&
|
|
160
168
|
typeof this.options.enabled !== 'boolean'
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
QueryClient,
|
|
14
14
|
QueryFunction,
|
|
15
15
|
QueryObserver,
|
|
16
|
+
QueryObserverOptions,
|
|
16
17
|
} from '..'
|
|
17
18
|
import { focusManager, onlineManager } from '..'
|
|
18
19
|
|
|
@@ -357,6 +358,38 @@ describe('queryClient', () => {
|
|
|
357
358
|
expect(queryCache.find(key)!.state.data).toBe(newData)
|
|
358
359
|
})
|
|
359
360
|
|
|
361
|
+
test('should apply a custom structuralSharing function when provided', () => {
|
|
362
|
+
const key = queryKey()
|
|
363
|
+
|
|
364
|
+
const queryObserverOptions = {
|
|
365
|
+
structuralSharing: (
|
|
366
|
+
prevData: { value: Date } | undefined,
|
|
367
|
+
newData: { value: Date },
|
|
368
|
+
) => {
|
|
369
|
+
if (!prevData) {
|
|
370
|
+
return newData
|
|
371
|
+
}
|
|
372
|
+
return newData.value.getTime() === prevData.value.getTime()
|
|
373
|
+
? prevData
|
|
374
|
+
: newData
|
|
375
|
+
},
|
|
376
|
+
} as QueryObserverOptions
|
|
377
|
+
|
|
378
|
+
queryClient.setDefaultOptions({ queries: queryObserverOptions })
|
|
379
|
+
|
|
380
|
+
const oldData = { value: new Date(2022, 6, 19) }
|
|
381
|
+
const newData = { value: new Date(2022, 6, 19) }
|
|
382
|
+
queryClient.setQueryData(key, oldData)
|
|
383
|
+
queryClient.setQueryData(key, newData)
|
|
384
|
+
|
|
385
|
+
expect(queryCache.find(key)!.state.data).toBe(oldData)
|
|
386
|
+
|
|
387
|
+
const distinctData = { value: new Date(2021, 11, 25) }
|
|
388
|
+
queryClient.setQueryData(key, distinctData)
|
|
389
|
+
|
|
390
|
+
expect(queryCache.find(key)!.state.data).toBe(distinctData)
|
|
391
|
+
})
|
|
392
|
+
|
|
360
393
|
test('should not set isFetching to false', async () => {
|
|
361
394
|
const key = queryKey()
|
|
362
395
|
queryClient.prefetchQuery(key, async () => {
|
|
@@ -799,4 +799,23 @@ describe('queryObserver', () => {
|
|
|
799
799
|
|
|
800
800
|
unsubscribe()
|
|
801
801
|
})
|
|
802
|
+
|
|
803
|
+
test('setOptions should notify cache listeners', async () => {
|
|
804
|
+
const key = queryKey()
|
|
805
|
+
|
|
806
|
+
const observer = new QueryObserver(queryClient, {
|
|
807
|
+
queryKey: key,
|
|
808
|
+
})
|
|
809
|
+
|
|
810
|
+
const spy = jest.fn()
|
|
811
|
+
const unsubscribe = queryClient.getQueryCache().subscribe(spy)
|
|
812
|
+
observer.setOptions({ enabled: false })
|
|
813
|
+
|
|
814
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
815
|
+
expect(spy).toHaveBeenCalledWith(
|
|
816
|
+
expect.objectContaining({ type: 'observerOptionsUpdated' }),
|
|
817
|
+
)
|
|
818
|
+
|
|
819
|
+
unsubscribe()
|
|
820
|
+
})
|
|
802
821
|
})
|
package/src/types.ts
CHANGED
|
@@ -76,9 +76,12 @@ export interface QueryOptions<
|
|
|
76
76
|
behavior?: QueryBehavior<TQueryFnData, TError, TData>
|
|
77
77
|
/**
|
|
78
78
|
* Set this to `false` to disable structural sharing between query results.
|
|
79
|
+
* Set this to a function which accepts the old and new data and returns resolved data of the same type to implement custom structural sharing logic.
|
|
79
80
|
* Defaults to `true`.
|
|
80
81
|
*/
|
|
81
|
-
structuralSharing?:
|
|
82
|
+
structuralSharing?:
|
|
83
|
+
| boolean
|
|
84
|
+
| ((oldData: TData | undefined, newData: TData) => TData)
|
|
82
85
|
/**
|
|
83
86
|
* This function can be set to automatically get the previous cursor for infinite queries.
|
|
84
87
|
* The result will also be used to determine the value of `hasPreviousPage`.
|
|
@@ -425,11 +428,14 @@ export interface QueryObserverSuccessResult<TData = unknown, TError = unknown>
|
|
|
425
428
|
status: 'success'
|
|
426
429
|
}
|
|
427
430
|
|
|
431
|
+
export type DefinedQueryObserverResult<TData = unknown, TError = unknown> =
|
|
432
|
+
| QueryObserverRefetchErrorResult<TData, TError>
|
|
433
|
+
| QueryObserverSuccessResult<TData, TError>
|
|
434
|
+
|
|
428
435
|
export type QueryObserverResult<TData = unknown, TError = unknown> =
|
|
436
|
+
| DefinedQueryObserverResult<TData, TError>
|
|
429
437
|
| QueryObserverLoadingErrorResult<TData, TError>
|
|
430
438
|
| QueryObserverLoadingResult<TData, TError>
|
|
431
|
-
| QueryObserverRefetchErrorResult<TData, TError>
|
|
432
|
-
| QueryObserverSuccessResult<TData, TError>
|
|
433
439
|
|
|
434
440
|
export interface InfiniteQueryObserverBaseResult<
|
|
435
441
|
TData = unknown,
|
|
@@ -535,18 +541,18 @@ export interface MutationOptions<
|
|
|
535
541
|
data: TData,
|
|
536
542
|
variables: TVariables,
|
|
537
543
|
context: TContext | undefined,
|
|
538
|
-
) => Promise<unknown> |
|
|
544
|
+
) => Promise<unknown> | unknown
|
|
539
545
|
onError?: (
|
|
540
546
|
error: TError,
|
|
541
547
|
variables: TVariables,
|
|
542
548
|
context: TContext | undefined,
|
|
543
|
-
) => Promise<unknown> |
|
|
549
|
+
) => Promise<unknown> | unknown
|
|
544
550
|
onSettled?: (
|
|
545
551
|
data: TData | undefined,
|
|
546
552
|
error: TError | null,
|
|
547
553
|
variables: TVariables,
|
|
548
554
|
context: TContext | undefined,
|
|
549
|
-
) => Promise<unknown> |
|
|
555
|
+
) => Promise<unknown> | unknown
|
|
550
556
|
retry?: RetryValue<TError>
|
|
551
557
|
retryDelay?: RetryDelayValue<TError>
|
|
552
558
|
networkMode?: NetworkMode
|
|
@@ -574,18 +580,18 @@ export interface MutateOptions<
|
|
|
574
580
|
data: TData,
|
|
575
581
|
variables: TVariables,
|
|
576
582
|
context: TContext,
|
|
577
|
-
) => Promise<unknown> |
|
|
583
|
+
) => Promise<unknown> | unknown
|
|
578
584
|
onError?: (
|
|
579
585
|
error: TError,
|
|
580
586
|
variables: TVariables,
|
|
581
587
|
context: TContext | undefined,
|
|
582
|
-
) => Promise<unknown> |
|
|
588
|
+
) => Promise<unknown> | unknown
|
|
583
589
|
onSettled?: (
|
|
584
590
|
data: TData | undefined,
|
|
585
591
|
error: TError | null,
|
|
586
592
|
variables: TVariables,
|
|
587
593
|
context: TContext | undefined,
|
|
588
|
-
) => Promise<unknown> |
|
|
594
|
+
) => Promise<unknown> | unknown
|
|
589
595
|
}
|
|
590
596
|
|
|
591
597
|
export type MutateFunction<
|
package/src/utils.ts
CHANGED
|
@@ -427,6 +427,8 @@ export function replaceData<
|
|
|
427
427
|
// Use prev data if an isDataEqual function is defined and returns `true`
|
|
428
428
|
if (options.isDataEqual?.(prevData, data)) {
|
|
429
429
|
return prevData as TData
|
|
430
|
+
} else if (typeof options.structuralSharing === 'function') {
|
|
431
|
+
return options.structuralSharing(prevData, data)
|
|
430
432
|
} else if (options.structuralSharing !== false) {
|
|
431
433
|
// Structurally share data between prev and new data if needed
|
|
432
434
|
return replaceEqualDeep(prevData, data)
|