@tanstack/query-core 4.24.10 → 5.0.0-alpha.0
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/focusManager.d.ts +1 -3
- package/build/lib/focusManager.esm.js +19 -36
- package/build/lib/focusManager.esm.js.map +1 -1
- package/build/lib/focusManager.js +19 -38
- package/build/lib/focusManager.js.map +1 -1
- package/build/lib/focusManager.mjs +19 -36
- package/build/lib/focusManager.mjs.map +1 -1
- package/build/lib/hydration.esm.js +21 -23
- package/build/lib/hydration.esm.js.map +1 -1
- package/build/lib/hydration.js +21 -25
- package/build/lib/hydration.js.map +1 -1
- package/build/lib/hydration.mjs +21 -23
- package/build/lib/hydration.mjs.map +1 -1
- package/build/lib/index.d.ts +1 -2
- package/build/lib/index.esm.js +1 -1
- package/build/lib/index.js +2 -8
- package/build/lib/index.js.map +1 -1
- package/build/lib/index.mjs +1 -1
- package/build/lib/infiniteQueryBehavior.d.ts +3 -7
- package/build/lib/infiniteQueryBehavior.esm.js +52 -75
- package/build/lib/infiniteQueryBehavior.esm.js.map +1 -1
- package/build/lib/infiniteQueryBehavior.js +50 -77
- package/build/lib/infiniteQueryBehavior.js.map +1 -1
- package/build/lib/infiniteQueryBehavior.mjs +52 -75
- package/build/lib/infiniteQueryBehavior.mjs.map +1 -1
- package/build/lib/infiniteQueryObserver.d.ts +4 -4
- package/build/lib/infiniteQueryObserver.esm.js +18 -26
- package/build/lib/infiniteQueryObserver.esm.js.map +1 -1
- package/build/lib/infiniteQueryObserver.js +18 -28
- package/build/lib/infiniteQueryObserver.js.map +1 -1
- package/build/lib/infiniteQueryObserver.mjs +18 -26
- package/build/lib/infiniteQueryObserver.mjs.map +1 -1
- package/build/lib/mutation.d.ts +11 -22
- package/build/lib/mutation.esm.js +73 -105
- package/build/lib/mutation.esm.js.map +1 -1
- package/build/lib/mutation.js +73 -107
- package/build/lib/mutation.js.map +1 -1
- package/build/lib/mutation.mjs +73 -105
- package/build/lib/mutation.mjs.map +1 -1
- package/build/lib/mutationCache.d.ts +4 -6
- package/build/lib/mutationCache.esm.js +23 -32
- package/build/lib/mutationCache.esm.js.map +1 -1
- package/build/lib/mutationCache.js +23 -34
- package/build/lib/mutationCache.js.map +1 -1
- package/build/lib/mutationCache.mjs +23 -32
- package/build/lib/mutationCache.mjs.map +1 -1
- package/build/lib/mutationObserver.d.ts +4 -9
- package/build/lib/mutationObserver.esm.js +43 -72
- package/build/lib/mutationObserver.esm.js.map +1 -1
- package/build/lib/mutationObserver.js +43 -74
- package/build/lib/mutationObserver.js.map +1 -1
- package/build/lib/mutationObserver.mjs +43 -72
- package/build/lib/mutationObserver.mjs.map +1 -1
- package/build/lib/notifyManager.esm.js +7 -17
- package/build/lib/notifyManager.esm.js.map +1 -1
- package/build/lib/notifyManager.js +7 -19
- package/build/lib/notifyManager.js.map +1 -1
- package/build/lib/notifyManager.mjs +7 -17
- package/build/lib/notifyManager.mjs.map +1 -1
- package/build/lib/onlineManager.d.ts +1 -3
- package/build/lib/onlineManager.esm.js +16 -30
- package/build/lib/onlineManager.esm.js.map +1 -1
- package/build/lib/onlineManager.js +16 -32
- package/build/lib/onlineManager.js.map +1 -1
- package/build/lib/onlineManager.mjs +16 -30
- package/build/lib/onlineManager.mjs.map +1 -1
- package/build/lib/queriesObserver.d.ts +3 -10
- package/build/lib/queriesObserver.esm.js +47 -71
- package/build/lib/queriesObserver.esm.js.map +1 -1
- package/build/lib/queriesObserver.js +49 -75
- package/build/lib/queriesObserver.js.map +1 -1
- package/build/lib/queriesObserver.mjs +47 -71
- package/build/lib/queriesObserver.mjs.map +1 -1
- package/build/lib/query.d.ts +14 -21
- package/build/lib/query.esm.js +140 -194
- package/build/lib/query.esm.js.map +1 -1
- package/build/lib/query.js +139 -195
- package/build/lib/query.js.map +1 -1
- package/build/lib/query.mjs +140 -194
- package/build/lib/query.mjs.map +1 -1
- package/build/lib/queryCache.d.ts +12 -7
- package/build/lib/queryCache.esm.js +21 -45
- package/build/lib/queryCache.esm.js.map +1 -1
- package/build/lib/queryCache.js +20 -46
- package/build/lib/queryCache.js.map +1 -1
- package/build/lib/queryCache.mjs +21 -45
- package/build/lib/queryCache.mjs.map +1 -1
- package/build/lib/queryClient.d.ts +18 -46
- package/build/lib/queryClient.esm.js +137 -216
- package/build/lib/queryClient.esm.js.map +1 -1
- package/build/lib/queryClient.js +136 -217
- package/build/lib/queryClient.js.map +1 -1
- package/build/lib/queryClient.mjs +137 -216
- package/build/lib/queryClient.mjs.map +1 -1
- package/build/lib/queryObserver.d.ts +4 -29
- package/build/lib/queryObserver.esm.js +176 -258
- package/build/lib/queryObserver.esm.js.map +1 -1
- package/build/lib/queryObserver.js +176 -260
- package/build/lib/queryObserver.js.map +1 -1
- package/build/lib/queryObserver.mjs +176 -258
- package/build/lib/queryObserver.mjs.map +1 -1
- package/build/lib/removable.d.ts +3 -3
- package/build/lib/removable.esm.js +10 -14
- package/build/lib/removable.esm.js.map +1 -1
- package/build/lib/removable.js +10 -16
- package/build/lib/removable.js.map +1 -1
- package/build/lib/removable.mjs +10 -14
- package/build/lib/removable.mjs.map +1 -1
- package/build/lib/retryer.d.ts +5 -5
- package/build/lib/retryer.esm.js +27 -44
- package/build/lib/retryer.esm.js.map +1 -1
- package/build/lib/retryer.js +27 -46
- package/build/lib/retryer.js.map +1 -1
- package/build/lib/retryer.mjs +27 -44
- package/build/lib/retryer.mjs.map +1 -1
- package/build/lib/subscribable.esm.js +4 -7
- package/build/lib/subscribable.esm.js.map +1 -1
- package/build/lib/subscribable.js +4 -9
- package/build/lib/subscribable.js.map +1 -1
- package/build/lib/subscribable.mjs +4 -7
- package/build/lib/subscribable.mjs.map +1 -1
- package/build/lib/tests/utils.d.ts +3 -12
- package/build/lib/types.d.ts +111 -99
- package/build/lib/utils.d.ts +8 -18
- package/build/lib/utils.esm.js +39 -132
- package/build/lib/utils.esm.js.map +1 -1
- package/build/lib/utils.js +42 -144
- package/build/lib/utils.js.map +1 -1
- package/build/lib/utils.mjs +39 -132
- package/build/lib/utils.mjs.map +1 -1
- package/build/umd/index.development.js +868 -1398
- 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/focusManager.ts +17 -24
- package/src/index.ts +1 -11
- package/src/infiniteQueryBehavior.ts +54 -94
- package/src/infiniteQueryObserver.ts +10 -12
- package/src/mutation.ts +68 -92
- package/src/mutationCache.ts +27 -27
- package/src/mutationObserver.ts +60 -97
- package/src/onlineManager.ts +14 -14
- package/src/queriesObserver.ts +50 -54
- package/src/query.ts +106 -110
- package/src/queryCache.ts +42 -41
- package/src/queryClient.ts +155 -434
- package/src/queryObserver.ts +155 -192
- package/src/removable.ts +13 -13
- package/src/retryer.ts +5 -5
- package/src/tests/focusManager.test.tsx +25 -25
- package/src/tests/hydration.test.tsx +167 -81
- package/src/tests/infiniteQueryBehavior.test.tsx +209 -17
- package/src/tests/infiniteQueryObserver.test.tsx +6 -2
- package/src/tests/mutationCache.test.tsx +127 -127
- package/src/tests/mutationObserver.test.tsx +1 -31
- package/src/tests/mutations.test.tsx +62 -43
- package/src/tests/onlineManager.test.tsx +12 -4
- package/src/tests/queriesObserver.test.tsx +41 -77
- package/src/tests/query.test.tsx +175 -243
- package/src/tests/queryCache.test.tsx +170 -93
- package/src/tests/queryClient.test.tsx +229 -378
- package/src/tests/queryObserver.test.tsx +23 -147
- package/src/tests/utils.test.tsx +84 -29
- package/src/tests/utils.ts +9 -18
- package/src/types.ts +187 -140
- package/src/utils.ts +31 -124
- package/build/lib/logger.d.ts +0 -8
- package/build/lib/logger.esm.js +0 -4
- package/build/lib/logger.esm.js.map +0 -1
- package/build/lib/logger.js +0 -8
- package/build/lib/logger.js.map +0 -1
- package/build/lib/logger.mjs +0 -4
- package/build/lib/logger.mjs.map +0 -1
- package/build/lib/logger.native.d.ts +0 -6
- package/build/lib/logger.native.esm.js +0 -12
- package/build/lib/logger.native.esm.js.map +0 -1
- package/build/lib/logger.native.js +0 -16
- package/build/lib/logger.native.js.map +0 -1
- package/build/lib/logger.native.mjs +0 -12
- package/build/lib/logger.native.mjs.map +0 -1
- package/src/logger.native.ts +0 -11
- package/src/logger.ts +0 -9
package/src/removable.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isServer, isValidTimeout } from './utils'
|
|
2
2
|
|
|
3
3
|
export abstract class Removable {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
gcTime!: number
|
|
5
|
+
#gcTimeout?: ReturnType<typeof setTimeout>
|
|
6
6
|
|
|
7
7
|
destroy(): void {
|
|
8
8
|
this.clearGcTimeout()
|
|
@@ -11,25 +11,25 @@ export abstract class Removable {
|
|
|
11
11
|
protected scheduleGc(): void {
|
|
12
12
|
this.clearGcTimeout()
|
|
13
13
|
|
|
14
|
-
if (isValidTimeout(this.
|
|
15
|
-
this
|
|
14
|
+
if (isValidTimeout(this.gcTime)) {
|
|
15
|
+
this.#gcTimeout = setTimeout(() => {
|
|
16
16
|
this.optionalRemove()
|
|
17
|
-
}, this.
|
|
17
|
+
}, this.gcTime)
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
protected
|
|
22
|
-
// Default to 5 minutes (Infinity for server-side) if no
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
|
|
21
|
+
protected updateGcTime(newGcTime: number | undefined): void {
|
|
22
|
+
// Default to 5 minutes (Infinity for server-side) if no gcTime is set
|
|
23
|
+
this.gcTime = Math.max(
|
|
24
|
+
this.gcTime || 0,
|
|
25
|
+
newGcTime ?? (isServer ? Infinity : 5 * 60 * 1000),
|
|
26
26
|
)
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
protected clearGcTimeout() {
|
|
30
|
-
if (this
|
|
31
|
-
clearTimeout(this
|
|
32
|
-
this
|
|
30
|
+
if (this.#gcTimeout) {
|
|
31
|
+
clearTimeout(this.#gcTimeout)
|
|
32
|
+
this.#gcTimeout = undefined
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
package/src/retryer.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { focusManager } from './focusManager'
|
|
2
2
|
import { onlineManager } from './onlineManager'
|
|
3
3
|
import { sleep } from './utils'
|
|
4
|
-
import type { CancelOptions, NetworkMode } from './types'
|
|
4
|
+
import type { CancelOptions, NetworkMode, RegisteredError } from './types'
|
|
5
5
|
|
|
6
6
|
// TYPES
|
|
7
7
|
|
|
8
|
-
interface RetryerConfig<TData = unknown, TError =
|
|
8
|
+
interface RetryerConfig<TData = unknown, TError = RegisteredError> {
|
|
9
9
|
fn: () => TData | Promise<TData>
|
|
10
10
|
abort?: () => void
|
|
11
11
|
onError?: (error: TError) => void
|
|
@@ -28,14 +28,14 @@ export interface Retryer<TData = unknown> {
|
|
|
28
28
|
|
|
29
29
|
export type RetryValue<TError> = boolean | number | ShouldRetryFunction<TError>
|
|
30
30
|
|
|
31
|
-
type ShouldRetryFunction<TError> = (
|
|
31
|
+
type ShouldRetryFunction<TError = RegisteredError> = (
|
|
32
32
|
failureCount: number,
|
|
33
33
|
error: TError,
|
|
34
34
|
) => boolean
|
|
35
35
|
|
|
36
36
|
export type RetryDelayValue<TError> = number | RetryDelayFunction<TError>
|
|
37
37
|
|
|
38
|
-
type RetryDelayFunction<TError =
|
|
38
|
+
type RetryDelayFunction<TError = RegisteredError> = (
|
|
39
39
|
failureCount: number,
|
|
40
40
|
error: TError,
|
|
41
41
|
) => number
|
|
@@ -63,7 +63,7 @@ export function isCancelledError(value: any): value is CancelledError {
|
|
|
63
63
|
return value instanceof CancelledError
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
export function createRetryer<TData = unknown, TError =
|
|
66
|
+
export function createRetryer<TData = unknown, TError = RegisteredError>(
|
|
67
67
|
config: RetryerConfig<TData, TError>,
|
|
68
68
|
): Retryer<TData> {
|
|
69
69
|
let isRetryCancelled = false
|
|
@@ -63,55 +63,55 @@ describe('focusManager', () => {
|
|
|
63
63
|
globalThis.document = document
|
|
64
64
|
})
|
|
65
65
|
|
|
66
|
-
test('cleanup should
|
|
66
|
+
test('cleanup (removeEventListener) should not be called if window is not defined', async () => {
|
|
67
67
|
const restoreIsServer = setIsServer(true)
|
|
68
68
|
|
|
69
|
+
const removeEventListenerSpy = jest.spyOn(globalThis, 'removeEventListener')
|
|
70
|
+
|
|
69
71
|
const unsubscribe = focusManager.subscribe(() => undefined)
|
|
70
|
-
expect(focusManager['cleanup']).toBeUndefined()
|
|
71
72
|
|
|
72
73
|
unsubscribe()
|
|
74
|
+
|
|
75
|
+
expect(removeEventListenerSpy).not.toHaveBeenCalled()
|
|
76
|
+
|
|
73
77
|
restoreIsServer()
|
|
74
78
|
})
|
|
75
79
|
|
|
76
|
-
test('cleanup should
|
|
80
|
+
test('cleanup (removeEventListener) should not be called if window.addEventListener is not defined', async () => {
|
|
77
81
|
const { addEventListener } = globalThis.window
|
|
78
82
|
|
|
79
83
|
// @ts-expect-error
|
|
80
84
|
globalThis.window.addEventListener = undefined
|
|
81
85
|
|
|
86
|
+
const removeEventListenerSpy = jest.spyOn(globalThis, 'removeEventListener')
|
|
87
|
+
|
|
82
88
|
const unsubscribe = focusManager.subscribe(() => undefined)
|
|
83
|
-
expect(focusManager['cleanup']).toBeUndefined()
|
|
84
89
|
|
|
85
90
|
unsubscribe()
|
|
91
|
+
|
|
92
|
+
expect(removeEventListenerSpy).not.toHaveBeenCalled()
|
|
93
|
+
|
|
86
94
|
globalThis.window.addEventListener = addEventListener
|
|
87
95
|
})
|
|
88
96
|
|
|
89
97
|
it('should replace default window listener when a new event listener is set', async () => {
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
'addEventListener',
|
|
93
|
-
)
|
|
98
|
+
const unsubscribeSpy = jest.fn().mockImplementation(() => undefined)
|
|
99
|
+
const handlerSpy = jest.fn().mockImplementation(() => unsubscribeSpy)
|
|
94
100
|
|
|
95
|
-
|
|
96
|
-
globalThis.window,
|
|
97
|
-
'removeEventListener',
|
|
98
|
-
)
|
|
101
|
+
focusManager.setEventListener(() => handlerSpy())
|
|
99
102
|
|
|
100
|
-
// Should set the default event listener with window event listeners
|
|
101
103
|
const unsubscribe = focusManager.subscribe(() => undefined)
|
|
102
|
-
expect(addEventListenerSpy).toHaveBeenCalledTimes(2)
|
|
103
104
|
|
|
104
|
-
// Should
|
|
105
|
-
|
|
106
|
-
focusManager.setEventListener(() => {
|
|
107
|
-
return () => void 0
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
expect(removeEventListenerSpy).toHaveBeenCalledTimes(2)
|
|
105
|
+
// Should call the custom event once
|
|
106
|
+
expect(handlerSpy).toHaveBeenCalledTimes(1)
|
|
111
107
|
|
|
112
108
|
unsubscribe()
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
|
|
110
|
+
// Should unsubscribe our event event
|
|
111
|
+
expect(unsubscribeSpy).toHaveBeenCalledTimes(1)
|
|
112
|
+
|
|
113
|
+
handlerSpy.mockRestore()
|
|
114
|
+
unsubscribeSpy.mockRestore()
|
|
115
115
|
})
|
|
116
116
|
|
|
117
117
|
test('should call removeEventListener when last listener unsubscribes', () => {
|
|
@@ -127,12 +127,12 @@ describe('focusManager', () => {
|
|
|
127
127
|
|
|
128
128
|
const unsubscribe1 = focusManager.subscribe(() => undefined)
|
|
129
129
|
const unsubscribe2 = focusManager.subscribe(() => undefined)
|
|
130
|
-
expect(addEventListenerSpy).toHaveBeenCalledTimes(
|
|
130
|
+
expect(addEventListenerSpy).toHaveBeenCalledTimes(1) // visibilitychange event
|
|
131
131
|
|
|
132
132
|
unsubscribe1()
|
|
133
133
|
expect(removeEventListenerSpy).toHaveBeenCalledTimes(0)
|
|
134
134
|
unsubscribe2()
|
|
135
|
-
expect(removeEventListenerSpy).toHaveBeenCalledTimes(
|
|
135
|
+
expect(removeEventListenerSpy).toHaveBeenCalledTimes(1) // visibilitychange event
|
|
136
136
|
})
|
|
137
137
|
|
|
138
138
|
test('should keep setup function even if last listener unsubscribes', () => {
|
|
@@ -16,14 +16,30 @@ describe('dehydration and rehydration', () => {
|
|
|
16
16
|
test('should work with serializeable values', async () => {
|
|
17
17
|
const queryCache = new QueryCache()
|
|
18
18
|
const queryClient = createQueryClient({ queryCache })
|
|
19
|
-
await queryClient.prefetchQuery(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
await queryClient.prefetchQuery(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
)
|
|
19
|
+
await queryClient.prefetchQuery({
|
|
20
|
+
queryKey: ['string'],
|
|
21
|
+
queryFn: () => fetchData('string'),
|
|
22
|
+
})
|
|
23
|
+
await queryClient.prefetchQuery({
|
|
24
|
+
queryKey: ['number'],
|
|
25
|
+
queryFn: () => fetchData(1),
|
|
26
|
+
})
|
|
27
|
+
await queryClient.prefetchQuery({
|
|
28
|
+
queryKey: ['boolean'],
|
|
29
|
+
queryFn: () => fetchData(true),
|
|
30
|
+
})
|
|
31
|
+
await queryClient.prefetchQuery({
|
|
32
|
+
queryKey: ['null'],
|
|
33
|
+
queryFn: () => fetchData(null),
|
|
34
|
+
})
|
|
35
|
+
await queryClient.prefetchQuery({
|
|
36
|
+
queryKey: ['array'],
|
|
37
|
+
queryFn: () => fetchData(['string', 0]),
|
|
38
|
+
})
|
|
39
|
+
await queryClient.prefetchQuery({
|
|
40
|
+
queryKey: ['nested'],
|
|
41
|
+
queryFn: () => fetchData({ key: [{ nestedKey: 1 }] }),
|
|
42
|
+
})
|
|
27
43
|
const dehydrated = dehydrate(queryClient)
|
|
28
44
|
const stringified = JSON.stringify(dehydrated)
|
|
29
45
|
|
|
@@ -35,32 +51,51 @@ describe('dehydration and rehydration', () => {
|
|
|
35
51
|
queryCache: hydrationCache,
|
|
36
52
|
})
|
|
37
53
|
hydrate(hydrationClient, parsed)
|
|
38
|
-
expect(hydrationCache.find(['string'])?.state.data).toBe(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
expect(hydrationCache.find(['
|
|
42
|
-
expect(hydrationCache.find(['
|
|
43
|
-
|
|
54
|
+
expect(hydrationCache.find({ queryKey: ['string'] })?.state.data).toBe(
|
|
55
|
+
'string',
|
|
56
|
+
)
|
|
57
|
+
expect(hydrationCache.find({ queryKey: ['number'] })?.state.data).toBe(1)
|
|
58
|
+
expect(hydrationCache.find({ queryKey: ['boolean'] })?.state.data).toBe(
|
|
59
|
+
true,
|
|
60
|
+
)
|
|
61
|
+
expect(hydrationCache.find({ queryKey: ['null'] })?.state.data).toBe(null)
|
|
62
|
+
expect(hydrationCache.find({ queryKey: ['array'] })?.state.data).toEqual([
|
|
63
|
+
'string',
|
|
64
|
+
0,
|
|
65
|
+
])
|
|
66
|
+
expect(hydrationCache.find({ queryKey: ['nested'] })?.state.data).toEqual({
|
|
44
67
|
key: [{ nestedKey: 1 }],
|
|
45
68
|
})
|
|
46
69
|
|
|
47
70
|
const fetchDataAfterHydration = jest.fn<unknown, unknown[]>()
|
|
48
|
-
await hydrationClient.prefetchQuery(
|
|
71
|
+
await hydrationClient.prefetchQuery({
|
|
72
|
+
queryKey: ['string'],
|
|
73
|
+
queryFn: fetchDataAfterHydration,
|
|
49
74
|
staleTime: 1000,
|
|
50
75
|
})
|
|
51
|
-
await hydrationClient.prefetchQuery(
|
|
76
|
+
await hydrationClient.prefetchQuery({
|
|
77
|
+
queryKey: ['number'],
|
|
78
|
+
queryFn: fetchDataAfterHydration,
|
|
52
79
|
staleTime: 1000,
|
|
53
80
|
})
|
|
54
|
-
await hydrationClient.prefetchQuery(
|
|
81
|
+
await hydrationClient.prefetchQuery({
|
|
82
|
+
queryKey: ['boolean'],
|
|
83
|
+
queryFn: fetchDataAfterHydration,
|
|
55
84
|
staleTime: 1000,
|
|
56
85
|
})
|
|
57
|
-
await hydrationClient.prefetchQuery(
|
|
86
|
+
await hydrationClient.prefetchQuery({
|
|
87
|
+
queryKey: ['null'],
|
|
88
|
+
queryFn: fetchDataAfterHydration,
|
|
58
89
|
staleTime: 1000,
|
|
59
90
|
})
|
|
60
|
-
await hydrationClient.prefetchQuery(
|
|
91
|
+
await hydrationClient.prefetchQuery({
|
|
92
|
+
queryKey: ['array'],
|
|
93
|
+
queryFn: fetchDataAfterHydration,
|
|
61
94
|
staleTime: 1000,
|
|
62
95
|
})
|
|
63
|
-
await hydrationClient.prefetchQuery(
|
|
96
|
+
await hydrationClient.prefetchQuery({
|
|
97
|
+
queryKey: ['nested'],
|
|
98
|
+
queryFn: fetchDataAfterHydration,
|
|
64
99
|
staleTime: 1000,
|
|
65
100
|
})
|
|
66
101
|
expect(fetchDataAfterHydration).toHaveBeenCalledTimes(0)
|
|
@@ -72,7 +107,10 @@ describe('dehydration and rehydration', () => {
|
|
|
72
107
|
test('should not dehydrate queries if dehydrateQueries is set to false', async () => {
|
|
73
108
|
const queryCache = new QueryCache()
|
|
74
109
|
const queryClient = createQueryClient({ queryCache })
|
|
75
|
-
await queryClient.prefetchQuery(
|
|
110
|
+
await queryClient.prefetchQuery({
|
|
111
|
+
queryKey: ['string'],
|
|
112
|
+
queryFn: () => fetchData('string'),
|
|
113
|
+
})
|
|
76
114
|
|
|
77
115
|
const dehydrated = dehydrate(queryClient, { dehydrateQueries: false })
|
|
78
116
|
|
|
@@ -81,11 +119,13 @@ describe('dehydration and rehydration', () => {
|
|
|
81
119
|
queryClient.clear()
|
|
82
120
|
})
|
|
83
121
|
|
|
84
|
-
test('should use the
|
|
122
|
+
test('should use the garbage collection time from the client', async () => {
|
|
85
123
|
const queryCache = new QueryCache()
|
|
86
124
|
const queryClient = createQueryClient({ queryCache })
|
|
87
|
-
await queryClient.prefetchQuery(
|
|
88
|
-
|
|
125
|
+
await queryClient.prefetchQuery({
|
|
126
|
+
queryKey: ['string'],
|
|
127
|
+
queryFn: () => fetchData('string'),
|
|
128
|
+
gcTime: 50,
|
|
89
129
|
})
|
|
90
130
|
const dehydrated = dehydrate(queryClient)
|
|
91
131
|
const stringified = JSON.stringify(dehydrated)
|
|
@@ -98,9 +138,11 @@ describe('dehydration and rehydration', () => {
|
|
|
98
138
|
const hydrationCache = new QueryCache()
|
|
99
139
|
const hydrationClient = createQueryClient({ queryCache: hydrationCache })
|
|
100
140
|
hydrate(hydrationClient, parsed)
|
|
101
|
-
expect(hydrationCache.find(['string'])?.state.data).toBe(
|
|
141
|
+
expect(hydrationCache.find({ queryKey: ['string'] })?.state.data).toBe(
|
|
142
|
+
'string',
|
|
143
|
+
)
|
|
102
144
|
await sleep(100)
|
|
103
|
-
expect(hydrationCache.find(['string'])).toBeTruthy()
|
|
145
|
+
expect(hydrationCache.find({ queryKey: ['string'] })).toBeTruthy()
|
|
104
146
|
|
|
105
147
|
queryClient.clear()
|
|
106
148
|
hydrationClient.clear()
|
|
@@ -109,7 +151,10 @@ describe('dehydration and rehydration', () => {
|
|
|
109
151
|
test('should be able to provide default options for the hydrated queries', async () => {
|
|
110
152
|
const queryCache = new QueryCache()
|
|
111
153
|
const queryClient = createQueryClient({ queryCache })
|
|
112
|
-
await queryClient.prefetchQuery(
|
|
154
|
+
await queryClient.prefetchQuery({
|
|
155
|
+
queryKey: ['string'],
|
|
156
|
+
queryFn: () => fetchData('string'),
|
|
157
|
+
})
|
|
113
158
|
const dehydrated = dehydrate(queryClient)
|
|
114
159
|
const stringified = JSON.stringify(dehydrated)
|
|
115
160
|
const parsed = JSON.parse(stringified)
|
|
@@ -118,7 +163,9 @@ describe('dehydration and rehydration', () => {
|
|
|
118
163
|
hydrate(hydrationClient, parsed, {
|
|
119
164
|
defaultOptions: { queries: { retry: 10 } },
|
|
120
165
|
})
|
|
121
|
-
expect(hydrationCache.find(['string'])?.options.retry).toBe(
|
|
166
|
+
expect(hydrationCache.find({ queryKey: ['string'] })?.options.retry).toBe(
|
|
167
|
+
10,
|
|
168
|
+
)
|
|
122
169
|
queryClient.clear()
|
|
123
170
|
hydrationClient.clear()
|
|
124
171
|
})
|
|
@@ -126,10 +173,10 @@ describe('dehydration and rehydration', () => {
|
|
|
126
173
|
test('should work with complex keys', async () => {
|
|
127
174
|
const queryCache = new QueryCache()
|
|
128
175
|
const queryClient = createQueryClient({ queryCache })
|
|
129
|
-
await queryClient.prefetchQuery(
|
|
130
|
-
['string', { key: ['string'], key2: 0 }],
|
|
131
|
-
() => fetchData('string'),
|
|
132
|
-
)
|
|
176
|
+
await queryClient.prefetchQuery({
|
|
177
|
+
queryKey: ['string', { key: ['string'], key2: 0 }],
|
|
178
|
+
queryFn: () => fetchData('string'),
|
|
179
|
+
})
|
|
133
180
|
const dehydrated = dehydrate(queryClient)
|
|
134
181
|
const stringified = JSON.stringify(dehydrated)
|
|
135
182
|
|
|
@@ -140,15 +187,17 @@ describe('dehydration and rehydration', () => {
|
|
|
140
187
|
const hydrationClient = createQueryClient({ queryCache: hydrationCache })
|
|
141
188
|
hydrate(hydrationClient, parsed)
|
|
142
189
|
expect(
|
|
143
|
-
hydrationCache.find(
|
|
190
|
+
hydrationCache.find({
|
|
191
|
+
queryKey: ['string', { key: ['string'], key2: 0 }],
|
|
192
|
+
})?.state.data,
|
|
144
193
|
).toBe('string')
|
|
145
194
|
|
|
146
195
|
const fetchDataAfterHydration = jest.fn<unknown, unknown[]>()
|
|
147
|
-
await hydrationClient.prefetchQuery(
|
|
148
|
-
['string', { key: ['string'], key2: 0 }],
|
|
149
|
-
fetchDataAfterHydration,
|
|
150
|
-
|
|
151
|
-
)
|
|
196
|
+
await hydrationClient.prefetchQuery({
|
|
197
|
+
queryKey: ['string', { key: ['string'], key2: 0 }],
|
|
198
|
+
queryFn: fetchDataAfterHydration,
|
|
199
|
+
staleTime: 100,
|
|
200
|
+
})
|
|
152
201
|
expect(fetchDataAfterHydration).toHaveBeenCalledTimes(0)
|
|
153
202
|
|
|
154
203
|
queryClient.clear()
|
|
@@ -161,10 +210,19 @@ describe('dehydration and rehydration', () => {
|
|
|
161
210
|
|
|
162
211
|
const queryCache = new QueryCache()
|
|
163
212
|
const queryClient = createQueryClient({ queryCache })
|
|
164
|
-
await queryClient.prefetchQuery(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
213
|
+
await queryClient.prefetchQuery({
|
|
214
|
+
queryKey: ['success'],
|
|
215
|
+
queryFn: () => fetchData('success'),
|
|
216
|
+
})
|
|
217
|
+
queryClient.prefetchQuery({
|
|
218
|
+
queryKey: ['loading'],
|
|
219
|
+
queryFn: () => fetchData('loading', 10000),
|
|
220
|
+
})
|
|
221
|
+
await queryClient.prefetchQuery({
|
|
222
|
+
queryKey: ['error'],
|
|
223
|
+
queryFn: () => {
|
|
224
|
+
throw new Error()
|
|
225
|
+
},
|
|
168
226
|
})
|
|
169
227
|
const dehydrated = dehydrate(queryClient)
|
|
170
228
|
const stringified = JSON.stringify(dehydrated)
|
|
@@ -176,9 +234,9 @@ describe('dehydration and rehydration', () => {
|
|
|
176
234
|
const hydrationClient = createQueryClient({ queryCache: hydrationCache })
|
|
177
235
|
hydrate(hydrationClient, parsed)
|
|
178
236
|
|
|
179
|
-
expect(hydrationCache.find(['success'])).toBeTruthy()
|
|
180
|
-
expect(hydrationCache.find(['loading'])).toBeFalsy()
|
|
181
|
-
expect(hydrationCache.find(['error'])).toBeFalsy()
|
|
237
|
+
expect(hydrationCache.find({ queryKey: ['success'] })).toBeTruthy()
|
|
238
|
+
expect(hydrationCache.find({ queryKey: ['loading'] })).toBeFalsy()
|
|
239
|
+
expect(hydrationCache.find({ queryKey: ['error'] })).toBeFalsy()
|
|
182
240
|
|
|
183
241
|
queryClient.clear()
|
|
184
242
|
hydrationClient.clear()
|
|
@@ -188,8 +246,14 @@ describe('dehydration and rehydration', () => {
|
|
|
188
246
|
test('should filter queries via shouldDehydrateQuery', async () => {
|
|
189
247
|
const queryCache = new QueryCache()
|
|
190
248
|
const queryClient = createQueryClient({ queryCache })
|
|
191
|
-
await queryClient.prefetchQuery(
|
|
192
|
-
|
|
249
|
+
await queryClient.prefetchQuery({
|
|
250
|
+
queryKey: ['string'],
|
|
251
|
+
queryFn: () => fetchData('string'),
|
|
252
|
+
})
|
|
253
|
+
await queryClient.prefetchQuery({
|
|
254
|
+
queryKey: ['number'],
|
|
255
|
+
queryFn: () => fetchData(1),
|
|
256
|
+
})
|
|
193
257
|
const dehydrated = dehydrate(queryClient, {
|
|
194
258
|
shouldDehydrateQuery: (query) => query.queryKey[0] !== 'string',
|
|
195
259
|
})
|
|
@@ -209,8 +273,8 @@ describe('dehydration and rehydration', () => {
|
|
|
209
273
|
const hydrationCache = new QueryCache()
|
|
210
274
|
const hydrationClient = createQueryClient({ queryCache: hydrationCache })
|
|
211
275
|
hydrate(hydrationClient, parsed)
|
|
212
|
-
expect(hydrationCache.find(['string'])).toBeUndefined()
|
|
213
|
-
expect(hydrationCache.find(['number'])?.state.data).toBe(1)
|
|
276
|
+
expect(hydrationCache.find({ queryKey: ['string'] })).toBeUndefined()
|
|
277
|
+
expect(hydrationCache.find({ queryKey: ['number'] })?.state.data).toBe(1)
|
|
214
278
|
|
|
215
279
|
queryClient.clear()
|
|
216
280
|
hydrationClient.clear()
|
|
@@ -219,9 +283,10 @@ describe('dehydration and rehydration', () => {
|
|
|
219
283
|
test('should not overwrite query in cache if hydrated query is older', async () => {
|
|
220
284
|
const queryCache = new QueryCache()
|
|
221
285
|
const queryClient = createQueryClient({ queryCache })
|
|
222
|
-
await queryClient.prefetchQuery(
|
|
223
|
-
|
|
224
|
-
|
|
286
|
+
await queryClient.prefetchQuery({
|
|
287
|
+
queryKey: ['string'],
|
|
288
|
+
queryFn: () => fetchData('string-older', 5),
|
|
289
|
+
})
|
|
225
290
|
const dehydrated = dehydrate(queryClient)
|
|
226
291
|
const stringified = JSON.stringify(dehydrated)
|
|
227
292
|
|
|
@@ -230,12 +295,15 @@ describe('dehydration and rehydration', () => {
|
|
|
230
295
|
const parsed = JSON.parse(stringified)
|
|
231
296
|
const hydrationCache = new QueryCache()
|
|
232
297
|
const hydrationClient = createQueryClient({ queryCache: hydrationCache })
|
|
233
|
-
await hydrationClient.prefetchQuery(
|
|
234
|
-
|
|
235
|
-
|
|
298
|
+
await hydrationClient.prefetchQuery({
|
|
299
|
+
queryKey: ['string'],
|
|
300
|
+
queryFn: () => fetchData('string-newer', 5),
|
|
301
|
+
})
|
|
236
302
|
|
|
237
303
|
hydrate(hydrationClient, parsed)
|
|
238
|
-
expect(hydrationCache.find(['string'])?.state.data).toBe(
|
|
304
|
+
expect(hydrationCache.find({ queryKey: ['string'] })?.state.data).toBe(
|
|
305
|
+
'string-newer',
|
|
306
|
+
)
|
|
239
307
|
|
|
240
308
|
queryClient.clear()
|
|
241
309
|
hydrationClient.clear()
|
|
@@ -244,17 +312,19 @@ describe('dehydration and rehydration', () => {
|
|
|
244
312
|
test('should overwrite query in cache if hydrated query is newer', async () => {
|
|
245
313
|
const hydrationCache = new QueryCache()
|
|
246
314
|
const hydrationClient = createQueryClient({ queryCache: hydrationCache })
|
|
247
|
-
await hydrationClient.prefetchQuery(
|
|
248
|
-
|
|
249
|
-
|
|
315
|
+
await hydrationClient.prefetchQuery({
|
|
316
|
+
queryKey: ['string'],
|
|
317
|
+
queryFn: () => fetchData('string-older', 5),
|
|
318
|
+
})
|
|
250
319
|
|
|
251
320
|
// ---
|
|
252
321
|
|
|
253
322
|
const queryCache = new QueryCache()
|
|
254
323
|
const queryClient = createQueryClient({ queryCache })
|
|
255
|
-
await queryClient.prefetchQuery(
|
|
256
|
-
|
|
257
|
-
|
|
324
|
+
await queryClient.prefetchQuery({
|
|
325
|
+
queryKey: ['string'],
|
|
326
|
+
queryFn: () => fetchData('string-newer', 5),
|
|
327
|
+
})
|
|
258
328
|
const dehydrated = dehydrate(queryClient)
|
|
259
329
|
const stringified = JSON.stringify(dehydrated)
|
|
260
330
|
|
|
@@ -262,7 +332,9 @@ describe('dehydration and rehydration', () => {
|
|
|
262
332
|
|
|
263
333
|
const parsed = JSON.parse(stringified)
|
|
264
334
|
hydrate(hydrationClient, parsed)
|
|
265
|
-
expect(hydrationCache.find(['string'])?.state.data).toBe(
|
|
335
|
+
expect(hydrationCache.find({ queryKey: ['string'] })?.state.data).toBe(
|
|
336
|
+
'string-newer',
|
|
337
|
+
)
|
|
266
338
|
|
|
267
339
|
queryClient.clear()
|
|
268
340
|
hydrationClient.clear()
|
|
@@ -275,7 +347,7 @@ describe('dehydration and rehydration', () => {
|
|
|
275
347
|
|
|
276
348
|
const serverAddTodo = jest
|
|
277
349
|
.fn()
|
|
278
|
-
.mockImplementation(() => Promise.reject('offline'))
|
|
350
|
+
.mockImplementation(() => Promise.reject(new Error('offline')))
|
|
279
351
|
const serverOnMutate = jest.fn().mockImplementation((variables) => {
|
|
280
352
|
const optimisticTodo = { id: 1, text: variables.text }
|
|
281
353
|
return { optimisticTodo }
|
|
@@ -292,10 +364,13 @@ describe('dehydration and rehydration', () => {
|
|
|
292
364
|
retryDelay: 10,
|
|
293
365
|
})
|
|
294
366
|
|
|
295
|
-
executeMutation(
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
367
|
+
executeMutation(
|
|
368
|
+
serverClient,
|
|
369
|
+
{
|
|
370
|
+
mutationKey: ['addTodo'],
|
|
371
|
+
},
|
|
372
|
+
{ text: 'text' },
|
|
373
|
+
).catch(() => undefined)
|
|
299
374
|
|
|
300
375
|
await sleep(50)
|
|
301
376
|
|
|
@@ -352,7 +427,7 @@ describe('dehydration and rehydration', () => {
|
|
|
352
427
|
|
|
353
428
|
const serverAddTodo = jest
|
|
354
429
|
.fn()
|
|
355
|
-
.mockImplementation(() => Promise.reject('offline'))
|
|
430
|
+
.mockImplementation(() => Promise.reject(new Error('offline')))
|
|
356
431
|
|
|
357
432
|
const queryClient = createQueryClient()
|
|
358
433
|
|
|
@@ -361,10 +436,13 @@ describe('dehydration and rehydration', () => {
|
|
|
361
436
|
retry: false,
|
|
362
437
|
})
|
|
363
438
|
|
|
364
|
-
executeMutation(
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
439
|
+
executeMutation(
|
|
440
|
+
queryClient,
|
|
441
|
+
{
|
|
442
|
+
mutationKey: ['addTodo'],
|
|
443
|
+
},
|
|
444
|
+
{ text: 'text' },
|
|
445
|
+
).catch(() => undefined)
|
|
368
446
|
|
|
369
447
|
await sleep(1)
|
|
370
448
|
const dehydrated = dehydrate(queryClient, { dehydrateMutations: false })
|
|
@@ -381,7 +459,7 @@ describe('dehydration and rehydration', () => {
|
|
|
381
459
|
|
|
382
460
|
const serverAddTodo = jest
|
|
383
461
|
.fn()
|
|
384
|
-
.mockImplementation(() => Promise.reject('offline'))
|
|
462
|
+
.mockImplementation(() => Promise.reject(new Error('offline')))
|
|
385
463
|
|
|
386
464
|
const queryClient = createQueryClient()
|
|
387
465
|
|
|
@@ -391,10 +469,13 @@ describe('dehydration and rehydration', () => {
|
|
|
391
469
|
retryDelay: 20,
|
|
392
470
|
})
|
|
393
471
|
|
|
394
|
-
executeMutation(
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
472
|
+
executeMutation(
|
|
473
|
+
queryClient,
|
|
474
|
+
{
|
|
475
|
+
mutationKey: ['addTodo'],
|
|
476
|
+
},
|
|
477
|
+
{ text: 'text' },
|
|
478
|
+
).catch(() => undefined)
|
|
398
479
|
|
|
399
480
|
// Dehydrate mutation between retries
|
|
400
481
|
await sleep(1)
|
|
@@ -447,9 +528,12 @@ describe('dehydration and rehydration', () => {
|
|
|
447
528
|
return promise
|
|
448
529
|
}
|
|
449
530
|
|
|
450
|
-
await queryClient.prefetchQuery(
|
|
531
|
+
await queryClient.prefetchQuery({
|
|
532
|
+
queryKey: ['string'],
|
|
533
|
+
queryFn: () => customFetchData(),
|
|
534
|
+
})
|
|
451
535
|
|
|
452
|
-
queryClient.refetchQueries(['string'])
|
|
536
|
+
queryClient.refetchQueries({ queryKey: ['string'] })
|
|
453
537
|
|
|
454
538
|
const dehydrated = dehydrate(queryClient)
|
|
455
539
|
resolvePromise('string')
|
|
@@ -464,6 +548,8 @@ describe('dehydration and rehydration', () => {
|
|
|
464
548
|
const hydrationCache = new QueryCache()
|
|
465
549
|
const hydrationClient = createQueryClient({ queryCache: hydrationCache })
|
|
466
550
|
hydrate(hydrationClient, parsed)
|
|
467
|
-
expect(
|
|
551
|
+
expect(
|
|
552
|
+
hydrationCache.find({ queryKey: ['string'] })?.state.fetchStatus,
|
|
553
|
+
).toBe('idle')
|
|
468
554
|
})
|
|
469
555
|
})
|