@veams/status-quo-query 0.8.0 → 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 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 keys to observe
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 cache immediately, and stops after the last unsubscribe.
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 userKey = ['user', 42] as const;
420
- const configKey = ['config', 'global'] as 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
- [userKey, configKey],
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 selectionKey = ['selection'] as 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
- [selectionKey],
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 keys through TanStack `QueriesObserver` and lets the downstream query derive only `queryKey` and `enabled`. The public `QueryService` API does not change when this option is used.
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
- sourceKeys: {
46
- readonly [K in keyof TSources]: QueryKey;
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>;
@@ -53,7 +53,7 @@ export type QueryDependencyTuple<TSources extends readonly unknown[], TQueryKey
53
53
  * Function signature for the untracked query factory.
54
54
  */
55
55
  export interface CreateUntrackedQuery {
56
- <TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(queryKey: TQueryKey, queryFn: QueryFunction<TQueryFnData, TQueryKey>, options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>): QueryService<TData, TError>;
56
+ <TSources extends readonly unknown[] = [], TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(queryKey: TQueryKey, queryFn: QueryFunction<TQueryFnData, TQueryKey>, options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey, TSources>): QueryService<TData, TError>;
57
57
  }
58
58
  /**
59
59
  * Function signature for the default query factory that derives dependencies from the final
@@ -63,13 +63,13 @@ export interface CreateUntrackedQuery {
63
63
  * The only extra behavior is invisible: dependency registration and on-demand re-registration.
64
64
  */
65
65
  export interface CreateQuery {
66
- <TDeps extends TrackedDependencyRecord, TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends TrackedQueryKey<TDeps> = TrackedQueryKey<TDeps>>(queryKey: TQueryKey, queryFn: QueryFunction<TQueryFnData, TQueryKey>, options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>): QueryService<TData, TError>;
66
+ <TDeps extends TrackedDependencyRecord, TSources extends readonly unknown[] = [], TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends TrackedQueryKey<TDeps> = TrackedQueryKey<TDeps>>(queryKey: TQueryKey, queryFn: QueryFunction<TQueryFnData, TQueryKey>, options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey, TSources>): QueryService<TData, TError>;
67
67
  }
68
68
  /**
69
69
  * Configuration options for creating a query service, excluding function and key.
70
70
  */
71
- export type QueryServiceOptions<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> = Omit<QueryObserverOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>, 'queryFn' | 'queryKey'> & {
72
- dependsOn?: QueryDependencyTuple<any[], TQueryKey>;
71
+ export type QueryServiceOptions<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TSources extends readonly unknown[] = []> = Omit<QueryObserverOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>, 'queryFn' | 'queryKey'> & {
72
+ dependsOn?: QueryDependencyTuple<TSources, TQueryKey>;
73
73
  };
74
74
  /**
75
75
  * Extracts and maps status and fetchStatus to our QueryMetaState interface.
package/dist/query.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  // Import QueryObserver to monitor and manage individual queries.
3
- QueryObserver, QueriesObserver, } from '@tanstack/query-core';
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(queryClient, service, queryKey, dependsOn);
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(queryClient, queryKey, applyTrackedDerivedState, dependsOn)
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?.evaluateOnce();
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(queryClient, queryService, queryKey, dependsOn) {
162
- const dependencyController = createDependencyController(queryClient, queryKey, queryService.setDerivedState, dependsOn);
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.evaluateOnce();
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(queryClient, baseQueryKey, setDerivedState, dependsOn) {
187
- const [sourceKeys, deriveOptions] = dependsOn;
188
- let queriesObserver;
189
- let unsubscribe;
190
- const evaluateBinding = (results) => {
191
- const snapshots = results.map((result) => toQueryServiceSnapshot(result));
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 createObserver = () => new QueriesObserver(queryClient, sourceKeys.map((sourceKey) => ({
199
- enabled: false,
200
- queryKey: sourceKey,
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 (queriesObserver) {
214
+ if (isActive) {
205
215
  return;
206
216
  }
207
- queriesObserver = createObserver();
208
- evaluateBinding(queriesObserver.getCurrentResult());
209
- unsubscribe = queriesObserver.subscribe(evaluateBinding);
217
+ isActive = true;
218
+ sourceUnsubscribers = sources.map((source) => source.subscribe(() => {
219
+ scheduleEvaluate();
220
+ }));
221
+ evaluateBinding();
210
222
  },
211
223
  deactivate: () => {
212
- unsubscribe?.();
213
- unsubscribe = undefined;
214
- queriesObserver = undefined;
224
+ isActive = false;
225
+ sourceUnsubscribers.forEach((unsubscribe) => {
226
+ unsubscribe();
227
+ });
228
+ sourceUnsubscribers = [];
215
229
  },
216
- evaluateOnce: () => {
217
- if (queriesObserver) {
218
- evaluateBinding(queriesObserver.getCurrentResult());
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
- const transientObserver = createObserver();
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,EACb,eAAe,GAUhB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAIL,0BAA0B,GAC3B,MAAM,eAAe,CAAC;AA+IvB;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAA6E;IAE7E,6DAA6D;IAC7D,OAAO;QACL,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,MAAM,EAAE,QAAQ,CAAC,MAAM;KACxB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAqB;IAClD,mEAAmE;IACnE,OAAO,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,UAAU,CAAC;AACxE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,WAAwB;IACjD,8EAA8E;IAC9E,OAAO,SAAS,WAAW,CAOzB,QAAmB,EACnB,OAA+C,EAC/C,OAAiF;QAEjF,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QACxE,MAAM,OAAO,GAAG,kBAAkB,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;QAEnF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,OAAO,CAAC,OAAO,CAAC;QACzB,CAAC;QAED,OAAO,qBAAqB,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC1E,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,WAAwB,EACxB,gBAAkC;IAElC,OAAO,SAAS,WAAW,CAQzB,QAAmB,EACnB,OAA+C,EAC/C,OAAiF;QAEjF,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QACxE,yEAAyE;QACzE,MAAM,OAAO,GAAG,kBAAkB,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;QACnF,+EAA+E;QAC/E,IAAI,eAAe,GAAG,CAAC,CAAC;QAExB,uFAAuF;QACvF,gBAAgB,CAAC,QAAQ,CACvB,OAAO,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC,SAAS,EAC5C,0BAA0B,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CACzD,CAAC;QAEF,MAAM,wBAAwB,GAAG,CAAC,cAAwD,EAAE,EAAE;YAC5F,MAAM,iBAAiB,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC,SAAS,CAAC;YAEvE,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;YAExC,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC,SAAS,CAAC;YAEnE,IAAI,aAAa,KAAK,iBAAiB,EAAE,CAAC;gBACxC,OAAO;YACT,CAAC;YAED,gBAAgB,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;YAC/C,gBAAgB,CAAC,QAAQ,CAAC,aAAa,EAAE,0BAA0B,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC;QACrG,CAAC,CAAC;QAEF,MAAM,oBAAoB,GAAG,SAAS;YACpC,CAAC,CAAC,0BAA0B,CACxB,WAAW,EACX,QAAQ,EACR,wBAAwB,EACxB,SAAS,CACV;YACH,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,gBAAgB,GAAG,GAAG,EAAE;YAC5B,0FAA0F;YAC1F,oFAAoF;YACpF,MAAM,SAAS,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC,KAAK,CACjD,WAAW,EACX,OAAO,CAAC,yBAAyB,EAAE,CACpC,CAAC;YACF,MAAM,gBAAgB,GAAG,0BAA0B,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAElF,sFAAsF;YACtF,4FAA4F;YAC5F,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC/C,gBAAgB,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;YACnE,CAAC;QACH,CAAC,CAAC;QAEF,OAAO;YACL,GAAG,OAAO,CAAC,OAAO;YAClB,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;gBAChC,oBAAoB,EAAE,YAAY,EAAE,CAAC;gBACrC,iFAAiF;gBACjF,gBAAgB,EAAE,CAAC;gBACnB,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YACjD,CAAC;YACD,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE;gBACtB,sFAAsF;gBACtF,+EAA+E;gBAC/E,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;oBAC1B,oBAAoB,EAAE,QAAQ,EAAE,CAAC;oBACjC,gBAAgB,EAAE,CAAC;gBACrB,CAAC;gBAED,eAAe,IAAI,CAAC,CAAC;gBAErB,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;gBAExD,OAAO,GAAG,EAAE;oBACV,qFAAqF;oBACrF,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,eAAe,GAAG,CAAC,CAAC,CAAC;oBACnD,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;wBAC1B,oBAAoB,EAAE,UAAU,EAAE,CAAC;oBACrC,CAAC;oBACD,WAAW,EAAE,CAAC;gBAChB,CAAC,CAAC;YACJ,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAC7B,MAA0C;IAE1C,uEAAuE;IACvE,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAOzB,WAAwB,EACxB,QAAmB,EACnB,OAA+C,EAC/C,OAAwF;IAWxF,MAAM,YAAY,GAAG,QAAQ,CAAC;IAC9B,MAAM,WAAW,GAAG,OAAO,CAAC;IAC5B,IAAI,gBAAgB,GAAG,YAAY,CAAC;IACpC,IAAI,eAAe,GAAG,WAAW,CAAC;IAElC,MAAM,QAAQ,GAAG,IAAI,aAAa,CAChC,WAAW,EACX,cAAc,CAAC,gBAAgB,EAAE,OAAO,EAAE,eAAe,CAAC,CAC3D,CAAC;IAEF,MAAM,eAAe,GAAG,CAAC,cAAwD,EAAE,EAAE;QACnF,gBAAgB,GAAG,cAAc,CAAC,QAAQ,IAAI,YAAY,CAAC;QAC3D,eAAe,GAAG;YAChB,GAAG,WAAW;YACd,GAAG,CAAC,cAAc,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,CAAC;SACrF,CAAC;QACF,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,gBAAgB,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC;IAClF,CAAC,CAAC;IAEF,MAAM,yBAAyB,GAAG,GAAG,EAAE,CAAC,cAAc,CAAC,gBAAgB,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC;IAEnG,OAAO;QACL,QAAQ;QACR,yBAAyB;QACzB,kBAAkB,EAAE,GAAG,EAAE,CAAC,gBAAgB;QAC1C,eAAe;QACf,OAAO,EAAE;YACP,WAAW,EAAE,GAAG,EAAE,CAAC,sBAAsB,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;YACtE,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE,CACtB,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC5B,QAAQ,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3C,CAAC,CAAC;YACJ,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,CAChC,sBAAsB,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAChE,UAAU,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAChC,WAAW,CAAC,iBAAiB,CAC3B;gBACE,KAAK,EAAE,IAAI;gBACX,QAAQ,EAAE,gBAAgB;gBAC1B,GAAG,CAAC,iBAAiB,EAAE,WAAW,KAAK,SAAS;oBAC9C,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,EAAE,WAAW,EAAE,iBAAiB,CAAC,WAAW,EAAE,CAAC;aACpD,EACD,mBAAmB,CAAC,iBAAiB,CAAC,CACvC;YACH,gBAAgB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,gBAAgB,EAAE;SACpD;KACF,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAO5B,WAAwB,EACxB,YAEC,EACD,QAAmB,EACnB,SAAiD;IAEjD,MAAM,oBAAoB,GAAG,0BAA0B,CACrD,WAAW,EACX,QAAQ,EACR,YAAY,CAAC,eAAe,EAC5B,SAAS,CACV,CAAC;IACF,IAAI,eAAe,GAAG,CAAC,CAAC;IAExB,OAAO;QACL,GAAG,YAAY,CAAC,OAAO;QACvB,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;YAChC,oBAAoB,CAAC,YAAY,EAAE,CAAC;YACpC,OAAO,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACtD,CAAC;QACD,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE;YACtB,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;gBAC1B,oBAAoB,CAAC,QAAQ,EAAE,CAAC;YAClC,CAAC;YAED,eAAe,IAAI,CAAC,CAAC;YAErB,MAAM,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAE7D,OAAO,GAAG,EAAE;gBACV,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,eAAe,GAAG,CAAC,CAAC,CAAC;gBACnD,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;oBAC1B,oBAAoB,CAAC,UAAU,EAAE,CAAC;gBACpC,CAAC;gBACD,WAAW,EAAE,CAAC;YAChB,CAAC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CAOjC,WAAwB,EACxB,YAAuB,EACvB,eAAmF,EACnF,SAAiD;IAEjD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,SAAS,CAAC;IAC9C,IAAI,eAA4C,CAAC;IACjD,IAAI,WAAqC,CAAC;IAE1C,MAAM,eAAe,GAAG,CAAC,OAA8B,EAAE,EAAE;QACzD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACvC,sBAAsB,CAAC,MAAM,CAAC,CACQ,CAAC;QACzC,MAAM,cAAc,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;QAEhD,eAAe,CAAC;YACd,QAAQ,EAAE,cAAc,CAAC,QAAQ,IAAI,YAAY;YACjD,GAAG,CAAC,cAAc,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,CAAC;SACrF,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,GAAG,EAAE,CAC1B,IAAI,eAAe,CACjB,WAAW,EACX,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC7B,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,SAAS;KACpB,CAAC,CAAC,CACJ,CAAC;IAEJ,OAAO;QACL,QAAQ,EAAE,GAAG,EAAE;YACb,IAAI,eAAe,EAAE,CAAC;gBACpB,OAAO;YACT,CAAC;YAED,eAAe,GAAG,cAAc,EAAE,CAAC;YACnC,eAAe,CAAC,eAAe,CAAC,gBAAgB,EAAE,CAAC,CAAC;YACpD,WAAW,GAAG,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC3D,CAAC;QACD,UAAU,EAAE,GAAG,EAAE;YACf,WAAW,EAAE,EAAE,CAAC;YAChB,WAAW,GAAG,SAAS,CAAC;YACxB,eAAe,GAAG,SAAS,CAAC;QAC9B,CAAC;QACD,YAAY,EAAE,GAAG,EAAE;YACjB,IAAI,eAAe,EAAE,CAAC;gBACpB,eAAe,CAAC,eAAe,CAAC,gBAAgB,EAAE,CAAC,CAAC;gBACpD,OAAO;YACT,CAAC;YAED,MAAM,iBAAiB,GAAG,cAAc,EAAE,CAAC;YAC3C,eAAe,CAAC,iBAAiB,CAAC,gBAAgB,EAAE,CAAC,CAAC;YACtD,iBAAiB,CAAC,OAAO,EAAE,CAAC;QAC9B,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAO/B,OAAiF;IAKjF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO;YACL,SAAS,EAAE,SAAS;YACpB,cAAc,EAAE,SAAS;SAC1B,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,CAAC;IAEjD,OAAO;QACL,SAAS;QACT,cAAc;KACf,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAOrB,QAAmB,EACnB,OAA+C,EAC/C,OAAwF;IAGxF,4FAA4F;IAC5F,8DAA8D;IAC9D,OAAO;QACL,GAAG,OAAO;QACV,OAAO;QACP,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,OAAgC;IAC3D,gDAAgD;IAChD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,6EAA6E;IAC7E,MAAM,iBAAiB,GAAsB;QAC3C,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;QACxF,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC;KACtF,CAAC;IAEF,sEAAsE;IACtE,OAAO,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;AACnF,CAAC"}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veams/status-quo-query",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "TanStack Query service layer for the VEAMS StatusQuo ecosystem.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -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
- [userKey, configKey],
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 warm upstream cache data when dependsOn is evaluated on first refetch', async () => {
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
- [selectionKey],
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 firstKey = ['source', 'first'] as const;
163
- const secondKey = ['source', 'second'] as const;
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
- [firstKey, secondKey],
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
- [selectionKey],
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
- [selectionKey],
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
- [selectionKey],
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
- [selectionKey],
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
- sourceKeys: { readonly [K in keyof TSources]: QueryKey },
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>,
@@ -120,6 +119,7 @@ export type QueryDependencyTuple<
120
119
  */
121
120
  export interface CreateUntrackedQuery {
122
121
  <
122
+ TSources extends readonly unknown[] = [],
123
123
  TQueryFnData = unknown,
124
124
  TError = Error,
125
125
  TData = TQueryFnData,
@@ -131,7 +131,7 @@ export interface CreateUntrackedQuery {
131
131
  // The asynchronous function that performs the data fetch.
132
132
  queryFn: QueryFunction<TQueryFnData, TQueryKey>,
133
133
  // Optional configuration for behavior like staleness, retry, and refetching.
134
- options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
134
+ options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey, TSources>
135
135
  ): QueryService<TData, TError>;
136
136
  }
137
137
 
@@ -145,6 +145,7 @@ export interface CreateUntrackedQuery {
145
145
  export interface CreateQuery {
146
146
  <
147
147
  TDeps extends TrackedDependencyRecord,
148
+ TSources extends readonly unknown[] = [],
148
149
  TQueryFnData = unknown,
149
150
  TError = Error,
150
151
  TData = TQueryFnData,
@@ -153,7 +154,7 @@ export interface CreateQuery {
153
154
  >(
154
155
  queryKey: TQueryKey,
155
156
  queryFn: QueryFunction<TQueryFnData, TQueryKey>,
156
- options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
157
+ options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey, TSources>
157
158
  ): QueryService<TData, TError>;
158
159
  }
159
160
 
@@ -166,11 +167,12 @@ export type QueryServiceOptions<
166
167
  TData = TQueryFnData,
167
168
  TQueryData = TQueryFnData,
168
169
  TQueryKey extends QueryKey = QueryKey,
170
+ TSources extends readonly unknown[] = [],
169
171
  > = Omit<
170
172
  QueryObserverOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>,
171
173
  'queryFn' | 'queryKey'
172
174
  > & {
173
- dependsOn?: QueryDependencyTuple<any[], TQueryKey>;
175
+ dependsOn?: QueryDependencyTuple<TSources, TQueryKey>;
174
176
  };
175
177
 
176
178
  /**
@@ -200,6 +202,7 @@ export function isQueryLoading(query: QueryMetaState): boolean {
200
202
  export function setupQuery(queryClient: QueryClient): CreateUntrackedQuery {
201
203
  // Returns the actual factory function for creating individual query services.
202
204
  return function createQuery<
205
+ TSources extends readonly unknown[] = [],
203
206
  TQueryFnData = unknown,
204
207
  TError = Error,
205
208
  TData = TQueryFnData,
@@ -208,7 +211,7 @@ export function setupQuery(queryClient: QueryClient): CreateUntrackedQuery {
208
211
  >(
209
212
  queryKey: TQueryKey,
210
213
  queryFn: QueryFunction<TQueryFnData, TQueryKey>,
211
- options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
214
+ options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey, TSources>
212
215
  ): QueryService<TData, TError> {
213
216
  const { dependsOn, runtimeOptions } = splitQueryServiceOptions(options);
214
217
  const service = createQueryService(queryClient, queryKey, queryFn, runtimeOptions);
@@ -217,7 +220,7 @@ export function setupQuery(queryClient: QueryClient): CreateUntrackedQuery {
217
220
  return service.service;
218
221
  }
219
222
 
220
- return bindQueryDependencies(queryClient, service, queryKey, dependsOn);
223
+ return bindQueryDependencies(service, queryKey, dependsOn);
221
224
  };
222
225
  }
223
226
 
@@ -237,6 +240,7 @@ export function setupTrackedQuery(
237
240
  ): CreateQuery {
238
241
  return function createQuery<
239
242
  TDeps extends TrackedDependencyRecord,
243
+ TSources extends readonly unknown[] = [],
240
244
  TQueryFnData = unknown,
241
245
  TError = Error,
242
246
  TData = TQueryFnData,
@@ -245,7 +249,7 @@ export function setupTrackedQuery(
245
249
  >(
246
250
  queryKey: TQueryKey,
247
251
  queryFn: QueryFunction<TQueryFnData, TQueryKey>,
248
- options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
252
+ options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey, TSources>
249
253
  ): QueryService<TData, TError> {
250
254
  const { dependsOn, runtimeOptions } = splitQueryServiceOptions(options);
251
255
  // Reuse the same core query service implementation as the untracked API.
@@ -276,7 +280,6 @@ export function setupTrackedQuery(
276
280
 
277
281
  const dependencyController = dependsOn
278
282
  ? createDependencyController(
279
- queryClient,
280
283
  queryKey,
281
284
  applyTrackedDerivedState,
282
285
  dependsOn
@@ -302,7 +305,7 @@ export function setupTrackedQuery(
302
305
  return {
303
306
  ...service.service,
304
307
  refetch: async (refetchOptions) => {
305
- dependencyController?.evaluateOnce();
308
+ await dependencyController?.evaluateForRefetch();
306
309
  // Refetch is one of the two explicit reactivation paths agreed on in the design.
307
310
  ensureRegistered();
308
311
  return service.service.refetch(refetchOptions);
@@ -423,21 +426,20 @@ function createQueryService<
423
426
  }
424
427
 
425
428
  function bindQueryDependencies<
429
+ TSources extends readonly unknown[] = [],
426
430
  TQueryFnData = unknown,
427
431
  TError = Error,
428
432
  TData = TQueryFnData,
429
433
  TQueryData = TQueryFnData,
430
434
  TQueryKey extends QueryKey = QueryKey,
431
435
  >(
432
- queryClient: QueryClient,
433
436
  queryService: ReturnType<
434
437
  typeof createQueryService<TQueryFnData, TError, TData, TQueryData, TQueryKey>
435
438
  >,
436
439
  queryKey: TQueryKey,
437
- dependsOn: QueryDependencyTuple<any[], TQueryKey>
440
+ dependsOn: QueryDependencyTuple<TSources, TQueryKey>
438
441
  ): QueryService<TData, TError> {
439
442
  const dependencyController = createDependencyController(
440
- queryClient,
441
443
  queryKey,
442
444
  queryService.setDerivedState,
443
445
  dependsOn
@@ -447,7 +449,7 @@ function bindQueryDependencies<
447
449
  return {
448
450
  ...queryService.service,
449
451
  refetch: async (refetchOptions) => {
450
- dependencyController.evaluateOnce();
452
+ await dependencyController.evaluateForRefetch();
451
453
  return queryService.service.refetch(refetchOptions);
452
454
  },
453
455
  subscribe: (listener) => {
@@ -471,25 +473,24 @@ function bindQueryDependencies<
471
473
  }
472
474
 
473
475
  function createDependencyController<
476
+ TSources extends readonly unknown[] = [],
474
477
  TQueryFnData = unknown,
475
478
  TError = Error,
476
479
  TData = TQueryFnData,
477
480
  TQueryData = TQueryFnData,
478
481
  TQueryKey extends QueryKey = QueryKey,
479
482
  >(
480
- queryClient: QueryClient,
481
483
  baseQueryKey: TQueryKey,
482
484
  setDerivedState: (derivedOptions: QueryDependencyDerivedOptions<TQueryKey>) => void,
483
- dependsOn: QueryDependencyTuple<any[], TQueryKey>
485
+ dependsOn: QueryDependencyTuple<TSources, TQueryKey>
484
486
  ) {
485
- const [sourceKeys, deriveOptions] = dependsOn;
486
- let queriesObserver: QueriesObserver | undefined;
487
- let unsubscribe: (() => void) | undefined;
488
-
489
- const evaluateBinding = (results: QueryObserverResult[]) => {
490
- const snapshots = results.map((result) =>
491
- toQueryServiceSnapshot(result)
492
- ) 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];
493
494
  const derivedOptions = deriveOptions(snapshots);
494
495
 
495
496
  setDerivedState({
@@ -498,39 +499,58 @@ function createDependencyController<
498
499
  });
499
500
  };
500
501
 
501
- const createObserver = () =>
502
- new QueriesObserver(
503
- queryClient,
504
- sourceKeys.map((sourceKey) => ({
505
- enabled: false,
506
- queryKey: sourceKey,
507
- }))
508
- );
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
+ };
509
519
 
510
520
  return {
511
521
  activate: () => {
512
- if (queriesObserver) {
522
+ if (isActive) {
513
523
  return;
514
524
  }
515
525
 
516
- queriesObserver = createObserver();
517
- evaluateBinding(queriesObserver.getCurrentResult());
518
- unsubscribe = queriesObserver.subscribe(evaluateBinding);
526
+ isActive = true;
527
+ sourceUnsubscribers = sources.map((source) =>
528
+ source.subscribe(() => {
529
+ scheduleEvaluate();
530
+ })
531
+ );
532
+ evaluateBinding();
519
533
  },
520
534
  deactivate: () => {
521
- unsubscribe?.();
522
- unsubscribe = undefined;
523
- queriesObserver = undefined;
535
+ isActive = false;
536
+ sourceUnsubscribers.forEach((unsubscribe) => {
537
+ unsubscribe();
538
+ });
539
+ sourceUnsubscribers = [];
524
540
  },
525
- evaluateOnce: () => {
526
- if (queriesObserver) {
527
- evaluateBinding(queriesObserver.getCurrentResult());
541
+ evaluateForRefetch: async () => {
542
+ await Promise.all(
543
+ sources.map(async (source) => {
544
+ await source.refetch();
545
+ })
546
+ );
547
+
548
+ if (isActive) {
549
+ scheduleEvaluate();
528
550
  return;
529
551
  }
530
552
 
531
- const transientObserver = createObserver();
532
- evaluateBinding(transientObserver.getCurrentResult());
533
- transientObserver.destroy();
553
+ evaluateBinding();
534
554
  },
535
555
  };
536
556
  }
@@ -541,10 +561,11 @@ function splitQueryServiceOptions<
541
561
  TData = TQueryFnData,
542
562
  TQueryData = TQueryFnData,
543
563
  TQueryKey extends QueryKey = QueryKey,
564
+ TSources extends readonly unknown[] = [],
544
565
  >(
545
- options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
566
+ options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey, TSources>
546
567
  ): {
547
- dependsOn?: QueryDependencyTuple<any[], TQueryKey>;
568
+ dependsOn?: QueryDependencyTuple<TSources, TQueryKey>;
548
569
  runtimeOptions: QueryServiceRuntimeOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey> | undefined;
549
570
  } {
550
571
  if (options === undefined) {