@veams/status-quo-query 0.8.1 → 0.9.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/README.md +12 -8
- package/dist/query.d.ts +2 -2
- package/dist/query.js +45 -30
- package/dist/query.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/query.spec.ts +31 -13
- package/src/__tests__/tracked.spec.ts +15 -2
- package/src/query.ts +51 -38
package/README.md
CHANGED
|
@@ -400,10 +400,10 @@ Use `dependsOn` when a query needs data from other queries before it can run.
|
|
|
400
400
|
|
|
401
401
|
`dependsOn` accepts a `QueryDependencyTuple`:
|
|
402
402
|
|
|
403
|
-
- an ordered list of source query
|
|
403
|
+
- an ordered list of source query services
|
|
404
404
|
- a `deriveOptions(...)` callback that returns only `queryKey` and/or `enabled`
|
|
405
405
|
|
|
406
|
-
The watcher starts on the first `subscribe(...)` or `refetch()`, reads the current
|
|
406
|
+
The watcher starts on the first `subscribe(...)` or `refetch()`, reads the current source snapshots immediately, and stops after the last unsubscribe. A downstream `refetch()` refetches all source services first, then refetches the derived query.
|
|
407
407
|
|
|
408
408
|
Untracked example:
|
|
409
409
|
|
|
@@ -416,8 +416,8 @@ type Config = { region: string; companyProfileEnabled: boolean };
|
|
|
416
416
|
|
|
417
417
|
const queryClient = new QueryClient();
|
|
418
418
|
const createQuery = setupQuery(queryClient);
|
|
419
|
-
const
|
|
420
|
-
const
|
|
419
|
+
const userQuery = createQuery(['user', 42] as const, () => fetchUser(42), { enabled: false });
|
|
420
|
+
const configQuery = createQuery(['config', 'global'] as const, fetchConfig, { enabled: false });
|
|
421
421
|
|
|
422
422
|
const companyProfileQuery = createQuery(
|
|
423
423
|
['company-profile', { companyId: undefined as string | undefined, region: undefined as string | undefined }],
|
|
@@ -425,7 +425,7 @@ const companyProfileQuery = createQuery(
|
|
|
425
425
|
{
|
|
426
426
|
enabled: false,
|
|
427
427
|
dependsOn: <QueryDependencyTuple<[User, Config]>>[
|
|
428
|
-
[
|
|
428
|
+
[userQuery, configQuery],
|
|
429
429
|
([userSnapshot, configSnapshot]) => {
|
|
430
430
|
if (!userSnapshot.data?.companyId || !configSnapshot.data?.region) {
|
|
431
431
|
return { enabled: false };
|
|
@@ -455,7 +455,11 @@ import { setupQueryManager } from '@veams/status-quo-query';
|
|
|
455
455
|
|
|
456
456
|
const queryClient = new QueryClient();
|
|
457
457
|
const manager = setupQueryManager(queryClient);
|
|
458
|
-
const
|
|
458
|
+
const selectionQuery = manager.createUntrackedQuery(
|
|
459
|
+
['selection'] as const,
|
|
460
|
+
fetchSelection,
|
|
461
|
+
{ enabled: false }
|
|
462
|
+
);
|
|
459
463
|
|
|
460
464
|
const productQuery = manager.createQuery(
|
|
461
465
|
['product', { deps: { applicationId: 'pending' }, view: { page: 0 } }],
|
|
@@ -463,7 +467,7 @@ const productQuery = manager.createQuery(
|
|
|
463
467
|
{
|
|
464
468
|
enabled: false,
|
|
465
469
|
dependsOn: [
|
|
466
|
-
[
|
|
470
|
+
[selectionQuery],
|
|
467
471
|
([selectionSnapshot]) =>
|
|
468
472
|
selectionSnapshot.data?.applicationId
|
|
469
473
|
? {
|
|
@@ -610,7 +614,7 @@ It also adds:
|
|
|
610
614
|
|
|
611
615
|
- `dependsOn?: QueryDependencyTuple<[...sources]>`
|
|
612
616
|
|
|
613
|
-
`dependsOn` observes the listed source
|
|
617
|
+
`dependsOn` observes the listed source query services and lets the downstream query derive only `queryKey` and `enabled`. Source services are activated while the downstream query is active, and downstream `refetch()` refetches the sources first. The public `QueryService` API does not change when this option is used.
|
|
614
618
|
|
|
615
619
|
`QueryService` methods:
|
|
616
620
|
|
package/dist/query.d.ts
CHANGED
|
@@ -42,8 +42,8 @@ type QueryDependencyDerivedOptions<TQueryKey extends QueryKey = QueryKey> = {
|
|
|
42
42
|
queryKey?: TQueryKey;
|
|
43
43
|
};
|
|
44
44
|
export type QueryDependencyTuple<TSources extends readonly unknown[], TQueryKey extends QueryKey = QueryKey> = readonly [
|
|
45
|
-
|
|
46
|
-
readonly [K in keyof TSources]:
|
|
45
|
+
sources: {
|
|
46
|
+
readonly [K in keyof TSources]: QueryService<TSources[K], Error>;
|
|
47
47
|
},
|
|
48
48
|
deriveOptions: (sourceSnapshots: {
|
|
49
49
|
readonly [K in keyof TSources]: QueryServiceSnapshot<TSources[K], Error>;
|
package/dist/query.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
// Import QueryObserver to monitor and manage individual queries.
|
|
3
|
-
QueryObserver,
|
|
3
|
+
QueryObserver, } from '@tanstack/query-core';
|
|
4
4
|
import { extractTrackedDependencies, } from './tracking.js';
|
|
5
5
|
/**
|
|
6
6
|
* Extracts and maps status and fetchStatus to our QueryMetaState interface.
|
|
@@ -30,7 +30,7 @@ export function setupQuery(queryClient) {
|
|
|
30
30
|
if (!dependsOn) {
|
|
31
31
|
return service.service;
|
|
32
32
|
}
|
|
33
|
-
return bindQueryDependencies(
|
|
33
|
+
return bindQueryDependencies(service, queryKey, dependsOn);
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
@@ -63,7 +63,7 @@ export function setupTrackedQuery(queryClient, trackingRegistry) {
|
|
|
63
63
|
trackingRegistry.register(nextQueryHash, extractTrackedDependencies(service.getCurrentQueryKey()));
|
|
64
64
|
};
|
|
65
65
|
const dependencyController = dependsOn
|
|
66
|
-
? createDependencyController(
|
|
66
|
+
? createDependencyController(queryKey, applyTrackedDerivedState, dependsOn)
|
|
67
67
|
: undefined;
|
|
68
68
|
const ensureRegistered = () => {
|
|
69
69
|
// Build resolves the current live TanStack query for the stored observer options. This is
|
|
@@ -79,7 +79,7 @@ export function setupTrackedQuery(queryClient, trackingRegistry) {
|
|
|
79
79
|
return {
|
|
80
80
|
...service.service,
|
|
81
81
|
refetch: async (refetchOptions) => {
|
|
82
|
-
dependencyController?.
|
|
82
|
+
await dependencyController?.evaluateForRefetch();
|
|
83
83
|
// Refetch is one of the two explicit reactivation paths agreed on in the design.
|
|
84
84
|
ensureRegistered();
|
|
85
85
|
return service.service.refetch(refetchOptions);
|
|
@@ -158,13 +158,13 @@ function createQueryService(queryClient, queryKey, queryFn, options) {
|
|
|
158
158
|
},
|
|
159
159
|
};
|
|
160
160
|
}
|
|
161
|
-
function bindQueryDependencies(
|
|
162
|
-
const dependencyController = createDependencyController(
|
|
161
|
+
function bindQueryDependencies(queryService, queryKey, dependsOn) {
|
|
162
|
+
const dependencyController = createDependencyController(queryKey, queryService.setDerivedState, dependsOn);
|
|
163
163
|
let subscriberCount = 0;
|
|
164
164
|
return {
|
|
165
165
|
...queryService.service,
|
|
166
166
|
refetch: async (refetchOptions) => {
|
|
167
|
-
dependencyController.
|
|
167
|
+
await dependencyController.evaluateForRefetch();
|
|
168
168
|
return queryService.service.refetch(refetchOptions);
|
|
169
169
|
},
|
|
170
170
|
subscribe: (listener) => {
|
|
@@ -183,44 +183,59 @@ function bindQueryDependencies(queryClient, queryService, queryKey, dependsOn) {
|
|
|
183
183
|
},
|
|
184
184
|
};
|
|
185
185
|
}
|
|
186
|
-
function createDependencyController(
|
|
187
|
-
const [
|
|
188
|
-
let
|
|
189
|
-
let
|
|
190
|
-
|
|
191
|
-
|
|
186
|
+
function createDependencyController(baseQueryKey, setDerivedState, dependsOn) {
|
|
187
|
+
const [sources, deriveOptions] = dependsOn;
|
|
188
|
+
let isActive = false;
|
|
189
|
+
let scheduledEvaluation = false;
|
|
190
|
+
let sourceUnsubscribers = [];
|
|
191
|
+
const evaluateBinding = () => {
|
|
192
|
+
const snapshots = sources.map((source) => source.getSnapshot());
|
|
192
193
|
const derivedOptions = deriveOptions(snapshots);
|
|
193
194
|
setDerivedState({
|
|
194
195
|
queryKey: derivedOptions.queryKey ?? baseQueryKey,
|
|
195
196
|
...(derivedOptions.enabled === undefined ? {} : { enabled: derivedOptions.enabled }),
|
|
196
197
|
});
|
|
197
198
|
};
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
199
|
+
const scheduleEvaluate = () => {
|
|
200
|
+
if (scheduledEvaluation) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
scheduledEvaluation = true;
|
|
204
|
+
queueMicrotask(() => {
|
|
205
|
+
scheduledEvaluation = false;
|
|
206
|
+
if (!isActive) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
evaluateBinding();
|
|
210
|
+
});
|
|
211
|
+
};
|
|
202
212
|
return {
|
|
203
213
|
activate: () => {
|
|
204
|
-
if (
|
|
214
|
+
if (isActive) {
|
|
205
215
|
return;
|
|
206
216
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
217
|
+
isActive = true;
|
|
218
|
+
sourceUnsubscribers = sources.map((source) => source.subscribe(() => {
|
|
219
|
+
scheduleEvaluate();
|
|
220
|
+
}));
|
|
221
|
+
evaluateBinding();
|
|
210
222
|
},
|
|
211
223
|
deactivate: () => {
|
|
212
|
-
|
|
213
|
-
unsubscribe
|
|
214
|
-
|
|
224
|
+
isActive = false;
|
|
225
|
+
sourceUnsubscribers.forEach((unsubscribe) => {
|
|
226
|
+
unsubscribe();
|
|
227
|
+
});
|
|
228
|
+
sourceUnsubscribers = [];
|
|
215
229
|
},
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
230
|
+
evaluateForRefetch: async () => {
|
|
231
|
+
await Promise.all(sources.map(async (source) => {
|
|
232
|
+
await source.refetch();
|
|
233
|
+
}));
|
|
234
|
+
if (isActive) {
|
|
235
|
+
scheduleEvaluate();
|
|
219
236
|
return;
|
|
220
237
|
}
|
|
221
|
-
|
|
222
|
-
evaluateBinding(transientObserver.getCurrentResult());
|
|
223
|
-
transientObserver.destroy();
|
|
238
|
+
evaluateBinding();
|
|
224
239
|
},
|
|
225
240
|
};
|
|
226
241
|
}
|
package/dist/query.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO;AAaL,iEAAiE;AACjE,aAAa,
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -68,6 +68,12 @@ describe('Query Service', () => {
|
|
|
68
68
|
const createQuery = setupQuery(queryClient);
|
|
69
69
|
const userKey = ['user', 42] as const;
|
|
70
70
|
const configKey = ['config', 'global'] as const;
|
|
71
|
+
const userQuery = createQuery(userKey, jest.fn().mockResolvedValue({ companyId: 'company-1' }), {
|
|
72
|
+
enabled: false,
|
|
73
|
+
});
|
|
74
|
+
const configQuery = createQuery(configKey, jest.fn().mockResolvedValue({ region: 'eu' }), {
|
|
75
|
+
enabled: false,
|
|
76
|
+
});
|
|
71
77
|
const queryFn = jest
|
|
72
78
|
.fn()
|
|
73
79
|
.mockImplementation(({ queryKey }) => `${queryKey[1].companyId}:${queryKey[1].region}`);
|
|
@@ -78,7 +84,7 @@ describe('Query Service', () => {
|
|
|
78
84
|
{
|
|
79
85
|
enabled: false,
|
|
80
86
|
dependsOn: [
|
|
81
|
-
[
|
|
87
|
+
[userQuery, configQuery],
|
|
82
88
|
([userSnapshot, configSnapshot]) => {
|
|
83
89
|
if (!userSnapshot.data?.companyId || !configSnapshot.data?.region) {
|
|
84
90
|
return { enabled: false };
|
|
@@ -120,21 +126,21 @@ describe('Query Service', () => {
|
|
|
120
126
|
unsubscribe();
|
|
121
127
|
});
|
|
122
128
|
|
|
123
|
-
it('uses
|
|
129
|
+
it('uses source query data when dependsOn is evaluated on first refetch', async () => {
|
|
124
130
|
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: 0 } } });
|
|
125
131
|
const createQuery = setupQuery(queryClient);
|
|
126
132
|
const selectionKey = ['selection'] as const;
|
|
133
|
+
const selectionQueryFn = jest.fn().mockResolvedValue({ id: 'item-2' });
|
|
134
|
+
const selectionQuery = createQuery(selectionKey, selectionQueryFn, { enabled: false });
|
|
127
135
|
const queryFn = jest.fn().mockImplementation(async ({ queryKey }) => queryKey[1].id);
|
|
128
136
|
|
|
129
|
-
queryClient.setQueryData(selectionKey, { id: 'item-2' });
|
|
130
|
-
|
|
131
137
|
const service = createQuery(
|
|
132
138
|
['details', { id: undefined as string | undefined }],
|
|
133
139
|
queryFn,
|
|
134
140
|
{
|
|
135
141
|
enabled: false,
|
|
136
142
|
dependsOn: [
|
|
137
|
-
[
|
|
143
|
+
[selectionQuery],
|
|
138
144
|
([selectionSnapshot]) =>
|
|
139
145
|
selectionSnapshot.data?.id
|
|
140
146
|
? {
|
|
@@ -149,6 +155,7 @@ describe('Query Service', () => {
|
|
|
149
155
|
const result = await service.refetch();
|
|
150
156
|
|
|
151
157
|
expect(result.data).toBe('item-2');
|
|
158
|
+
expect(selectionQueryFn).toHaveBeenCalledTimes(1);
|
|
152
159
|
expect(queryFn).toHaveBeenCalledWith(
|
|
153
160
|
expect.objectContaining({
|
|
154
161
|
queryKey: ['details', { id: 'item-2' }],
|
|
@@ -159,20 +166,21 @@ describe('Query Service', () => {
|
|
|
159
166
|
it('preserves source snapshot tuple order in dependsOn', async () => {
|
|
160
167
|
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: 0 } } });
|
|
161
168
|
const createQuery = setupQuery(queryClient);
|
|
162
|
-
const
|
|
163
|
-
|
|
169
|
+
const firstQuery = createQuery(['source', 'first'] as const, jest.fn().mockResolvedValue({ label: 'first' }), {
|
|
170
|
+
enabled: false,
|
|
171
|
+
});
|
|
172
|
+
const secondQuery = createQuery(['source', 'second'] as const, jest.fn().mockResolvedValue({ label: 'second' }), {
|
|
173
|
+
enabled: false,
|
|
174
|
+
});
|
|
164
175
|
const observedOrders: Array<[string | undefined, string | undefined]> = [];
|
|
165
176
|
|
|
166
|
-
queryClient.setQueryData(firstKey, { label: 'first' });
|
|
167
|
-
queryClient.setQueryData(secondKey, { label: 'second' });
|
|
168
|
-
|
|
169
177
|
const service = createQuery(
|
|
170
178
|
['ordered', { left: undefined as string | undefined, right: undefined as string | undefined }],
|
|
171
179
|
jest.fn().mockResolvedValue('ok'),
|
|
172
180
|
{
|
|
173
181
|
enabled: false,
|
|
174
182
|
dependsOn: [
|
|
175
|
-
[
|
|
183
|
+
[firstQuery, secondQuery],
|
|
176
184
|
([firstSnapshot, secondSnapshot]) => {
|
|
177
185
|
observedOrders.push([firstSnapshot.data?.label, secondSnapshot.data?.label]);
|
|
178
186
|
|
|
@@ -201,6 +209,9 @@ describe('Query Service', () => {
|
|
|
201
209
|
const invalidateQueriesSpy = jest.spyOn(queryClient, 'invalidateQueries');
|
|
202
210
|
const createQuery = setupQuery(queryClient);
|
|
203
211
|
const selectionKey = ['selection'] as const;
|
|
212
|
+
const selectionQuery = createQuery(selectionKey, jest.fn().mockResolvedValue({ id: 'item-3' }), {
|
|
213
|
+
enabled: false,
|
|
214
|
+
});
|
|
204
215
|
|
|
205
216
|
queryClient.setQueryData(selectionKey, { id: 'item-3' });
|
|
206
217
|
|
|
@@ -210,7 +221,7 @@ describe('Query Service', () => {
|
|
|
210
221
|
{
|
|
211
222
|
enabled: false,
|
|
212
223
|
dependsOn: [
|
|
213
|
-
[
|
|
224
|
+
[selectionQuery],
|
|
214
225
|
([selectionSnapshot]) =>
|
|
215
226
|
selectionSnapshot.data?.id
|
|
216
227
|
? {
|
|
@@ -240,6 +251,13 @@ describe('Query Service', () => {
|
|
|
240
251
|
const invalidateQueriesSpy = jest.spyOn(queryClient, 'invalidateQueries');
|
|
241
252
|
const createQuery = setupQuery(queryClient);
|
|
242
253
|
const selectionKey = ['selection'] as const;
|
|
254
|
+
const selectionQuery = createQuery(
|
|
255
|
+
selectionKey,
|
|
256
|
+
jest.fn().mockResolvedValue({ id: 'item-2' }),
|
|
257
|
+
{
|
|
258
|
+
enabled: false,
|
|
259
|
+
}
|
|
260
|
+
);
|
|
243
261
|
const queryFn = jest.fn().mockImplementation(async ({ queryKey }) => queryKey[1].id);
|
|
244
262
|
|
|
245
263
|
queryClient.setQueryData(selectionKey, { id: 'item-1' });
|
|
@@ -250,7 +268,7 @@ describe('Query Service', () => {
|
|
|
250
268
|
{
|
|
251
269
|
enabled: false,
|
|
252
270
|
dependsOn: [
|
|
253
|
-
[
|
|
271
|
+
[selectionQuery],
|
|
254
272
|
([selectionSnapshot]) =>
|
|
255
273
|
selectionSnapshot.data?.id
|
|
256
274
|
? {
|
|
@@ -286,6 +286,11 @@ describe('Tracked Query Invalidation', () => {
|
|
|
286
286
|
const manager = setupQueryManager(queryClient);
|
|
287
287
|
const invalidateQueriesSpy = jest.spyOn(queryClient, 'invalidateQueries');
|
|
288
288
|
const selectionKey = ['selection'] as const;
|
|
289
|
+
const selectionQuery = manager.createUntrackedQuery(
|
|
290
|
+
selectionKey,
|
|
291
|
+
jest.fn().mockResolvedValue({ applicationId: 'app-1' }),
|
|
292
|
+
{ enabled: false }
|
|
293
|
+
);
|
|
289
294
|
|
|
290
295
|
queryClient.setQueryData(selectionKey, { applicationId: 'app-1' });
|
|
291
296
|
|
|
@@ -295,7 +300,7 @@ describe('Tracked Query Invalidation', () => {
|
|
|
295
300
|
{
|
|
296
301
|
enabled: false,
|
|
297
302
|
dependsOn: [
|
|
298
|
-
[
|
|
303
|
+
[selectionQuery],
|
|
299
304
|
([selectionSnapshot]) =>
|
|
300
305
|
selectionSnapshot.data?.applicationId
|
|
301
306
|
? {
|
|
@@ -337,6 +342,14 @@ describe('Tracked Query Invalidation', () => {
|
|
|
337
342
|
const manager = setupQueryManager(queryClient);
|
|
338
343
|
const invalidateQueriesSpy = jest.spyOn(queryClient, 'invalidateQueries');
|
|
339
344
|
const selectionKey = ['selection'] as const;
|
|
345
|
+
const selectionQuery = manager.createUntrackedQuery(
|
|
346
|
+
selectionKey,
|
|
347
|
+
jest
|
|
348
|
+
.fn()
|
|
349
|
+
.mockResolvedValueOnce({ applicationId: 'app-1' })
|
|
350
|
+
.mockResolvedValueOnce({ applicationId: 'app-2' }),
|
|
351
|
+
{ enabled: false }
|
|
352
|
+
);
|
|
340
353
|
const initialDerivedKey = [
|
|
341
354
|
'product',
|
|
342
355
|
{ deps: { applicationId: 'app-1' }, view: { page: 1 } },
|
|
@@ -354,7 +367,7 @@ describe('Tracked Query Invalidation', () => {
|
|
|
354
367
|
{
|
|
355
368
|
enabled: false,
|
|
356
369
|
dependsOn: [
|
|
357
|
-
[
|
|
370
|
+
[selectionQuery],
|
|
358
371
|
([selectionSnapshot]) =>
|
|
359
372
|
selectionSnapshot.data?.applicationId
|
|
360
373
|
? {
|
package/src/query.ts
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
type QueryKey,
|
|
14
14
|
// Import QueryObserver to monitor and manage individual queries.
|
|
15
15
|
QueryObserver,
|
|
16
|
-
QueriesObserver,
|
|
17
16
|
type QueryOptions,
|
|
18
17
|
// Import configuration options for the query observer.
|
|
19
18
|
type QueryObserverOptions,
|
|
@@ -109,7 +108,7 @@ export type QueryDependencyTuple<
|
|
|
109
108
|
TSources extends readonly unknown[],
|
|
110
109
|
TQueryKey extends QueryKey = QueryKey,
|
|
111
110
|
> = readonly [
|
|
112
|
-
|
|
111
|
+
sources: { readonly [K in keyof TSources]: QueryService<TSources[K], Error> },
|
|
113
112
|
deriveOptions: (
|
|
114
113
|
sourceSnapshots: { readonly [K in keyof TSources]: QueryServiceSnapshot<TSources[K], Error> }
|
|
115
114
|
) => QueryDependencyDerivedOptions<TQueryKey>,
|
|
@@ -221,7 +220,7 @@ export function setupQuery(queryClient: QueryClient): CreateUntrackedQuery {
|
|
|
221
220
|
return service.service;
|
|
222
221
|
}
|
|
223
222
|
|
|
224
|
-
return bindQueryDependencies(
|
|
223
|
+
return bindQueryDependencies(service, queryKey, dependsOn);
|
|
225
224
|
};
|
|
226
225
|
}
|
|
227
226
|
|
|
@@ -281,7 +280,6 @@ export function setupTrackedQuery(
|
|
|
281
280
|
|
|
282
281
|
const dependencyController = dependsOn
|
|
283
282
|
? createDependencyController(
|
|
284
|
-
queryClient,
|
|
285
283
|
queryKey,
|
|
286
284
|
applyTrackedDerivedState,
|
|
287
285
|
dependsOn
|
|
@@ -307,7 +305,7 @@ export function setupTrackedQuery(
|
|
|
307
305
|
return {
|
|
308
306
|
...service.service,
|
|
309
307
|
refetch: async (refetchOptions) => {
|
|
310
|
-
dependencyController?.
|
|
308
|
+
await dependencyController?.evaluateForRefetch();
|
|
311
309
|
// Refetch is one of the two explicit reactivation paths agreed on in the design.
|
|
312
310
|
ensureRegistered();
|
|
313
311
|
return service.service.refetch(refetchOptions);
|
|
@@ -435,7 +433,6 @@ function bindQueryDependencies<
|
|
|
435
433
|
TQueryData = TQueryFnData,
|
|
436
434
|
TQueryKey extends QueryKey = QueryKey,
|
|
437
435
|
>(
|
|
438
|
-
queryClient: QueryClient,
|
|
439
436
|
queryService: ReturnType<
|
|
440
437
|
typeof createQueryService<TQueryFnData, TError, TData, TQueryData, TQueryKey>
|
|
441
438
|
>,
|
|
@@ -443,7 +440,6 @@ function bindQueryDependencies<
|
|
|
443
440
|
dependsOn: QueryDependencyTuple<TSources, TQueryKey>
|
|
444
441
|
): QueryService<TData, TError> {
|
|
445
442
|
const dependencyController = createDependencyController(
|
|
446
|
-
queryClient,
|
|
447
443
|
queryKey,
|
|
448
444
|
queryService.setDerivedState,
|
|
449
445
|
dependsOn
|
|
@@ -453,7 +449,7 @@ function bindQueryDependencies<
|
|
|
453
449
|
return {
|
|
454
450
|
...queryService.service,
|
|
455
451
|
refetch: async (refetchOptions) => {
|
|
456
|
-
dependencyController.
|
|
452
|
+
await dependencyController.evaluateForRefetch();
|
|
457
453
|
return queryService.service.refetch(refetchOptions);
|
|
458
454
|
},
|
|
459
455
|
subscribe: (listener) => {
|
|
@@ -484,19 +480,17 @@ function createDependencyController<
|
|
|
484
480
|
TQueryData = TQueryFnData,
|
|
485
481
|
TQueryKey extends QueryKey = QueryKey,
|
|
486
482
|
>(
|
|
487
|
-
queryClient: QueryClient,
|
|
488
483
|
baseQueryKey: TQueryKey,
|
|
489
484
|
setDerivedState: (derivedOptions: QueryDependencyDerivedOptions<TQueryKey>) => void,
|
|
490
485
|
dependsOn: QueryDependencyTuple<TSources, TQueryKey>
|
|
491
486
|
) {
|
|
492
|
-
const [
|
|
493
|
-
let
|
|
494
|
-
let
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
) as Parameters<typeof deriveOptions>[0];
|
|
487
|
+
const [sources, deriveOptions] = dependsOn;
|
|
488
|
+
let isActive = false;
|
|
489
|
+
let scheduledEvaluation = false;
|
|
490
|
+
let sourceUnsubscribers: Array<() => void> = [];
|
|
491
|
+
|
|
492
|
+
const evaluateBinding = () => {
|
|
493
|
+
const snapshots = sources.map((source) => source.getSnapshot()) as Parameters<typeof deriveOptions>[0];
|
|
500
494
|
const derivedOptions = deriveOptions(snapshots);
|
|
501
495
|
|
|
502
496
|
setDerivedState({
|
|
@@ -505,39 +499,58 @@ function createDependencyController<
|
|
|
505
499
|
});
|
|
506
500
|
};
|
|
507
501
|
|
|
508
|
-
const
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
)
|
|
502
|
+
const scheduleEvaluate = () => {
|
|
503
|
+
if (scheduledEvaluation) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
scheduledEvaluation = true;
|
|
508
|
+
|
|
509
|
+
queueMicrotask(() => {
|
|
510
|
+
scheduledEvaluation = false;
|
|
511
|
+
|
|
512
|
+
if (!isActive) {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
evaluateBinding();
|
|
517
|
+
});
|
|
518
|
+
};
|
|
516
519
|
|
|
517
520
|
return {
|
|
518
521
|
activate: () => {
|
|
519
|
-
if (
|
|
522
|
+
if (isActive) {
|
|
520
523
|
return;
|
|
521
524
|
}
|
|
522
525
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
+
isActive = true;
|
|
527
|
+
sourceUnsubscribers = sources.map((source) =>
|
|
528
|
+
source.subscribe(() => {
|
|
529
|
+
scheduleEvaluate();
|
|
530
|
+
})
|
|
531
|
+
);
|
|
532
|
+
evaluateBinding();
|
|
526
533
|
},
|
|
527
534
|
deactivate: () => {
|
|
528
|
-
|
|
529
|
-
unsubscribe
|
|
530
|
-
|
|
535
|
+
isActive = false;
|
|
536
|
+
sourceUnsubscribers.forEach((unsubscribe) => {
|
|
537
|
+
unsubscribe();
|
|
538
|
+
});
|
|
539
|
+
sourceUnsubscribers = [];
|
|
531
540
|
},
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
541
|
+
evaluateForRefetch: async () => {
|
|
542
|
+
await Promise.all(
|
|
543
|
+
sources.map(async (source) => {
|
|
544
|
+
await source.refetch();
|
|
545
|
+
})
|
|
546
|
+
);
|
|
547
|
+
|
|
548
|
+
if (isActive) {
|
|
549
|
+
scheduleEvaluate();
|
|
535
550
|
return;
|
|
536
551
|
}
|
|
537
552
|
|
|
538
|
-
|
|
539
|
-
evaluateBinding(transientObserver.getCurrentResult());
|
|
540
|
-
transientObserver.destroy();
|
|
553
|
+
evaluateBinding();
|
|
541
554
|
},
|
|
542
555
|
};
|
|
543
556
|
}
|