@tanstack/query-core 4.24.4 → 4.24.6
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/mutation.d.ts +1 -1
- package/build/lib/mutation.esm.js +2 -5
- package/build/lib/mutation.esm.js.map +1 -1
- package/build/lib/mutation.js +2 -5
- package/build/lib/mutation.js.map +1 -1
- package/build/lib/mutation.mjs +2 -5
- package/build/lib/mutation.mjs.map +1 -1
- package/build/lib/mutationCache.d.ts +2 -1
- package/build/lib/mutationCache.esm.js +9 -2
- package/build/lib/mutationCache.esm.js.map +1 -1
- package/build/lib/mutationCache.js +9 -2
- package/build/lib/mutationCache.js.map +1 -1
- package/build/lib/mutationCache.mjs +9 -2
- package/build/lib/mutationCache.mjs.map +1 -1
- package/build/lib/queryCache.d.ts +1 -1
- package/build/lib/queryCache.esm.js.map +1 -1
- package/build/lib/queryCache.js.map +1 -1
- package/build/lib/queryCache.mjs.map +1 -1
- package/build/lib/queryClient.d.ts +1 -1
- package/build/lib/queryClient.esm.js.map +1 -1
- package/build/lib/queryClient.js.map +1 -1
- package/build/lib/queryClient.mjs.map +1 -1
- package/build/lib/retryer.d.ts +1 -1
- package/build/lib/retryer.esm.js +8 -3
- package/build/lib/retryer.esm.js.map +1 -1
- package/build/lib/retryer.js +8 -3
- package/build/lib/retryer.js.map +1 -1
- package/build/lib/retryer.mjs +8 -3
- package/build/lib/retryer.mjs.map +1 -1
- package/build/umd/index.development.js +19 -10
- 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/mutation.ts +2 -6
- package/src/mutationCache.ts +18 -9
- package/src/queryCache.ts +2 -2
- package/src/queryClient.ts +1 -1
- package/src/retryer.ts +8 -5
- package/src/tests/queryClient.test.tsx +77 -1
package/package.json
CHANGED
package/src/mutation.ts
CHANGED
|
@@ -159,12 +159,8 @@ export class Mutation<
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
continue(): Promise<
|
|
163
|
-
|
|
164
|
-
this.retryer.continue()
|
|
165
|
-
return this.retryer.promise
|
|
166
|
-
}
|
|
167
|
-
return this.execute()
|
|
162
|
+
continue(): Promise<unknown> {
|
|
163
|
+
return this.retryer?.continue() ?? this.execute()
|
|
168
164
|
}
|
|
169
165
|
|
|
170
166
|
async execute(): Promise<TData> {
|
package/src/mutationCache.ts
CHANGED
|
@@ -79,6 +79,7 @@ export class MutationCache extends Subscribable<MutationCacheListener> {
|
|
|
79
79
|
|
|
80
80
|
private mutations: Mutation<any, any, any, any>[]
|
|
81
81
|
private mutationId: number
|
|
82
|
+
private resuming: Promise<unknown> | undefined
|
|
82
83
|
|
|
83
84
|
constructor(config?: MutationCacheConfig) {
|
|
84
85
|
super()
|
|
@@ -152,14 +153,22 @@ export class MutationCache extends Subscribable<MutationCacheListener> {
|
|
|
152
153
|
})
|
|
153
154
|
}
|
|
154
155
|
|
|
155
|
-
resumePausedMutations(): Promise<
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
156
|
+
resumePausedMutations(): Promise<unknown> {
|
|
157
|
+
this.resuming = (this.resuming ?? Promise.resolve())
|
|
158
|
+
.then(() => {
|
|
159
|
+
const pausedMutations = this.mutations.filter((x) => x.state.isPaused)
|
|
160
|
+
return notifyManager.batch(() =>
|
|
161
|
+
pausedMutations.reduce(
|
|
162
|
+
(promise, mutation) =>
|
|
163
|
+
promise.then(() => mutation.continue().catch(noop)),
|
|
164
|
+
Promise.resolve() as Promise<unknown>,
|
|
165
|
+
),
|
|
166
|
+
)
|
|
167
|
+
})
|
|
168
|
+
.then(() => {
|
|
169
|
+
this.resuming = undefined
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
return this.resuming
|
|
164
173
|
}
|
|
165
174
|
}
|
package/src/queryCache.ts
CHANGED
|
@@ -149,10 +149,10 @@ export class QueryCache extends Subscribable<QueryCacheListener> {
|
|
|
149
149
|
TQueryFnData = unknown,
|
|
150
150
|
TError = unknown,
|
|
151
151
|
TData = TQueryFnData,
|
|
152
|
-
|
|
152
|
+
TQueryKey extends QueryKey = QueryKey,
|
|
153
153
|
>(
|
|
154
154
|
queryHash: string,
|
|
155
|
-
): Query<TQueryFnData, TError, TData,
|
|
155
|
+
): Query<TQueryFnData, TError, TData, TQueryKey> | undefined {
|
|
156
156
|
return this.queriesMap[queryHash]
|
|
157
157
|
}
|
|
158
158
|
|
package/src/queryClient.ts
CHANGED
package/src/retryer.ts
CHANGED
|
@@ -21,7 +21,7 @@ interface RetryerConfig<TData = unknown, TError = unknown> {
|
|
|
21
21
|
export interface Retryer<TData = unknown> {
|
|
22
22
|
promise: Promise<TData>
|
|
23
23
|
cancel: (cancelOptions?: CancelOptions) => void
|
|
24
|
-
continue: () =>
|
|
24
|
+
continue: () => Promise<unknown>
|
|
25
25
|
cancelRetry: () => void
|
|
26
26
|
continueRetry: () => void
|
|
27
27
|
}
|
|
@@ -69,7 +69,7 @@ export function createRetryer<TData = unknown, TError = unknown>(
|
|
|
69
69
|
let isRetryCancelled = false
|
|
70
70
|
let failureCount = 0
|
|
71
71
|
let isResolved = false
|
|
72
|
-
let continueFn: ((value?: unknown) =>
|
|
72
|
+
let continueFn: ((value?: unknown) => boolean) | undefined
|
|
73
73
|
let promiseResolve: (data: TData) => void
|
|
74
74
|
let promiseReject: (error: TError) => void
|
|
75
75
|
|
|
@@ -118,9 +118,11 @@ export function createRetryer<TData = unknown, TError = unknown>(
|
|
|
118
118
|
const pause = () => {
|
|
119
119
|
return new Promise((continueResolve) => {
|
|
120
120
|
continueFn = (value) => {
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
const canContinue = isResolved || !shouldPause()
|
|
122
|
+
if (canContinue) {
|
|
123
|
+
continueResolve(value)
|
|
123
124
|
}
|
|
125
|
+
return canContinue
|
|
124
126
|
}
|
|
125
127
|
config.onPause?.()
|
|
126
128
|
}).then(() => {
|
|
@@ -208,7 +210,8 @@ export function createRetryer<TData = unknown, TError = unknown>(
|
|
|
208
210
|
promise,
|
|
209
211
|
cancel,
|
|
210
212
|
continue: () => {
|
|
211
|
-
continueFn?.()
|
|
213
|
+
const didContinue = continueFn?.()
|
|
214
|
+
return didContinue ? promise : Promise.resolve()
|
|
212
215
|
},
|
|
213
216
|
cancelRetry,
|
|
214
217
|
continueRetry,
|
|
@@ -8,8 +8,9 @@ import type {
|
|
|
8
8
|
QueryFunction,
|
|
9
9
|
QueryObserverOptions,
|
|
10
10
|
} from '..'
|
|
11
|
-
import { InfiniteQueryObserver, QueryObserver } from '..'
|
|
11
|
+
import { InfiniteQueryObserver, MutationObserver, QueryObserver } from '..'
|
|
12
12
|
import { focusManager, onlineManager } from '..'
|
|
13
|
+
import { noop } from '../utils'
|
|
13
14
|
|
|
14
15
|
describe('queryClient', () => {
|
|
15
16
|
let queryClient: QueryClient
|
|
@@ -1468,6 +1469,81 @@ describe('queryClient', () => {
|
|
|
1468
1469
|
onlineManager.setOnline(undefined)
|
|
1469
1470
|
})
|
|
1470
1471
|
|
|
1472
|
+
test('should resume paused mutations when coming online', async () => {
|
|
1473
|
+
const consoleMock = jest.spyOn(console, 'error')
|
|
1474
|
+
consoleMock.mockImplementation(() => undefined)
|
|
1475
|
+
onlineManager.setOnline(false)
|
|
1476
|
+
|
|
1477
|
+
const observer1 = new MutationObserver(queryClient, {
|
|
1478
|
+
mutationFn: async () => 1,
|
|
1479
|
+
})
|
|
1480
|
+
|
|
1481
|
+
const observer2 = new MutationObserver(queryClient, {
|
|
1482
|
+
mutationFn: async () => 2,
|
|
1483
|
+
})
|
|
1484
|
+
void observer1.mutate().catch(noop)
|
|
1485
|
+
void observer2.mutate().catch(noop)
|
|
1486
|
+
|
|
1487
|
+
await waitFor(() => {
|
|
1488
|
+
expect(observer1.getCurrentResult().isPaused).toBeTruthy()
|
|
1489
|
+
expect(observer2.getCurrentResult().isPaused).toBeTruthy()
|
|
1490
|
+
})
|
|
1491
|
+
|
|
1492
|
+
onlineManager.setOnline(true)
|
|
1493
|
+
|
|
1494
|
+
await waitFor(() => {
|
|
1495
|
+
expect(observer1.getCurrentResult().status).toBe('success')
|
|
1496
|
+
expect(observer1.getCurrentResult().status).toBe('success')
|
|
1497
|
+
})
|
|
1498
|
+
|
|
1499
|
+
onlineManager.setOnline(undefined)
|
|
1500
|
+
})
|
|
1501
|
+
|
|
1502
|
+
test('should resume paused mutations one after the other when invoked manually at the same time', async () => {
|
|
1503
|
+
const consoleMock = jest.spyOn(console, 'error')
|
|
1504
|
+
consoleMock.mockImplementation(() => undefined)
|
|
1505
|
+
onlineManager.setOnline(false)
|
|
1506
|
+
|
|
1507
|
+
const orders: Array<string> = []
|
|
1508
|
+
|
|
1509
|
+
const observer1 = new MutationObserver(queryClient, {
|
|
1510
|
+
mutationFn: async () => {
|
|
1511
|
+
orders.push('1start')
|
|
1512
|
+
await sleep(50)
|
|
1513
|
+
orders.push('1end')
|
|
1514
|
+
return 1
|
|
1515
|
+
},
|
|
1516
|
+
})
|
|
1517
|
+
|
|
1518
|
+
const observer2 = new MutationObserver(queryClient, {
|
|
1519
|
+
mutationFn: async () => {
|
|
1520
|
+
orders.push('2start')
|
|
1521
|
+
await sleep(20)
|
|
1522
|
+
orders.push('2end')
|
|
1523
|
+
return 2
|
|
1524
|
+
},
|
|
1525
|
+
})
|
|
1526
|
+
void observer1.mutate().catch(noop)
|
|
1527
|
+
void observer2.mutate().catch(noop)
|
|
1528
|
+
|
|
1529
|
+
await waitFor(() => {
|
|
1530
|
+
expect(observer1.getCurrentResult().isPaused).toBeTruthy()
|
|
1531
|
+
expect(observer2.getCurrentResult().isPaused).toBeTruthy()
|
|
1532
|
+
})
|
|
1533
|
+
|
|
1534
|
+
onlineManager.setOnline(undefined)
|
|
1535
|
+
void queryClient.resumePausedMutations()
|
|
1536
|
+
await sleep(5)
|
|
1537
|
+
await queryClient.resumePausedMutations()
|
|
1538
|
+
|
|
1539
|
+
await waitFor(() => {
|
|
1540
|
+
expect(observer1.getCurrentResult().status).toBe('success')
|
|
1541
|
+
expect(observer2.getCurrentResult().status).toBe('success')
|
|
1542
|
+
})
|
|
1543
|
+
|
|
1544
|
+
expect(orders).toEqual(['1start', '1end', '2start', '2end'])
|
|
1545
|
+
})
|
|
1546
|
+
|
|
1471
1547
|
test('should notify queryCache and mutationCache after multiple mounts and single unmount', async () => {
|
|
1472
1548
|
const testClient = createQueryClient()
|
|
1473
1549
|
testClient.mount()
|