@tanstack/query-core 5.29.0 → 5.32.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/legacy/hydration.cjs +4 -4
- package/build/legacy/hydration.cjs.map +1 -1
- package/build/legacy/hydration.d.cts +2 -1
- package/build/legacy/hydration.d.ts +2 -1
- package/build/legacy/hydration.js +4 -4
- package/build/legacy/hydration.js.map +1 -1
- package/build/legacy/index.d.cts +1 -1
- package/build/legacy/index.d.ts +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.cjs +31 -32
- package/build/legacy/mutation.cjs.map +1 -1
- package/build/legacy/mutation.d.cts +1 -1
- package/build/legacy/mutation.d.ts +1 -1
- package/build/legacy/mutation.js +32 -33
- package/build/legacy/mutation.js.map +1 -1
- package/build/legacy/mutationCache.cjs +43 -25
- package/build/legacy/mutationCache.cjs.map +1 -1
- package/build/legacy/mutationCache.d.cts +1 -1
- package/build/legacy/mutationCache.d.ts +1 -1
- package/build/legacy/mutationCache.js +43 -25
- package/build/legacy/mutationCache.js.map +1 -1
- package/build/legacy/mutationObserver.d.cts +1 -1
- package/build/legacy/mutationObserver.d.ts +1 -1
- package/build/legacy/queriesObserver.d.cts +1 -1
- package/build/legacy/queriesObserver.d.ts +1 -1
- package/build/legacy/query.cjs +18 -21
- 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 +18 -21
- 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.d.cts +1 -1
- package/build/legacy/queryObserver.d.ts +1 -1
- package/build/legacy/retryer.cjs +16 -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 +16 -16
- package/build/legacy/retryer.js.map +1 -1
- package/build/legacy/{queryClient-K0zFyarY.d.ts → types-PcQm32IV.d.ts} +276 -266
- package/build/legacy/{queryClient--tFV-sQG.d.cts → types-eJX-7bPI.d.cts} +276 -266
- package/build/legacy/types.cjs.map +1 -1
- package/build/legacy/types.d.cts +1 -1
- package/build/legacy/types.d.ts +1 -1
- package/build/legacy/utils.d.cts +1 -1
- package/build/legacy/utils.d.ts +1 -1
- package/build/modern/hydration.cjs +4 -4
- package/build/modern/hydration.cjs.map +1 -1
- package/build/modern/hydration.d.cts +2 -1
- package/build/modern/hydration.d.ts +2 -1
- package/build/modern/hydration.js +4 -4
- package/build/modern/hydration.js.map +1 -1
- package/build/modern/index.d.cts +1 -1
- package/build/modern/index.d.ts +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.cjs +30 -30
- package/build/modern/mutation.cjs.map +1 -1
- package/build/modern/mutation.d.cts +1 -1
- package/build/modern/mutation.d.ts +1 -1
- package/build/modern/mutation.js +31 -31
- package/build/modern/mutation.js.map +1 -1
- package/build/modern/mutationCache.cjs +38 -23
- package/build/modern/mutationCache.cjs.map +1 -1
- package/build/modern/mutationCache.d.cts +1 -1
- package/build/modern/mutationCache.d.ts +1 -1
- package/build/modern/mutationCache.js +38 -23
- package/build/modern/mutationCache.js.map +1 -1
- package/build/modern/mutationObserver.d.cts +1 -1
- package/build/modern/mutationObserver.d.ts +1 -1
- package/build/modern/queriesObserver.d.cts +1 -1
- package/build/modern/queriesObserver.d.ts +1 -1
- package/build/modern/query.cjs +17 -19
- 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 +17 -19
- 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.d.cts +1 -1
- package/build/modern/queryObserver.d.ts +1 -1
- package/build/modern/retryer.cjs +16 -16
- 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 +16 -16
- package/build/modern/retryer.js.map +1 -1
- package/build/modern/{queryClient-K0zFyarY.d.ts → types-PcQm32IV.d.ts} +276 -266
- package/build/modern/{queryClient--tFV-sQG.d.cts → types-eJX-7bPI.d.cts} +276 -266
- package/build/modern/types.cjs.map +1 -1
- package/build/modern/types.d.cts +1 -1
- package/build/modern/types.d.ts +1 -1
- package/build/modern/utils.d.cts +1 -1
- package/build/modern/utils.d.ts +1 -1
- package/package.json +1 -1
- package/src/__tests__/hydration.test.tsx +34 -0
- package/src/__tests__/mutations.test.tsx +191 -0
- package/src/__tests__/queryClient.test.tsx +96 -4
- package/src/hydration.ts +8 -6
- package/src/mutation.ts +32 -33
- package/src/mutationCache.ts +54 -28
- package/src/query.ts +17 -18
- package/src/retryer.ts +24 -20
- package/src/types.ts +5 -0
package/src/mutation.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { notifyManager } from './notifyManager'
|
|
2
2
|
import { Removable } from './removable'
|
|
3
|
-
import {
|
|
3
|
+
import { createRetryer } from './retryer'
|
|
4
4
|
import type {
|
|
5
5
|
DefaultError,
|
|
6
6
|
MutationMeta,
|
|
@@ -17,7 +17,6 @@ interface MutationConfig<TData, TError, TVariables, TContext> {
|
|
|
17
17
|
mutationId: number
|
|
18
18
|
mutationCache: MutationCache
|
|
19
19
|
options: MutationOptions<TData, TError, TVariables, TContext>
|
|
20
|
-
defaultOptions?: MutationOptions<TData, TError, TVariables, TContext>
|
|
21
20
|
state?: MutationState<TData, TError, TVariables, TContext>
|
|
22
21
|
}
|
|
23
22
|
|
|
@@ -46,6 +45,7 @@ interface FailedAction<TError> {
|
|
|
46
45
|
|
|
47
46
|
interface PendingAction<TVariables, TContext> {
|
|
48
47
|
type: 'pending'
|
|
48
|
+
isPaused: boolean
|
|
49
49
|
variables?: TVariables
|
|
50
50
|
context?: TContext
|
|
51
51
|
}
|
|
@@ -89,7 +89,6 @@ export class Mutation<
|
|
|
89
89
|
readonly mutationId: number
|
|
90
90
|
|
|
91
91
|
#observers: Array<MutationObserver<TData, TError, TVariables, TContext>>
|
|
92
|
-
#defaultOptions?: MutationOptions<TData, TError, TVariables, TContext>
|
|
93
92
|
#mutationCache: MutationCache
|
|
94
93
|
#retryer?: Retryer<TData>
|
|
95
94
|
|
|
@@ -97,7 +96,6 @@ export class Mutation<
|
|
|
97
96
|
super()
|
|
98
97
|
|
|
99
98
|
this.mutationId = config.mutationId
|
|
100
|
-
this.#defaultOptions = config.defaultOptions
|
|
101
99
|
this.#mutationCache = config.mutationCache
|
|
102
100
|
this.#observers = []
|
|
103
101
|
this.state = config.state || getDefaultState()
|
|
@@ -107,9 +105,9 @@ export class Mutation<
|
|
|
107
105
|
}
|
|
108
106
|
|
|
109
107
|
setOptions(
|
|
110
|
-
options
|
|
108
|
+
options: MutationOptions<TData, TError, TVariables, TContext>,
|
|
111
109
|
): void {
|
|
112
|
-
this.options =
|
|
110
|
+
this.options = options
|
|
113
111
|
|
|
114
112
|
this.updateGcTime(this.options.gcTime)
|
|
115
113
|
}
|
|
@@ -164,36 +162,34 @@ export class Mutation<
|
|
|
164
162
|
}
|
|
165
163
|
|
|
166
164
|
async execute(variables: TVariables): Promise<TData> {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return this.#retryer.promise
|
|
190
|
-
}
|
|
165
|
+
this.#retryer = createRetryer({
|
|
166
|
+
fn: () => {
|
|
167
|
+
if (!this.options.mutationFn) {
|
|
168
|
+
return Promise.reject(new Error('No mutationFn found'))
|
|
169
|
+
}
|
|
170
|
+
return this.options.mutationFn(variables)
|
|
171
|
+
},
|
|
172
|
+
onFail: (failureCount, error) => {
|
|
173
|
+
this.#dispatch({ type: 'failed', failureCount, error })
|
|
174
|
+
},
|
|
175
|
+
onPause: () => {
|
|
176
|
+
this.#dispatch({ type: 'pause' })
|
|
177
|
+
},
|
|
178
|
+
onContinue: () => {
|
|
179
|
+
this.#dispatch({ type: 'continue' })
|
|
180
|
+
},
|
|
181
|
+
retry: this.options.retry ?? 0,
|
|
182
|
+
retryDelay: this.options.retryDelay,
|
|
183
|
+
networkMode: this.options.networkMode,
|
|
184
|
+
canRun: () => this.#mutationCache.canRun(this),
|
|
185
|
+
})
|
|
191
186
|
|
|
192
187
|
const restored = this.state.status === 'pending'
|
|
188
|
+
const isPaused = !this.#retryer.canStart()
|
|
193
189
|
|
|
194
190
|
try {
|
|
195
191
|
if (!restored) {
|
|
196
|
-
this.#dispatch({ type: 'pending', variables })
|
|
192
|
+
this.#dispatch({ type: 'pending', variables, isPaused })
|
|
197
193
|
// Notify cache callback
|
|
198
194
|
await this.#mutationCache.config.onMutate?.(
|
|
199
195
|
variables,
|
|
@@ -205,10 +201,11 @@ export class Mutation<
|
|
|
205
201
|
type: 'pending',
|
|
206
202
|
context,
|
|
207
203
|
variables,
|
|
204
|
+
isPaused,
|
|
208
205
|
})
|
|
209
206
|
}
|
|
210
207
|
}
|
|
211
|
-
const data = await
|
|
208
|
+
const data = await this.#retryer.start()
|
|
212
209
|
|
|
213
210
|
// Notify cache callback
|
|
214
211
|
await this.#mutationCache.config.onSuccess?.(
|
|
@@ -268,6 +265,8 @@ export class Mutation<
|
|
|
268
265
|
} finally {
|
|
269
266
|
this.#dispatch({ type: 'error', error: error as TError })
|
|
270
267
|
}
|
|
268
|
+
} finally {
|
|
269
|
+
this.#mutationCache.runNext(this)
|
|
271
270
|
}
|
|
272
271
|
}
|
|
273
272
|
|
|
@@ -300,7 +299,7 @@ export class Mutation<
|
|
|
300
299
|
failureCount: 0,
|
|
301
300
|
failureReason: null,
|
|
302
301
|
error: null,
|
|
303
|
-
isPaused:
|
|
302
|
+
isPaused: action.isPaused,
|
|
304
303
|
status: 'pending',
|
|
305
304
|
variables: action.variables,
|
|
306
305
|
submittedAt: Date.now(),
|
package/src/mutationCache.ts
CHANGED
|
@@ -82,14 +82,13 @@ type MutationCacheListener = (event: MutationCacheNotifyEvent) => void
|
|
|
82
82
|
// CLASS
|
|
83
83
|
|
|
84
84
|
export class MutationCache extends Subscribable<MutationCacheListener> {
|
|
85
|
-
#mutations: Array<Mutation<any, any, any, any
|
|
85
|
+
#mutations: Map<string, Array<Mutation<any, any, any, any>>>
|
|
86
86
|
#mutationId: number
|
|
87
|
-
#resuming: Promise<unknown> | undefined
|
|
88
87
|
|
|
89
88
|
constructor(public config: MutationCacheConfig = {}) {
|
|
90
89
|
super()
|
|
91
|
-
this.#mutations =
|
|
92
|
-
this.#mutationId =
|
|
90
|
+
this.#mutations = new Map()
|
|
91
|
+
this.#mutationId = Date.now()
|
|
93
92
|
}
|
|
94
93
|
|
|
95
94
|
build<TData, TError, TVariables, TContext>(
|
|
@@ -110,25 +109,59 @@ export class MutationCache extends Subscribable<MutationCacheListener> {
|
|
|
110
109
|
}
|
|
111
110
|
|
|
112
111
|
add(mutation: Mutation<any, any, any, any>): void {
|
|
113
|
-
|
|
112
|
+
const scope = scopeFor(mutation)
|
|
113
|
+
const mutations = this.#mutations.get(scope) ?? []
|
|
114
|
+
mutations.push(mutation)
|
|
115
|
+
this.#mutations.set(scope, mutations)
|
|
114
116
|
this.notify({ type: 'added', mutation })
|
|
115
117
|
}
|
|
116
118
|
|
|
117
119
|
remove(mutation: Mutation<any, any, any, any>): void {
|
|
118
|
-
|
|
120
|
+
const scope = scopeFor(mutation)
|
|
121
|
+
if (this.#mutations.has(scope)) {
|
|
122
|
+
const mutations = this.#mutations
|
|
123
|
+
.get(scope)
|
|
124
|
+
?.filter((x) => x !== mutation)
|
|
125
|
+
if (mutations) {
|
|
126
|
+
if (mutations.length === 0) {
|
|
127
|
+
this.#mutations.delete(scope)
|
|
128
|
+
} else {
|
|
129
|
+
this.#mutations.set(scope, mutations)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
119
134
|
this.notify({ type: 'removed', mutation })
|
|
120
135
|
}
|
|
121
136
|
|
|
137
|
+
canRun(mutation: Mutation<any, any, any, any>): boolean {
|
|
138
|
+
const firstPendingMutation = this.#mutations
|
|
139
|
+
.get(scopeFor(mutation))
|
|
140
|
+
?.find((m) => m.state.status === 'pending')
|
|
141
|
+
|
|
142
|
+
// we can run if there is no current pending mutation (start use-case)
|
|
143
|
+
// or if WE are the first pending mutation (continue use-case)
|
|
144
|
+
return !firstPendingMutation || firstPendingMutation === mutation
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
runNext(mutation: Mutation<any, any, any, any>): Promise<unknown> {
|
|
148
|
+
const foundMutation = this.#mutations
|
|
149
|
+
.get(scopeFor(mutation))
|
|
150
|
+
?.find((m) => m !== mutation && m.state.isPaused)
|
|
151
|
+
|
|
152
|
+
return foundMutation?.continue() ?? Promise.resolve()
|
|
153
|
+
}
|
|
154
|
+
|
|
122
155
|
clear(): void {
|
|
123
156
|
notifyManager.batch(() => {
|
|
124
|
-
this
|
|
157
|
+
this.getAll().forEach((mutation) => {
|
|
125
158
|
this.remove(mutation)
|
|
126
159
|
})
|
|
127
160
|
})
|
|
128
161
|
}
|
|
129
162
|
|
|
130
163
|
getAll(): Array<Mutation> {
|
|
131
|
-
return this.#mutations
|
|
164
|
+
return [...this.#mutations.values()].flat()
|
|
132
165
|
}
|
|
133
166
|
|
|
134
167
|
find<
|
|
@@ -141,15 +174,13 @@ export class MutationCache extends Subscribable<MutationCacheListener> {
|
|
|
141
174
|
): Mutation<TData, TError, TVariables, TContext> | undefined {
|
|
142
175
|
const defaultedFilters = { exact: true, ...filters }
|
|
143
176
|
|
|
144
|
-
return this
|
|
177
|
+
return this.getAll().find((mutation) =>
|
|
145
178
|
matchMutation(defaultedFilters, mutation),
|
|
146
|
-
)
|
|
179
|
+
) as Mutation<TData, TError, TVariables, TContext> | undefined
|
|
147
180
|
}
|
|
148
181
|
|
|
149
182
|
findAll(filters: MutationFilters = {}): Array<Mutation> {
|
|
150
|
-
return this
|
|
151
|
-
matchMutation(filters, mutation),
|
|
152
|
-
)
|
|
183
|
+
return this.getAll().filter((mutation) => matchMutation(filters, mutation))
|
|
153
184
|
}
|
|
154
185
|
|
|
155
186
|
notify(event: MutationCacheNotifyEvent) {
|
|
@@ -161,21 +192,16 @@ export class MutationCache extends Subscribable<MutationCacheListener> {
|
|
|
161
192
|
}
|
|
162
193
|
|
|
163
194
|
resumePausedMutations(): Promise<unknown> {
|
|
164
|
-
|
|
165
|
-
.then(() => {
|
|
166
|
-
const pausedMutations = this.#mutations.filter((x) => x.state.isPaused)
|
|
167
|
-
return notifyManager.batch(() =>
|
|
168
|
-
pausedMutations.reduce(
|
|
169
|
-
(promise, mutation) =>
|
|
170
|
-
promise.then(() => mutation.continue().catch(noop)),
|
|
171
|
-
Promise.resolve() as Promise<unknown>,
|
|
172
|
-
),
|
|
173
|
-
)
|
|
174
|
-
})
|
|
175
|
-
.then(() => {
|
|
176
|
-
this.#resuming = undefined
|
|
177
|
-
})
|
|
195
|
+
const pausedMutations = this.getAll().filter((x) => x.state.isPaused)
|
|
178
196
|
|
|
179
|
-
return
|
|
197
|
+
return notifyManager.batch(() =>
|
|
198
|
+
Promise.all(
|
|
199
|
+
pausedMutations.map((mutation) => mutation.continue().catch(noop)),
|
|
200
|
+
),
|
|
201
|
+
)
|
|
180
202
|
}
|
|
181
203
|
}
|
|
204
|
+
|
|
205
|
+
function scopeFor(mutation: Mutation<any, any, any, any>) {
|
|
206
|
+
return mutation.options.scope?.id ?? String(mutation.mutationId)
|
|
207
|
+
}
|
package/src/query.ts
CHANGED
|
@@ -160,7 +160,7 @@ export class Query<
|
|
|
160
160
|
#revertState?: QueryState<TData, TError>
|
|
161
161
|
#cache: QueryCache
|
|
162
162
|
#retryer?: Retryer<TData>
|
|
163
|
-
|
|
163
|
+
observers: Array<QueryObserver<any, any, any, any, any>>
|
|
164
164
|
#defaultOptions?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>
|
|
165
165
|
#abortSignalConsumed: boolean
|
|
166
166
|
|
|
@@ -170,7 +170,7 @@ export class Query<
|
|
|
170
170
|
this.#abortSignalConsumed = false
|
|
171
171
|
this.#defaultOptions = config.defaultOptions
|
|
172
172
|
this.setOptions(config.options)
|
|
173
|
-
this
|
|
173
|
+
this.observers = []
|
|
174
174
|
this.#cache = config.cache
|
|
175
175
|
this.queryKey = config.queryKey
|
|
176
176
|
this.queryHash = config.queryHash
|
|
@@ -191,7 +191,7 @@ export class Query<
|
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
protected optionalRemove() {
|
|
194
|
-
if (!this
|
|
194
|
+
if (!this.observers.length && this.state.fetchStatus === 'idle') {
|
|
195
195
|
this.#cache.remove(this)
|
|
196
196
|
}
|
|
197
197
|
}
|
|
@@ -238,9 +238,7 @@ export class Query<
|
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
isActive(): boolean {
|
|
241
|
-
return this
|
|
242
|
-
(observer) => observer.options.enabled !== false,
|
|
243
|
-
)
|
|
241
|
+
return this.observers.some((observer) => observer.options.enabled !== false)
|
|
244
242
|
}
|
|
245
243
|
|
|
246
244
|
isDisabled(): boolean {
|
|
@@ -253,7 +251,7 @@ export class Query<
|
|
|
253
251
|
}
|
|
254
252
|
|
|
255
253
|
if (this.getObserversCount() > 0) {
|
|
256
|
-
return this
|
|
254
|
+
return this.observers.some(
|
|
257
255
|
(observer) => observer.getCurrentResult().isStale,
|
|
258
256
|
)
|
|
259
257
|
}
|
|
@@ -270,7 +268,7 @@ export class Query<
|
|
|
270
268
|
}
|
|
271
269
|
|
|
272
270
|
onFocus(): void {
|
|
273
|
-
const observer = this
|
|
271
|
+
const observer = this.observers.find((x) => x.shouldFetchOnWindowFocus())
|
|
274
272
|
|
|
275
273
|
observer?.refetch({ cancelRefetch: false })
|
|
276
274
|
|
|
@@ -279,7 +277,7 @@ export class Query<
|
|
|
279
277
|
}
|
|
280
278
|
|
|
281
279
|
onOnline(): void {
|
|
282
|
-
const observer = this
|
|
280
|
+
const observer = this.observers.find((x) => x.shouldFetchOnReconnect())
|
|
283
281
|
|
|
284
282
|
observer?.refetch({ cancelRefetch: false })
|
|
285
283
|
|
|
@@ -288,8 +286,8 @@ export class Query<
|
|
|
288
286
|
}
|
|
289
287
|
|
|
290
288
|
addObserver(observer: QueryObserver<any, any, any, any, any>): void {
|
|
291
|
-
if (!this
|
|
292
|
-
this
|
|
289
|
+
if (!this.observers.includes(observer)) {
|
|
290
|
+
this.observers.push(observer)
|
|
293
291
|
|
|
294
292
|
// Stop the query from being garbage collected
|
|
295
293
|
this.clearGcTimeout()
|
|
@@ -299,10 +297,10 @@ export class Query<
|
|
|
299
297
|
}
|
|
300
298
|
|
|
301
299
|
removeObserver(observer: QueryObserver<any, any, any, any, any>): void {
|
|
302
|
-
if (this
|
|
303
|
-
this
|
|
300
|
+
if (this.observers.includes(observer)) {
|
|
301
|
+
this.observers = this.observers.filter((x) => x !== observer)
|
|
304
302
|
|
|
305
|
-
if (!this
|
|
303
|
+
if (!this.observers.length) {
|
|
306
304
|
// If the transport layer does not support cancellation
|
|
307
305
|
// we'll let the query continue so the result can be cached
|
|
308
306
|
if (this.#retryer) {
|
|
@@ -321,7 +319,7 @@ export class Query<
|
|
|
321
319
|
}
|
|
322
320
|
|
|
323
321
|
getObserversCount(): number {
|
|
324
|
-
return this
|
|
322
|
+
return this.observers.length
|
|
325
323
|
}
|
|
326
324
|
|
|
327
325
|
invalidate(): void {
|
|
@@ -354,7 +352,7 @@ export class Query<
|
|
|
354
352
|
// Use the options from the first observer with a query function if no function is found.
|
|
355
353
|
// This can happen when the query is hydrated or created with setQueryData.
|
|
356
354
|
if (!this.options.queryFn) {
|
|
357
|
-
const observer = this
|
|
355
|
+
const observer = this.observers.find((x) => x.options.queryFn)
|
|
358
356
|
if (observer) {
|
|
359
357
|
this.setOptions(observer.options)
|
|
360
358
|
}
|
|
@@ -527,9 +525,10 @@ export class Query<
|
|
|
527
525
|
retry: context.options.retry,
|
|
528
526
|
retryDelay: context.options.retryDelay,
|
|
529
527
|
networkMode: context.options.networkMode,
|
|
528
|
+
canRun: () => true,
|
|
530
529
|
})
|
|
531
530
|
|
|
532
|
-
return this.#retryer.
|
|
531
|
+
return this.#retryer.start()
|
|
533
532
|
}
|
|
534
533
|
|
|
535
534
|
#dispatch(action: Action<TData, TError>): void {
|
|
@@ -607,7 +606,7 @@ export class Query<
|
|
|
607
606
|
this.state = reducer(this.state)
|
|
608
607
|
|
|
609
608
|
notifyManager.batch(() => {
|
|
610
|
-
this
|
|
609
|
+
this.observers.forEach((observer) => {
|
|
611
610
|
observer.onQueryUpdate()
|
|
612
611
|
})
|
|
613
612
|
|
package/src/retryer.ts
CHANGED
|
@@ -16,6 +16,7 @@ interface RetryerConfig<TData = unknown, TError = DefaultError> {
|
|
|
16
16
|
retry?: RetryValue<TError>
|
|
17
17
|
retryDelay?: RetryDelayValue<TError>
|
|
18
18
|
networkMode: NetworkMode | undefined
|
|
19
|
+
canRun: () => boolean
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export interface Retryer<TData = unknown> {
|
|
@@ -24,6 +25,8 @@ export interface Retryer<TData = unknown> {
|
|
|
24
25
|
continue: () => Promise<unknown>
|
|
25
26
|
cancelRetry: () => void
|
|
26
27
|
continueRetry: () => void
|
|
28
|
+
canStart: () => boolean
|
|
29
|
+
start: () => Promise<TData>
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
export type RetryValue<TError> = boolean | number | ShouldRetryFunction<TError>
|
|
@@ -69,7 +72,7 @@ export function createRetryer<TData = unknown, TError = DefaultError>(
|
|
|
69
72
|
let isRetryCancelled = false
|
|
70
73
|
let failureCount = 0
|
|
71
74
|
let isResolved = false
|
|
72
|
-
let continueFn: ((value?: unknown) =>
|
|
75
|
+
let continueFn: ((value?: unknown) => void) | undefined
|
|
73
76
|
let promiseResolve: (data: TData) => void
|
|
74
77
|
let promiseReject: (error: TError) => void
|
|
75
78
|
|
|
@@ -93,9 +96,12 @@ export function createRetryer<TData = unknown, TError = DefaultError>(
|
|
|
93
96
|
isRetryCancelled = false
|
|
94
97
|
}
|
|
95
98
|
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
(config.networkMode
|
|
99
|
+
const canContinue = () =>
|
|
100
|
+
focusManager.isFocused() &&
|
|
101
|
+
(config.networkMode === 'always' || onlineManager.isOnline()) &&
|
|
102
|
+
config.canRun()
|
|
103
|
+
|
|
104
|
+
const canStart = () => canFetch(config.networkMode) && config.canRun()
|
|
99
105
|
|
|
100
106
|
const resolve = (value: any) => {
|
|
101
107
|
if (!isResolved) {
|
|
@@ -118,11 +124,9 @@ export function createRetryer<TData = unknown, TError = DefaultError>(
|
|
|
118
124
|
const pause = () => {
|
|
119
125
|
return new Promise((continueResolve) => {
|
|
120
126
|
continueFn = (value) => {
|
|
121
|
-
|
|
122
|
-
if (canContinue) {
|
|
127
|
+
if (isResolved || canContinue()) {
|
|
123
128
|
continueResolve(value)
|
|
124
129
|
}
|
|
125
|
-
return canContinue
|
|
126
130
|
}
|
|
127
131
|
config.onPause?.()
|
|
128
132
|
}).then(() => {
|
|
@@ -184,10 +188,7 @@ export function createRetryer<TData = unknown, TError = DefaultError>(
|
|
|
184
188
|
sleep(delay)
|
|
185
189
|
// Pause if the document is not visible or when the device is offline
|
|
186
190
|
.then(() => {
|
|
187
|
-
|
|
188
|
-
return pause()
|
|
189
|
-
}
|
|
190
|
-
return
|
|
191
|
+
return canContinue() ? undefined : pause()
|
|
191
192
|
})
|
|
192
193
|
.then(() => {
|
|
193
194
|
if (isRetryCancelled) {
|
|
@@ -199,21 +200,24 @@ export function createRetryer<TData = unknown, TError = DefaultError>(
|
|
|
199
200
|
})
|
|
200
201
|
}
|
|
201
202
|
|
|
202
|
-
// Start loop
|
|
203
|
-
if (canFetch(config.networkMode)) {
|
|
204
|
-
run()
|
|
205
|
-
} else {
|
|
206
|
-
pause().then(run)
|
|
207
|
-
}
|
|
208
|
-
|
|
209
203
|
return {
|
|
210
204
|
promise,
|
|
211
205
|
cancel,
|
|
212
206
|
continue: () => {
|
|
213
|
-
|
|
214
|
-
return
|
|
207
|
+
continueFn?.()
|
|
208
|
+
return promise
|
|
215
209
|
},
|
|
216
210
|
cancelRetry,
|
|
217
211
|
continueRetry,
|
|
212
|
+
canStart,
|
|
213
|
+
start: () => {
|
|
214
|
+
// Start loop
|
|
215
|
+
if (canStart()) {
|
|
216
|
+
run()
|
|
217
|
+
} else {
|
|
218
|
+
pause().then(run)
|
|
219
|
+
}
|
|
220
|
+
return promise
|
|
221
|
+
},
|
|
218
222
|
}
|
|
219
223
|
}
|
package/src/types.ts
CHANGED
|
@@ -717,6 +717,10 @@ export type MutationKey = ReadonlyArray<unknown>
|
|
|
717
717
|
|
|
718
718
|
export type MutationStatus = 'idle' | 'pending' | 'success' | 'error'
|
|
719
719
|
|
|
720
|
+
export type MutationScope = {
|
|
721
|
+
id: string
|
|
722
|
+
}
|
|
723
|
+
|
|
720
724
|
export type MutationMeta = Register extends {
|
|
721
725
|
mutationMeta: infer TMutationMeta
|
|
722
726
|
}
|
|
@@ -762,6 +766,7 @@ export interface MutationOptions<
|
|
|
762
766
|
gcTime?: number
|
|
763
767
|
_defaulted?: boolean
|
|
764
768
|
meta?: MutationMeta
|
|
769
|
+
scope?: MutationScope
|
|
765
770
|
}
|
|
766
771
|
|
|
767
772
|
export interface MutationObserverOptions<
|