@tanstack/query-core 5.83.1 → 5.87.4
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/legacy/{hydration-Cvr-9VdO.d.ts → hydration-BYonJkjc.d.ts} +8 -6
- package/build/legacy/{hydration-CADtEOkK.d.cts → hydration-_hO-y142.d.cts} +8 -6
- package/build/legacy/hydration.d.cts +1 -1
- package/build/legacy/hydration.d.ts +1 -1
- package/build/legacy/index.cjs +14 -12
- package/build/legacy/index.cjs.map +1 -1
- package/build/legacy/index.d.cts +5 -4
- package/build/legacy/index.d.ts +5 -4
- package/build/legacy/index.js +26 -23
- package/build/legacy/index.js.map +1 -1
- package/build/legacy/infiniteQueryBehavior.d.cts +1 -1
- package/build/legacy/infiniteQueryBehavior.d.ts +1 -1
- package/build/legacy/infiniteQueryObserver.d.cts +1 -1
- package/build/legacy/infiniteQueryObserver.d.ts +1 -1
- package/build/legacy/mutation.d.cts +1 -1
- package/build/legacy/mutation.d.ts +1 -1
- package/build/legacy/mutationCache.d.cts +1 -1
- package/build/legacy/mutationCache.d.ts +1 -1
- package/build/legacy/mutationObserver.d.cts +1 -1
- package/build/legacy/mutationObserver.d.ts +1 -1
- package/build/legacy/notifyManager.cjs +2 -1
- package/build/legacy/notifyManager.cjs.map +1 -1
- package/build/legacy/notifyManager.js +2 -1
- package/build/legacy/notifyManager.js.map +1 -1
- package/build/legacy/queriesObserver.cjs +19 -13
- package/build/legacy/queriesObserver.cjs.map +1 -1
- package/build/legacy/queriesObserver.d.cts +1 -1
- package/build/legacy/queriesObserver.d.ts +1 -1
- package/build/legacy/queriesObserver.js +20 -14
- package/build/legacy/queriesObserver.js.map +1 -1
- package/build/legacy/query.cjs +78 -61
- package/build/legacy/query.cjs.map +1 -1
- package/build/legacy/query.d.cts +1 -1
- package/build/legacy/query.d.ts +1 -1
- package/build/legacy/query.js +79 -62
- package/build/legacy/query.js.map +1 -1
- package/build/legacy/queryCache.d.cts +1 -1
- package/build/legacy/queryCache.d.ts +1 -1
- package/build/legacy/queryClient.d.cts +1 -1
- package/build/legacy/queryClient.d.ts +1 -1
- package/build/legacy/queryObserver.cjs +12 -9
- package/build/legacy/queryObserver.cjs.map +1 -1
- package/build/legacy/queryObserver.d.cts +1 -1
- package/build/legacy/queryObserver.d.ts +1 -1
- package/build/legacy/queryObserver.js +12 -9
- package/build/legacy/queryObserver.js.map +1 -1
- package/build/legacy/removable.cjs +3 -2
- package/build/legacy/removable.cjs.map +1 -1
- package/build/legacy/removable.js +3 -2
- package/build/legacy/removable.js.map +1 -1
- package/build/legacy/retryer.cjs +12 -16
- package/build/legacy/retryer.cjs.map +1 -1
- package/build/legacy/retryer.d.cts +1 -1
- package/build/legacy/retryer.d.ts +1 -1
- package/build/legacy/retryer.js +12 -16
- package/build/legacy/retryer.js.map +1 -1
- package/build/legacy/streamedQuery.cjs +7 -8
- package/build/legacy/streamedQuery.cjs.map +1 -1
- package/build/legacy/streamedQuery.d.cts +18 -10
- package/build/legacy/streamedQuery.d.ts +18 -10
- package/build/legacy/streamedQuery.js +7 -8
- package/build/legacy/streamedQuery.js.map +1 -1
- package/build/legacy/timeoutManager.cjs +110 -0
- package/build/legacy/timeoutManager.cjs.map +1 -0
- package/build/legacy/timeoutManager.d.cts +58 -0
- package/build/legacy/timeoutManager.d.ts +58 -0
- package/build/legacy/timeoutManager.js +81 -0
- package/build/legacy/timeoutManager.js.map +1 -0
- package/build/legacy/types.d.cts +1 -1
- package/build/legacy/types.d.ts +1 -1
- package/build/legacy/utils.cjs +26 -22
- package/build/legacy/utils.cjs.map +1 -1
- package/build/legacy/utils.d.cts +1 -1
- package/build/legacy/utils.d.ts +1 -1
- package/build/legacy/utils.js +26 -22
- package/build/legacy/utils.js.map +1 -1
- package/build/modern/{hydration-Cvr-9VdO.d.ts → hydration-BYonJkjc.d.ts} +8 -6
- package/build/modern/{hydration-CADtEOkK.d.cts → hydration-_hO-y142.d.cts} +8 -6
- package/build/modern/hydration.d.cts +1 -1
- package/build/modern/hydration.d.ts +1 -1
- package/build/modern/index.cjs +14 -12
- package/build/modern/index.cjs.map +1 -1
- package/build/modern/index.d.cts +5 -4
- package/build/modern/index.d.ts +5 -4
- package/build/modern/index.js +26 -23
- package/build/modern/index.js.map +1 -1
- package/build/modern/infiniteQueryBehavior.d.cts +1 -1
- package/build/modern/infiniteQueryBehavior.d.ts +1 -1
- package/build/modern/infiniteQueryObserver.d.cts +1 -1
- package/build/modern/infiniteQueryObserver.d.ts +1 -1
- package/build/modern/mutation.d.cts +1 -1
- package/build/modern/mutation.d.ts +1 -1
- package/build/modern/mutationCache.d.cts +1 -1
- package/build/modern/mutationCache.d.ts +1 -1
- package/build/modern/mutationObserver.d.cts +1 -1
- package/build/modern/mutationObserver.d.ts +1 -1
- package/build/modern/notifyManager.cjs +2 -1
- package/build/modern/notifyManager.cjs.map +1 -1
- package/build/modern/notifyManager.js +2 -1
- package/build/modern/notifyManager.js.map +1 -1
- package/build/modern/queriesObserver.cjs +19 -13
- package/build/modern/queriesObserver.cjs.map +1 -1
- package/build/modern/queriesObserver.d.cts +1 -1
- package/build/modern/queriesObserver.d.ts +1 -1
- package/build/modern/queriesObserver.js +20 -14
- package/build/modern/queriesObserver.js.map +1 -1
- package/build/modern/query.cjs +71 -52
- package/build/modern/query.cjs.map +1 -1
- package/build/modern/query.d.cts +1 -1
- package/build/modern/query.d.ts +1 -1
- package/build/modern/query.js +72 -53
- package/build/modern/query.js.map +1 -1
- package/build/modern/queryCache.d.cts +1 -1
- package/build/modern/queryCache.d.ts +1 -1
- package/build/modern/queryClient.d.cts +1 -1
- package/build/modern/queryClient.d.ts +1 -1
- package/build/modern/queryObserver.cjs +12 -9
- package/build/modern/queryObserver.cjs.map +1 -1
- package/build/modern/queryObserver.d.cts +1 -1
- package/build/modern/queryObserver.d.ts +1 -1
- package/build/modern/queryObserver.js +12 -9
- package/build/modern/queryObserver.js.map +1 -1
- package/build/modern/removable.cjs +3 -2
- package/build/modern/removable.cjs.map +1 -1
- package/build/modern/removable.js +3 -2
- package/build/modern/removable.js.map +1 -1
- package/build/modern/retryer.cjs +12 -14
- package/build/modern/retryer.cjs.map +1 -1
- package/build/modern/retryer.d.cts +1 -1
- package/build/modern/retryer.d.ts +1 -1
- package/build/modern/retryer.js +12 -14
- package/build/modern/retryer.js.map +1 -1
- package/build/modern/streamedQuery.cjs +7 -8
- package/build/modern/streamedQuery.cjs.map +1 -1
- package/build/modern/streamedQuery.d.cts +18 -10
- package/build/modern/streamedQuery.d.ts +18 -10
- package/build/modern/streamedQuery.js +7 -8
- package/build/modern/streamedQuery.js.map +1 -1
- package/build/modern/timeoutManager.cjs +98 -0
- package/build/modern/timeoutManager.cjs.map +1 -0
- package/build/modern/timeoutManager.d.cts +58 -0
- package/build/modern/timeoutManager.d.ts +58 -0
- package/build/modern/timeoutManager.js +70 -0
- package/build/modern/timeoutManager.js.map +1 -0
- package/build/modern/types.d.cts +1 -1
- package/build/modern/types.d.ts +1 -1
- package/build/modern/utils.cjs +26 -22
- package/build/modern/utils.cjs.map +1 -1
- package/build/modern/utils.d.cts +1 -1
- package/build/modern/utils.d.ts +1 -1
- package/build/modern/utils.js +26 -22
- package/build/modern/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +32 -27
- package/src/notifyManager.ts +3 -1
- package/src/queriesObserver.ts +24 -15
- package/src/query.ts +96 -69
- package/src/queryObserver.ts +19 -11
- package/src/removable.ts +5 -3
- package/src/retryer.ts +20 -17
- package/src/streamedQuery.ts +47 -23
- package/src/timeoutManager.ts +135 -0
- package/src/utils.ts +39 -31
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* {@link TimeoutManager} does not support passing arguments to the callback.
|
|
3
|
+
*
|
|
4
|
+
* `(_: void)` is the argument type inferred by TypeScript's default typings for
|
|
5
|
+
* `setTimeout(cb, number)`.
|
|
6
|
+
* If we don't accept a single void argument, then
|
|
7
|
+
* `new Promise(resolve => timeoutManager.setTimeout(resolve, N))` is a type error.
|
|
8
|
+
*/
|
|
9
|
+
export type TimeoutCallback = (_: void) => void
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Wrapping `setTimeout` is awkward from a typing perspective because platform
|
|
13
|
+
* typings may extend the return type of `setTimeout`. For example, NodeJS
|
|
14
|
+
* typings add `NodeJS.Timeout`; but a non-default `timeoutManager` may not be
|
|
15
|
+
* able to return such a type.
|
|
16
|
+
*/
|
|
17
|
+
export type ManagedTimerId = number | { [Symbol.toPrimitive]: () => number }
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Backend for timer functions.
|
|
21
|
+
*/
|
|
22
|
+
export type TimeoutProvider<TTimerId extends ManagedTimerId = ManagedTimerId> =
|
|
23
|
+
{
|
|
24
|
+
readonly setTimeout: (callback: TimeoutCallback, delay: number) => TTimerId
|
|
25
|
+
readonly clearTimeout: (timeoutId: TTimerId | undefined) => void
|
|
26
|
+
|
|
27
|
+
readonly setInterval: (callback: TimeoutCallback, delay: number) => TTimerId
|
|
28
|
+
readonly clearInterval: (intervalId: TTimerId | undefined) => void
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const defaultTimeoutProvider: TimeoutProvider<
|
|
32
|
+
ReturnType<typeof setTimeout>
|
|
33
|
+
> = {
|
|
34
|
+
// We need the wrapper function syntax below instead of direct references to
|
|
35
|
+
// global setTimeout etc.
|
|
36
|
+
//
|
|
37
|
+
// BAD: `setTimeout: setTimeout`
|
|
38
|
+
// GOOD: `setTimeout: (cb, delay) => setTimeout(cb, delay)`
|
|
39
|
+
//
|
|
40
|
+
// If we use direct references here, then anything that wants to spy on or
|
|
41
|
+
// replace the global setTimeout (like tests) won't work since we'll already
|
|
42
|
+
// have a hard reference to the original implementation at the time when this
|
|
43
|
+
// file was imported.
|
|
44
|
+
setTimeout: (callback, delay) => setTimeout(callback, delay),
|
|
45
|
+
clearTimeout: (timeoutId) => clearTimeout(timeoutId),
|
|
46
|
+
|
|
47
|
+
setInterval: (callback, delay) => setInterval(callback, delay),
|
|
48
|
+
clearInterval: (intervalId) => clearInterval(intervalId),
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Allows customization of how timeouts are created.
|
|
53
|
+
*
|
|
54
|
+
* @tanstack/query-core makes liberal use of timeouts to implement `staleTime`
|
|
55
|
+
* and `gcTime`. The default TimeoutManager provider uses the platform's global
|
|
56
|
+
* `setTimeout` implementation, which is known to have scalability issues with
|
|
57
|
+
* thousands of timeouts on the event loop.
|
|
58
|
+
*
|
|
59
|
+
* If you hit this limitation, consider providing a custom TimeoutProvider that
|
|
60
|
+
* coalesces timeouts.
|
|
61
|
+
*/
|
|
62
|
+
export class TimeoutManager implements Omit<TimeoutProvider, 'name'> {
|
|
63
|
+
// We cannot have TimeoutManager<T> as we must instantiate it with a concrete
|
|
64
|
+
// type at app boot; and if we leave that type, then any new timer provider
|
|
65
|
+
// would need to support ReturnType<typeof setTimeout>, which is infeasible.
|
|
66
|
+
//
|
|
67
|
+
// We settle for type safety for the TimeoutProvider type, and accept that
|
|
68
|
+
// this class is unsafe internally to allow for extension.
|
|
69
|
+
#provider: TimeoutProvider<any> = defaultTimeoutProvider
|
|
70
|
+
#providerCalled = false
|
|
71
|
+
|
|
72
|
+
setTimeoutProvider<TTimerId extends ManagedTimerId>(
|
|
73
|
+
provider: TimeoutProvider<TTimerId>,
|
|
74
|
+
): void {
|
|
75
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
76
|
+
if (this.#providerCalled && provider !== this.#provider) {
|
|
77
|
+
// After changing providers, `clearTimeout` will not work as expected for
|
|
78
|
+
// timeouts from the previous provider.
|
|
79
|
+
//
|
|
80
|
+
// Since they may allocate the same timeout ID, clearTimeout may cancel an
|
|
81
|
+
// arbitrary different timeout, or unexpected no-op.
|
|
82
|
+
//
|
|
83
|
+
// We could protect against this by mixing the timeout ID bits
|
|
84
|
+
// deterministically with some per-provider bits.
|
|
85
|
+
//
|
|
86
|
+
// We could internally queue `setTimeout` calls to `TimeoutManager` until
|
|
87
|
+
// some API call to set the initial provider.
|
|
88
|
+
console.error(
|
|
89
|
+
`[timeoutManager]: Switching provider after calls to previous provider might result in unexpected behavior.`,
|
|
90
|
+
{ previous: this.#provider, provider },
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
this.#provider = provider
|
|
96
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
97
|
+
this.#providerCalled = false
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
setTimeout(callback: TimeoutCallback, delay: number): ManagedTimerId {
|
|
102
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
103
|
+
this.#providerCalled = true
|
|
104
|
+
}
|
|
105
|
+
return this.#provider.setTimeout(callback, delay)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
clearTimeout(timeoutId: ManagedTimerId | undefined): void {
|
|
109
|
+
this.#provider.clearTimeout(timeoutId)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
setInterval(callback: TimeoutCallback, delay: number): ManagedTimerId {
|
|
113
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
114
|
+
this.#providerCalled = true
|
|
115
|
+
}
|
|
116
|
+
return this.#provider.setInterval(callback, delay)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
clearInterval(intervalId: ManagedTimerId | undefined): void {
|
|
120
|
+
this.#provider.clearInterval(intervalId)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export const timeoutManager = new TimeoutManager()
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* In many cases code wants to delay to the next event loop tick; this is not
|
|
128
|
+
* mediated by {@link timeoutManager}.
|
|
129
|
+
*
|
|
130
|
+
* This function is provided to make auditing the `tanstack/query-core` for
|
|
131
|
+
* incorrect use of system `setTimeout` easier.
|
|
132
|
+
*/
|
|
133
|
+
export function systemSetTimeoutZero(callback: TimeoutCallback): void {
|
|
134
|
+
setTimeout(callback, 0)
|
|
135
|
+
}
|
package/src/utils.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { timeoutManager } from './timeoutManager'
|
|
1
2
|
import type {
|
|
2
3
|
DefaultError,
|
|
3
4
|
Enabled,
|
|
@@ -245,6 +246,8 @@ export function partialMatchKey(a: any, b: any): boolean {
|
|
|
245
246
|
return false
|
|
246
247
|
}
|
|
247
248
|
|
|
249
|
+
const hasOwn = Object.prototype.hasOwnProperty
|
|
250
|
+
|
|
248
251
|
/**
|
|
249
252
|
* This function returns `a` if `b` is deeply equal.
|
|
250
253
|
* If not, it will replace any deeply equal children of `b` with those of `a`.
|
|
@@ -258,37 +261,43 @@ export function replaceEqualDeep(a: any, b: any): any {
|
|
|
258
261
|
|
|
259
262
|
const array = isPlainArray(a) && isPlainArray(b)
|
|
260
263
|
|
|
261
|
-
if (array
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
264
|
+
if (!array && !(isPlainObject(a) && isPlainObject(b))) return b
|
|
265
|
+
|
|
266
|
+
const aItems = array ? a : Object.keys(a)
|
|
267
|
+
const aSize = aItems.length
|
|
268
|
+
const bItems = array ? b : Object.keys(b)
|
|
269
|
+
const bSize = bItems.length
|
|
270
|
+
const copy: any = array ? new Array(bSize) : {}
|
|
271
|
+
|
|
272
|
+
let equalItems = 0
|
|
273
|
+
|
|
274
|
+
for (let i = 0; i < bSize; i++) {
|
|
275
|
+
const key: any = array ? i : bItems[i]
|
|
276
|
+
const aItem = a[key]
|
|
277
|
+
const bItem = b[key]
|
|
278
|
+
|
|
279
|
+
if (aItem === bItem) {
|
|
280
|
+
copy[key] = aItem
|
|
281
|
+
if (array ? i < aSize : hasOwn.call(a, key)) equalItems++
|
|
282
|
+
continue
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (
|
|
286
|
+
aItem === null ||
|
|
287
|
+
bItem === null ||
|
|
288
|
+
typeof aItem !== 'object' ||
|
|
289
|
+
typeof bItem !== 'object'
|
|
290
|
+
) {
|
|
291
|
+
copy[key] = bItem
|
|
292
|
+
continue
|
|
286
293
|
}
|
|
287
294
|
|
|
288
|
-
|
|
295
|
+
const v = replaceEqualDeep(aItem, bItem)
|
|
296
|
+
copy[key] = v
|
|
297
|
+
if (v === aItem) equalItems++
|
|
289
298
|
}
|
|
290
299
|
|
|
291
|
-
return
|
|
300
|
+
return aSize === bSize && equalItems === aSize ? a : copy
|
|
292
301
|
}
|
|
293
302
|
|
|
294
303
|
/**
|
|
@@ -311,13 +320,12 @@ export function shallowEqualObjects<T extends Record<string, any>>(
|
|
|
311
320
|
return true
|
|
312
321
|
}
|
|
313
322
|
|
|
314
|
-
export function isPlainArray(value: unknown) {
|
|
323
|
+
export function isPlainArray(value: unknown): value is Array<unknown> {
|
|
315
324
|
return Array.isArray(value) && value.length === Object.keys(value).length
|
|
316
325
|
}
|
|
317
326
|
|
|
318
327
|
// Copied from: https://github.com/jonschlinkert/is-plain-object
|
|
319
|
-
|
|
320
|
-
export function isPlainObject(o: any): o is Object {
|
|
328
|
+
export function isPlainObject(o: any): o is Record<PropertyKey, unknown> {
|
|
321
329
|
if (!hasObjectPrototype(o)) {
|
|
322
330
|
return false
|
|
323
331
|
}
|
|
@@ -354,7 +362,7 @@ function hasObjectPrototype(o: any): boolean {
|
|
|
354
362
|
|
|
355
363
|
export function sleep(timeout: number): Promise<void> {
|
|
356
364
|
return new Promise((resolve) => {
|
|
357
|
-
setTimeout(resolve, timeout)
|
|
365
|
+
timeoutManager.setTimeout(resolve, timeout)
|
|
358
366
|
})
|
|
359
367
|
}
|
|
360
368
|
|