@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/query.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { noop, replaceData, timeUntilStale } from './utils'
|
|
2
2
|
import type {
|
|
3
3
|
InitialDataFunction,
|
|
4
4
|
QueryKey,
|
|
@@ -9,11 +9,10 @@ import type {
|
|
|
9
9
|
CancelOptions,
|
|
10
10
|
SetDataOptions,
|
|
11
11
|
FetchStatus,
|
|
12
|
+
RegisteredError,
|
|
12
13
|
} from './types'
|
|
13
14
|
import type { QueryCache } from './queryCache'
|
|
14
15
|
import type { QueryObserver } from './queryObserver'
|
|
15
|
-
import type { Logger } from './logger'
|
|
16
|
-
import { defaultLogger } from './logger'
|
|
17
16
|
import { notifyManager } from './notifyManager'
|
|
18
17
|
import type { Retryer } from './retryer'
|
|
19
18
|
import { isCancelledError, canFetch, createRetryer } from './retryer'
|
|
@@ -30,13 +29,12 @@ interface QueryConfig<
|
|
|
30
29
|
cache: QueryCache
|
|
31
30
|
queryKey: TQueryKey
|
|
32
31
|
queryHash: string
|
|
33
|
-
logger?: Logger
|
|
34
32
|
options?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>
|
|
35
33
|
defaultOptions?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>
|
|
36
34
|
state?: QueryState<TData, TError>
|
|
37
35
|
}
|
|
38
36
|
|
|
39
|
-
export interface QueryState<TData = unknown, TError =
|
|
37
|
+
export interface QueryState<TData = unknown, TError = RegisteredError> {
|
|
40
38
|
data: TData | undefined
|
|
41
39
|
dataUpdateCount: number
|
|
42
40
|
dataUpdatedAt: number
|
|
@@ -45,7 +43,7 @@ export interface QueryState<TData = unknown, TError = unknown> {
|
|
|
45
43
|
errorUpdatedAt: number
|
|
46
44
|
fetchFailureCount: number
|
|
47
45
|
fetchFailureReason: TError | null
|
|
48
|
-
fetchMeta:
|
|
46
|
+
fetchMeta: FetchMeta | null
|
|
49
47
|
isInvalidated: boolean
|
|
50
48
|
status: QueryStatus
|
|
51
49
|
fetchStatus: FetchStatus
|
|
@@ -59,7 +57,7 @@ export interface FetchContext<
|
|
|
59
57
|
> {
|
|
60
58
|
fetchFn: () => unknown | Promise<unknown>
|
|
61
59
|
fetchOptions?: FetchOptions
|
|
62
|
-
signal
|
|
60
|
+
signal: AbortSignal
|
|
63
61
|
options: QueryOptions<TQueryFnData, TError, TData, any>
|
|
64
62
|
queryKey: TQueryKey
|
|
65
63
|
state: QueryState<TData, TError>
|
|
@@ -67,7 +65,7 @@ export interface FetchContext<
|
|
|
67
65
|
|
|
68
66
|
export interface QueryBehavior<
|
|
69
67
|
TQueryFnData = unknown,
|
|
70
|
-
TError =
|
|
68
|
+
TError = RegisteredError,
|
|
71
69
|
TData = TQueryFnData,
|
|
72
70
|
TQueryKey extends QueryKey = QueryKey,
|
|
73
71
|
> {
|
|
@@ -76,9 +74,13 @@ export interface QueryBehavior<
|
|
|
76
74
|
) => void
|
|
77
75
|
}
|
|
78
76
|
|
|
77
|
+
export interface FetchMeta {
|
|
78
|
+
fetchMore?: { direction: 'forward' | 'backward' }
|
|
79
|
+
}
|
|
80
|
+
|
|
79
81
|
export interface FetchOptions {
|
|
80
82
|
cancelRefetch?: boolean
|
|
81
|
-
meta?:
|
|
83
|
+
meta?: FetchMeta
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
interface FailedAction<TError> {
|
|
@@ -89,7 +91,7 @@ interface FailedAction<TError> {
|
|
|
89
91
|
|
|
90
92
|
interface FetchAction {
|
|
91
93
|
type: 'fetch'
|
|
92
|
-
meta?:
|
|
94
|
+
meta?: FetchMeta
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
interface SuccessAction<TData> {
|
|
@@ -140,57 +142,54 @@ export interface SetStateOptions {
|
|
|
140
142
|
|
|
141
143
|
export class Query<
|
|
142
144
|
TQueryFnData = unknown,
|
|
143
|
-
TError =
|
|
145
|
+
TError = RegisteredError,
|
|
144
146
|
TData = TQueryFnData,
|
|
145
147
|
TQueryKey extends QueryKey = QueryKey,
|
|
146
148
|
> extends Removable {
|
|
147
149
|
queryKey: TQueryKey
|
|
148
150
|
queryHash: string
|
|
149
151
|
options!: QueryOptions<TQueryFnData, TError, TData, TQueryKey>
|
|
150
|
-
initialState: QueryState<TData, TError>
|
|
151
|
-
revertState?: QueryState<TData, TError>
|
|
152
152
|
state: QueryState<TData, TError>
|
|
153
153
|
isFetchingOptimistic?: boolean
|
|
154
154
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
155
|
+
#initialState: QueryState<TData, TError>
|
|
156
|
+
#revertState?: QueryState<TData, TError>
|
|
157
|
+
#cache: QueryCache
|
|
158
|
+
#promise?: Promise<TData>
|
|
159
|
+
#retryer?: Retryer<TData>
|
|
160
|
+
#observers: QueryObserver<any, any, any, any, any>[]
|
|
161
|
+
#defaultOptions?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>
|
|
162
|
+
#abortSignalConsumed: boolean
|
|
162
163
|
|
|
163
164
|
constructor(config: QueryConfig<TQueryFnData, TError, TData, TQueryKey>) {
|
|
164
165
|
super()
|
|
165
166
|
|
|
166
|
-
this
|
|
167
|
-
this
|
|
168
|
-
this
|
|
169
|
-
this
|
|
170
|
-
this
|
|
171
|
-
this.logger = config.logger || defaultLogger
|
|
167
|
+
this.#abortSignalConsumed = false
|
|
168
|
+
this.#defaultOptions = config.defaultOptions
|
|
169
|
+
this.#setOptions(config.options)
|
|
170
|
+
this.#observers = []
|
|
171
|
+
this.#cache = config.cache
|
|
172
172
|
this.queryKey = config.queryKey
|
|
173
173
|
this.queryHash = config.queryHash
|
|
174
|
-
this
|
|
175
|
-
this.state = this
|
|
174
|
+
this.#initialState = config.state || getDefaultState(this.options)
|
|
175
|
+
this.state = this.#initialState
|
|
176
176
|
this.scheduleGc()
|
|
177
177
|
}
|
|
178
|
-
|
|
179
178
|
get meta(): QueryMeta | undefined {
|
|
180
179
|
return this.options.meta
|
|
181
180
|
}
|
|
182
181
|
|
|
183
|
-
|
|
182
|
+
#setOptions(
|
|
184
183
|
options?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>,
|
|
185
184
|
): void {
|
|
186
|
-
this.options = { ...this
|
|
185
|
+
this.options = { ...this.#defaultOptions, ...options }
|
|
187
186
|
|
|
188
|
-
this.
|
|
187
|
+
this.updateGcTime(this.options.gcTime)
|
|
189
188
|
}
|
|
190
189
|
|
|
191
190
|
protected optionalRemove() {
|
|
192
|
-
if (!this
|
|
193
|
-
this
|
|
191
|
+
if (!this.#observers.length && this.state.fetchStatus === 'idle') {
|
|
192
|
+
this.#cache.remove(this)
|
|
194
193
|
}
|
|
195
194
|
}
|
|
196
195
|
|
|
@@ -201,7 +200,7 @@ export class Query<
|
|
|
201
200
|
const data = replaceData(this.state.data, newData, this.options)
|
|
202
201
|
|
|
203
202
|
// Set data and mark it as cached
|
|
204
|
-
this
|
|
203
|
+
this.#dispatch({
|
|
205
204
|
data,
|
|
206
205
|
type: 'success',
|
|
207
206
|
dataUpdatedAt: options?.updatedAt,
|
|
@@ -215,12 +214,12 @@ export class Query<
|
|
|
215
214
|
state: QueryState<TData, TError>,
|
|
216
215
|
setStateOptions?: SetStateOptions,
|
|
217
216
|
): void {
|
|
218
|
-
this
|
|
217
|
+
this.#dispatch({ type: 'setState', state, setStateOptions })
|
|
219
218
|
}
|
|
220
219
|
|
|
221
220
|
cancel(options?: CancelOptions): Promise<void> {
|
|
222
|
-
const promise = this
|
|
223
|
-
this
|
|
221
|
+
const promise = this.#promise
|
|
222
|
+
this.#retryer?.cancel(options)
|
|
224
223
|
return promise ? promise.then(noop).catch(noop) : Promise.resolve()
|
|
225
224
|
}
|
|
226
225
|
|
|
@@ -232,11 +231,13 @@ export class Query<
|
|
|
232
231
|
|
|
233
232
|
reset(): void {
|
|
234
233
|
this.destroy()
|
|
235
|
-
this.setState(this
|
|
234
|
+
this.setState(this.#initialState)
|
|
236
235
|
}
|
|
237
236
|
|
|
238
237
|
isActive(): boolean {
|
|
239
|
-
return this
|
|
238
|
+
return this.#observers.some(
|
|
239
|
+
(observer) => observer.options.enabled !== false,
|
|
240
|
+
)
|
|
240
241
|
}
|
|
241
242
|
|
|
242
243
|
isDisabled(): boolean {
|
|
@@ -247,7 +248,7 @@ export class Query<
|
|
|
247
248
|
return (
|
|
248
249
|
this.state.isInvalidated ||
|
|
249
250
|
!this.state.dataUpdatedAt ||
|
|
250
|
-
this
|
|
251
|
+
this.#observers.some((observer) => observer.getCurrentResult().isStale)
|
|
251
252
|
)
|
|
252
253
|
}
|
|
253
254
|
|
|
@@ -260,67 +261,63 @@ export class Query<
|
|
|
260
261
|
}
|
|
261
262
|
|
|
262
263
|
onFocus(): void {
|
|
263
|
-
const observer = this
|
|
264
|
+
const observer = this.#observers.find((x) => x.shouldFetchOnWindowFocus())
|
|
264
265
|
|
|
265
|
-
|
|
266
|
-
observer.refetch({ cancelRefetch: false })
|
|
267
|
-
}
|
|
266
|
+
observer?.refetch({ cancelRefetch: false })
|
|
268
267
|
|
|
269
268
|
// Continue fetch if currently paused
|
|
270
|
-
this
|
|
269
|
+
this.#retryer?.continue()
|
|
271
270
|
}
|
|
272
271
|
|
|
273
272
|
onOnline(): void {
|
|
274
|
-
const observer = this
|
|
273
|
+
const observer = this.#observers.find((x) => x.shouldFetchOnReconnect())
|
|
275
274
|
|
|
276
|
-
|
|
277
|
-
observer.refetch({ cancelRefetch: false })
|
|
278
|
-
}
|
|
275
|
+
observer?.refetch({ cancelRefetch: false })
|
|
279
276
|
|
|
280
277
|
// Continue fetch if currently paused
|
|
281
|
-
this
|
|
278
|
+
this.#retryer?.continue()
|
|
282
279
|
}
|
|
283
280
|
|
|
284
281
|
addObserver(observer: QueryObserver<any, any, any, any, any>): void {
|
|
285
|
-
if (this
|
|
286
|
-
this
|
|
282
|
+
if (this.#observers.indexOf(observer) === -1) {
|
|
283
|
+
this.#observers.push(observer)
|
|
287
284
|
|
|
288
285
|
// Stop the query from being garbage collected
|
|
289
286
|
this.clearGcTimeout()
|
|
290
287
|
|
|
291
|
-
this
|
|
288
|
+
this.#cache.notify({ type: 'observerAdded', query: this, observer })
|
|
292
289
|
}
|
|
293
290
|
}
|
|
294
291
|
|
|
295
292
|
removeObserver(observer: QueryObserver<any, any, any, any, any>): void {
|
|
296
|
-
if (this
|
|
297
|
-
this
|
|
293
|
+
if (this.#observers.indexOf(observer) !== -1) {
|
|
294
|
+
this.#observers = this.#observers.filter((x) => x !== observer)
|
|
298
295
|
|
|
299
|
-
if (!this
|
|
296
|
+
if (!this.#observers.length) {
|
|
300
297
|
// If the transport layer does not support cancellation
|
|
301
298
|
// we'll let the query continue so the result can be cached
|
|
302
|
-
if (this
|
|
303
|
-
if (this
|
|
304
|
-
this
|
|
299
|
+
if (this.#retryer) {
|
|
300
|
+
if (this.#abortSignalConsumed) {
|
|
301
|
+
this.#retryer.cancel({ revert: true })
|
|
305
302
|
} else {
|
|
306
|
-
this
|
|
303
|
+
this.#retryer.cancelRetry()
|
|
307
304
|
}
|
|
308
305
|
}
|
|
309
306
|
|
|
310
307
|
this.scheduleGc()
|
|
311
308
|
}
|
|
312
309
|
|
|
313
|
-
this
|
|
310
|
+
this.#cache.notify({ type: 'observerRemoved', query: this, observer })
|
|
314
311
|
}
|
|
315
312
|
}
|
|
316
313
|
|
|
317
314
|
getObserversCount(): number {
|
|
318
|
-
return this
|
|
315
|
+
return this.#observers.length
|
|
319
316
|
}
|
|
320
317
|
|
|
321
318
|
invalidate(): void {
|
|
322
319
|
if (!this.state.isInvalidated) {
|
|
323
|
-
this
|
|
320
|
+
this.#dispatch({ type: 'invalidate' })
|
|
324
321
|
}
|
|
325
322
|
}
|
|
326
323
|
|
|
@@ -332,42 +329,41 @@ export class Query<
|
|
|
332
329
|
if (this.state.dataUpdatedAt && fetchOptions?.cancelRefetch) {
|
|
333
330
|
// Silently cancel current fetch if the user wants to cancel refetches
|
|
334
331
|
this.cancel({ silent: true })
|
|
335
|
-
} else if (this
|
|
332
|
+
} else if (this.#promise) {
|
|
336
333
|
// make sure that retries that were potentially cancelled due to unmounts can continue
|
|
337
|
-
this
|
|
334
|
+
this.#retryer?.continueRetry()
|
|
338
335
|
// Return current promise if we are already fetching
|
|
339
|
-
return this
|
|
336
|
+
return this.#promise
|
|
340
337
|
}
|
|
341
338
|
}
|
|
342
339
|
|
|
343
340
|
// Update config if passed, otherwise the config from the last execution is used
|
|
344
341
|
if (options) {
|
|
345
|
-
this
|
|
342
|
+
this.#setOptions(options)
|
|
346
343
|
}
|
|
347
344
|
|
|
348
345
|
// Use the options from the first observer with a query function if no function is found.
|
|
349
346
|
// This can happen when the query is hydrated or created with setQueryData.
|
|
350
347
|
if (!this.options.queryFn) {
|
|
351
|
-
const observer = this
|
|
348
|
+
const observer = this.#observers.find((x) => x.options.queryFn)
|
|
352
349
|
if (observer) {
|
|
353
|
-
this
|
|
350
|
+
this.#setOptions(observer.options)
|
|
354
351
|
}
|
|
355
352
|
}
|
|
356
353
|
|
|
357
|
-
if (
|
|
358
|
-
if (
|
|
359
|
-
|
|
354
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
355
|
+
if (!Array.isArray(this.options.queryKey)) {
|
|
356
|
+
console.error(
|
|
360
357
|
`As of v4, queryKey needs to be an Array. If you are using a string like 'repoData', please change it to an Array, e.g. ['repoData']`,
|
|
361
358
|
)
|
|
362
359
|
}
|
|
363
360
|
}
|
|
364
361
|
|
|
365
|
-
const abortController =
|
|
362
|
+
const abortController = new AbortController()
|
|
366
363
|
|
|
367
364
|
// Create query function context
|
|
368
|
-
const queryFnContext: QueryFunctionContext<TQueryKey> = {
|
|
365
|
+
const queryFnContext: Omit<QueryFunctionContext<TQueryKey>, 'signal'> = {
|
|
369
366
|
queryKey: this.queryKey,
|
|
370
|
-
pageParam: undefined,
|
|
371
367
|
meta: this.meta,
|
|
372
368
|
}
|
|
373
369
|
|
|
@@ -378,11 +374,8 @@ export class Query<
|
|
|
378
374
|
Object.defineProperty(object, 'signal', {
|
|
379
375
|
enumerable: true,
|
|
380
376
|
get: () => {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
return abortController.signal
|
|
384
|
-
}
|
|
385
|
-
return undefined
|
|
377
|
+
this.#abortSignalConsumed = true
|
|
378
|
+
return abortController.signal
|
|
386
379
|
},
|
|
387
380
|
})
|
|
388
381
|
}
|
|
@@ -392,14 +385,19 @@ export class Query<
|
|
|
392
385
|
// Create fetch function
|
|
393
386
|
const fetchFn = () => {
|
|
394
387
|
if (!this.options.queryFn) {
|
|
395
|
-
return Promise.reject('Missing queryFn')
|
|
388
|
+
return Promise.reject(new Error('Missing queryFn'))
|
|
396
389
|
}
|
|
397
|
-
this
|
|
398
|
-
return this.options.queryFn(
|
|
390
|
+
this.#abortSignalConsumed = false
|
|
391
|
+
return this.options.queryFn(
|
|
392
|
+
queryFnContext as QueryFunctionContext<TQueryKey>,
|
|
393
|
+
)
|
|
399
394
|
}
|
|
400
395
|
|
|
401
396
|
// Trigger behavior hook
|
|
402
|
-
const context:
|
|
397
|
+
const context: Omit<
|
|
398
|
+
FetchContext<TQueryFnData, TError, TData, TQueryKey>,
|
|
399
|
+
'signal'
|
|
400
|
+
> = {
|
|
403
401
|
fetchOptions,
|
|
404
402
|
options: this.options,
|
|
405
403
|
queryKey: this.queryKey,
|
|
@@ -409,23 +407,25 @@ export class Query<
|
|
|
409
407
|
|
|
410
408
|
addSignalProperty(context)
|
|
411
409
|
|
|
412
|
-
this.options.behavior?.onFetch(
|
|
410
|
+
this.options.behavior?.onFetch(
|
|
411
|
+
context as FetchContext<TQueryFnData, TError, TData, TQueryKey>,
|
|
412
|
+
)
|
|
413
413
|
|
|
414
414
|
// Store state in case the current fetch needs to be reverted
|
|
415
|
-
this
|
|
415
|
+
this.#revertState = this.state
|
|
416
416
|
|
|
417
417
|
// Set to fetching state if not already in it
|
|
418
418
|
if (
|
|
419
419
|
this.state.fetchStatus === 'idle' ||
|
|
420
420
|
this.state.fetchMeta !== context.fetchOptions?.meta
|
|
421
421
|
) {
|
|
422
|
-
this
|
|
422
|
+
this.#dispatch({ type: 'fetch', meta: context.fetchOptions?.meta })
|
|
423
423
|
}
|
|
424
424
|
|
|
425
425
|
const onError = (error: TError | { silent?: boolean }) => {
|
|
426
426
|
// Optimistically update state if needed
|
|
427
427
|
if (!(isCancelledError(error) && error.silent)) {
|
|
428
|
-
this
|
|
428
|
+
this.#dispatch({
|
|
429
429
|
type: 'error',
|
|
430
430
|
error: error as TError,
|
|
431
431
|
})
|
|
@@ -433,11 +433,7 @@ export class Query<
|
|
|
433
433
|
|
|
434
434
|
if (!isCancelledError(error)) {
|
|
435
435
|
// Notify cache callback
|
|
436
|
-
this
|
|
437
|
-
|
|
438
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
439
|
-
this.logger.error(error)
|
|
440
|
-
}
|
|
436
|
+
this.#cache.config.onError?.(error, this as Query<any, any, any, any>)
|
|
441
437
|
}
|
|
442
438
|
|
|
443
439
|
if (!this.isFetchingOptimistic) {
|
|
@@ -448,13 +444,13 @@ export class Query<
|
|
|
448
444
|
}
|
|
449
445
|
|
|
450
446
|
// Try to fetch the data
|
|
451
|
-
this
|
|
447
|
+
this.#retryer = createRetryer({
|
|
452
448
|
fn: context.fetchFn as () => TData,
|
|
453
|
-
abort: abortController
|
|
449
|
+
abort: abortController.abort.bind(abortController),
|
|
454
450
|
onSuccess: (data) => {
|
|
455
451
|
if (typeof data === 'undefined') {
|
|
456
452
|
if (process.env.NODE_ENV !== 'production') {
|
|
457
|
-
|
|
453
|
+
console.error(
|
|
458
454
|
`Query data cannot be undefined. Please make sure to return a value other than undefined from your query function. Affected query key: ${this.queryHash}`,
|
|
459
455
|
)
|
|
460
456
|
}
|
|
@@ -465,7 +461,7 @@ export class Query<
|
|
|
465
461
|
this.setData(data as TData)
|
|
466
462
|
|
|
467
463
|
// Notify cache callback
|
|
468
|
-
this
|
|
464
|
+
this.#cache.config.onSuccess?.(data, this as Query<any, any, any, any>)
|
|
469
465
|
|
|
470
466
|
if (!this.isFetchingOptimistic) {
|
|
471
467
|
// Schedule query gc after fetching
|
|
@@ -475,25 +471,25 @@ export class Query<
|
|
|
475
471
|
},
|
|
476
472
|
onError,
|
|
477
473
|
onFail: (failureCount, error) => {
|
|
478
|
-
this
|
|
474
|
+
this.#dispatch({ type: 'failed', failureCount, error })
|
|
479
475
|
},
|
|
480
476
|
onPause: () => {
|
|
481
|
-
this
|
|
477
|
+
this.#dispatch({ type: 'pause' })
|
|
482
478
|
},
|
|
483
479
|
onContinue: () => {
|
|
484
|
-
this
|
|
480
|
+
this.#dispatch({ type: 'continue' })
|
|
485
481
|
},
|
|
486
482
|
retry: context.options.retry,
|
|
487
483
|
retryDelay: context.options.retryDelay,
|
|
488
484
|
networkMode: context.options.networkMode,
|
|
489
485
|
})
|
|
490
486
|
|
|
491
|
-
this
|
|
487
|
+
this.#promise = this.#retryer.promise
|
|
492
488
|
|
|
493
|
-
return this
|
|
489
|
+
return this.#promise
|
|
494
490
|
}
|
|
495
491
|
|
|
496
|
-
|
|
492
|
+
#dispatch(action: Action<TData, TError>): void {
|
|
497
493
|
const reducer = (
|
|
498
494
|
state: QueryState<TData, TError>,
|
|
499
495
|
): QueryState<TData, TError> => {
|
|
@@ -525,7 +521,7 @@ export class Query<
|
|
|
525
521
|
: 'paused',
|
|
526
522
|
...(!state.dataUpdatedAt && {
|
|
527
523
|
error: null,
|
|
528
|
-
status: '
|
|
524
|
+
status: 'pending',
|
|
529
525
|
}),
|
|
530
526
|
}
|
|
531
527
|
case 'success':
|
|
@@ -546,8 +542,8 @@ export class Query<
|
|
|
546
542
|
case 'error':
|
|
547
543
|
const error = action.error as unknown
|
|
548
544
|
|
|
549
|
-
if (isCancelledError(error) && error.revert && this
|
|
550
|
-
return { ...this
|
|
545
|
+
if (isCancelledError(error) && error.revert && this.#revertState) {
|
|
546
|
+
return { ...this.#revertState }
|
|
551
547
|
}
|
|
552
548
|
|
|
553
549
|
return {
|
|
@@ -576,11 +572,11 @@ export class Query<
|
|
|
576
572
|
this.state = reducer(this.state)
|
|
577
573
|
|
|
578
574
|
notifyManager.batch(() => {
|
|
579
|
-
this
|
|
575
|
+
this.#observers.forEach((observer) => {
|
|
580
576
|
observer.onQueryUpdate(action)
|
|
581
577
|
})
|
|
582
578
|
|
|
583
|
-
this
|
|
579
|
+
this.#cache.notify({ query: this, type: 'updated', action })
|
|
584
580
|
})
|
|
585
581
|
}
|
|
586
582
|
}
|
|
@@ -617,7 +613,7 @@ function getDefaultState<
|
|
|
617
613
|
fetchFailureReason: null,
|
|
618
614
|
fetchMeta: null,
|
|
619
615
|
isInvalidated: false,
|
|
620
|
-
status: hasData ? 'success' : '
|
|
616
|
+
status: hasData ? 'success' : 'pending',
|
|
621
617
|
fetchStatus: 'idle',
|
|
622
618
|
}
|
|
623
619
|
}
|