ngx-signal-query 1.3.1 → 1.3.2-dev.2

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.
@@ -318,6 +318,14 @@ class QueryCache extends Cache {
318
318
  get(key) {
319
319
  return this.getEntry(hashKey(key));
320
320
  }
321
+ /**
322
+ * Like get(), but reactive, as findAll() is: a computed or an effect that
323
+ * calls it re-runs when an entry is added or removed.
324
+ */
325
+ find(key) {
326
+ this.entries();
327
+ return this.get(key);
328
+ }
321
329
  findAll(filters = {}) {
322
330
  const { queryKey, exact } = filters;
323
331
  // Reads the reactive `entries()` so findAll() works inside computed().
@@ -514,8 +522,20 @@ const QUERY_CLIENT_CONFIG = new InjectionToken('QUERY_CLIENT_CONFIG');
514
522
  * {@link injectQueryClient}. Offers imperative cache access — reading and
515
523
  * writing data, and invalidating, cancelling, or removing queries — that
516
524
  * complements the reactive {@link injectQuery} / {@link injectMutation} APIs.
525
+ *
526
+ * Its methods aren't reactive. Called from an effect, a method doesn't make
527
+ * the effect depend on the cache, on a query's state, or on what `queryFn` or
528
+ * an updater reads: the effect re-runs only when what it reads itself
529
+ * changes. A read is a snapshot, in a template or a `computed` too; for state
530
+ * that updates, use {@link injectQuery}, {@link injectIsFetching} and
531
+ * {@link injectIsMutating}.
517
532
  */
518
533
  class QueryClient {
534
+ // Every method that reads or writes the cache runs its body untracked. A
535
+ // call made from an effect mustn't make the effect depend on what the
536
+ // method reads to do its job: the cache, a query's state, or what queryFn
537
+ // or an updater reads. Otherwise a change to any of them re-runs the effect,
538
+ // and the effect repeats the call.
519
539
  #cache = inject(QueryCache);
520
540
  #mutationCache = inject(MutationCache);
521
541
  #config = inject(QUERY_CLIENT_CONFIG, { optional: true }) ?? {};
@@ -545,7 +565,7 @@ class QueryClient {
545
565
  /**
546
566
  * Imperatively fetches and caches a query, unless fresh data already exists
547
567
  * (governed by `staleTime`). Prefer {@link injectQuery} in components; use
548
- * this for prefetching outside the reactive flow.
568
+ * this to prefetch, from an event handler or an effect.
549
569
  *
550
570
  * @param key - The query key to fetch and cache under.
551
571
  * @param queryFn - Function returning the data as an `Observable` or `Promise`.
@@ -553,24 +573,28 @@ class QueryClient {
553
573
  * `cancelRefetch`).
554
574
  */
555
575
  fetchQuery(key, queryFn, options = {}) {
556
- const defaults = this.#config.defaultOptions?.queries;
557
- const staleTime = options.staleTime ?? defaults?.staleTime ?? 0;
558
- const retry = options.retry ?? defaults?.retry ?? 3;
559
- const retryDelay = options.retryDelay ?? defaults?.retryDelay ?? defaultRetryDelay;
560
- const query = this.#cache.getOrCreate(key);
561
- if (query.shouldFetch(staleTime)) {
562
- query.fetch(queryFn, retry, retryDelay, options.cancelRefetch);
563
- }
576
+ untracked(() => {
577
+ const defaults = this.#config.defaultOptions?.queries;
578
+ const staleTime = options.staleTime ?? defaults?.staleTime ?? 0;
579
+ const retry = options.retry ?? defaults?.retry ?? 3;
580
+ const retryDelay = options.retryDelay ?? defaults?.retryDelay ?? defaultRetryDelay;
581
+ const query = this.#cache.getOrCreate(key);
582
+ if (query.shouldFetch(staleTime)) {
583
+ query.fetch(queryFn, retry, retryDelay, options.cancelRefetch);
584
+ }
585
+ });
564
586
  }
565
587
  /**
566
588
  * Reads the current cached data for a query key, or `undefined` if the query
567
- * is not cached yet.
589
+ * is not cached yet. A snapshot: it doesn't update a template, a `computed`
590
+ * or an effect when the data changes. For data that updates, use
591
+ * {@link injectQuery}.
568
592
  *
569
593
  * @param key - The query key to read.
570
594
  * @returns The cached data, or `undefined`.
571
595
  */
572
596
  getQueryData(key) {
573
- return this.#cache.get(key)?.state().data;
597
+ return untracked(() => this.#cache.get(key)?.state().data);
574
598
  }
575
599
  /**
576
600
  * Writes data into the cache for a query key, creating the entry if needed.
@@ -586,12 +610,14 @@ class QueryClient {
586
610
  * ```
587
611
  */
588
612
  setQueryData(key, updater) {
589
- const query = this.#cache.getOrCreate(key);
590
- const data = functionalUpdate(updater, query.state().data);
591
- // Matches TanStack: an updater returning undefined is a no-op.
592
- if (data === undefined)
593
- return;
594
- query.setData(data);
613
+ untracked(() => {
614
+ const query = this.#cache.getOrCreate(key);
615
+ const data = functionalUpdate(updater, query.state().data);
616
+ // Matches TanStack: an updater returning undefined is a no-op.
617
+ if (data === undefined)
618
+ return;
619
+ query.setData(data);
620
+ });
595
621
  }
596
622
  /**
597
623
  * Marks matching queries as stale and refetches the actively observed ones,
@@ -609,20 +635,20 @@ class QueryClient {
609
635
  * ```
610
636
  */
611
637
  invalidateQueries(filters) {
612
- const queries = this.#cache.findAll(filters);
613
- queries.forEach((query) => query.invalidate());
614
- // Refetch each active query once, however many observers watch it; an
615
- // inactive one refetches when next observed, as shouldFetch sees the flag.
616
- // cancelRefetch: a fetch already in flight started before the
617
- // invalidation, so it may have missed the change. untracked: queryFn runs
618
- // synchronously here, and an effect calling this mustn't start tracking
619
- // what it reads.
620
- untracked(() => queries.forEach((query) => {
621
- const options = query.activeFetchOptions();
622
- if (options) {
623
- query.fetch(options.queryFn, options.retry, options.retryDelay, true);
624
- }
625
- }));
638
+ untracked(() => {
639
+ const queries = this.#cache.findAll(filters);
640
+ queries.forEach((query) => query.invalidate());
641
+ // Refetch each active query once, however many observers watch it; an
642
+ // inactive one refetches when next observed, as shouldFetch sees the
643
+ // flag. cancelRefetch: a fetch already in flight started before the
644
+ // invalidation, so it may have missed the change.
645
+ queries.forEach((query) => {
646
+ const options = query.activeFetchOptions();
647
+ if (options) {
648
+ query.fetch(options.queryFn, options.retry, options.retryDelay, true);
649
+ }
650
+ });
651
+ });
626
652
  }
627
653
  /**
628
654
  * Cancels any in-flight fetches for matching queries.
@@ -630,36 +656,45 @@ class QueryClient {
630
656
  * @param filters - Which queries to cancel; omit to cancel all.
631
657
  */
632
658
  cancelQueries(filters) {
633
- this.#cache.findAll(filters).forEach((query) => query.cancel());
659
+ untracked(() => this.#cache.findAll(filters).forEach((query) => query.cancel()));
634
660
  }
635
661
  /**
636
- * Removes matching queries from the cache entirely, discarding their data.
662
+ * Removes matching queries from the cache entirely, discarding their data
663
+ * and cancelling their fetches. Nothing is refetched: a component still
664
+ * showing a removed key keeps what it shows until something puts the key
665
+ * back in the cache (a write, a refetch, another component, its own
666
+ * polling), then shows what the cache holds, as after a key change.
637
667
  *
638
668
  * @param filters - Which queries to remove; omit to remove all.
639
669
  */
640
670
  removeQueries(filters) {
641
- this.#cache.findAll(filters).forEach((query) => {
671
+ untracked(() => this.#cache.findAll(filters).forEach((query) => {
642
672
  query.destroy();
643
673
  this.#cache.remove(query);
644
- });
674
+ }));
645
675
  }
646
676
  /**
647
- * Returns the number of matching queries currently fetching. For a reactive
648
- * count, prefer {@link injectIsFetching}.
677
+ * Returns the number of matching queries currently fetching. A snapshot: it
678
+ * doesn't update a template, a `computed` or an effect. For a count that
679
+ * updates, use {@link injectIsFetching}.
649
680
  *
650
681
  * @param filters - Which queries to count; omit to count all.
651
682
  */
652
683
  isFetching(filters) {
653
- return this.#cache
654
- .findAll(filters)
655
- .filter((query) => query.state().isFetching).length;
684
+ return untracked(() => {
685
+ const fetching = this.#cache
686
+ .findAll(filters)
687
+ .filter((query) => query.state().isFetching);
688
+ return fetching.length;
689
+ });
656
690
  }
657
691
  /**
658
- * Returns the number of mutations currently pending. For a reactive count,
659
- * prefer {@link injectIsMutating}.
692
+ * Returns the number of mutations currently pending. A snapshot: it doesn't
693
+ * update a template, a `computed` or an effect. For a count that updates,
694
+ * use {@link injectIsMutating}.
660
695
  */
661
696
  isMutating() {
662
- return this.#mutationCache.findAll({ status: 'pending' }).length;
697
+ return untracked(() => this.#mutationCache.findAll({ status: 'pending' }).length);
663
698
  }
664
699
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.21", ngImport: i0, type: QueryClient, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
665
700
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.21", ngImport: i0, type: QueryClient });
@@ -823,22 +858,24 @@ function createQueryObserver(optionsFn, injector) {
823
858
  applyInitialData(q);
824
859
  return q;
825
860
  };
826
- // The query the key effect below last switched to; unset until it first runs.
861
+ // The query the observer last switched to, by the key effect or the follow
862
+ // effect below; unset until the key effect first runs.
827
863
  const switched = signal(undefined, ...(ngDevMode ? [{ debugName: "switched" }] : []));
828
864
  // The observed query, resolved lazily: on the first read of a result signal
829
865
  // or the first effect run, whichever comes first. Resolving it calls
830
866
  // optionsFn, which may read inputs or fields that don't exist yet while the
831
867
  // owner is being constructed. A read before the key effect's first run
832
868
  // resolves the current key on the spot, so it already sees cached data and
833
- // initialData; from then on only the key effect switches queries.
869
+ // initialData; from then on the key and follow effects switch queries.
834
870
  const query = computed(() => switched() ?? untracked(() => resolve(defaultedOptions().queryKey)), ...(ngDevMode ? [{ debugName: "query" }] : []));
835
871
  // Data of the last query that had any, fed to the placeholderData function
836
- // on key change (mirrors TanStack's lastQueryWithDefinedData). Captured
837
- // synchronously before the switch so it can't miss a just-resolved value.
872
+ // on a switch: a key change, or the key coming back after a removal
873
+ // (mirrors TanStack's lastQueryWithDefinedData). Captured synchronously
874
+ // before the switch so it can't miss a just-resolved value.
838
875
  const lastData = signal(undefined, ...(ngDevMode ? [{ debugName: "lastData" }] : []));
839
- track(() => {
840
- const key = defaultedOptions().queryKey;
841
- const q = untracked(() => resolve(key));
876
+ // Switches the observer to q, first keeping the data of the query it
877
+ // leaves for the placeholderData function.
878
+ const switchTo = (q) => {
842
879
  untracked(() => {
843
880
  const prev = switched();
844
881
  if (prev && prev !== q && prev.state().data !== undefined) {
@@ -846,6 +883,26 @@ function createQueryObserver(optionsFn, injector) {
846
883
  }
847
884
  });
848
885
  switched.set(q);
886
+ };
887
+ track(() => {
888
+ const key = defaultedOptions().queryKey;
889
+ switchTo(untracked(() => resolve(key)));
890
+ });
891
+ // The query cached under the key right now, read reactively: undefined once
892
+ // removeQueries drops it, and the new entry once something brings the key
893
+ // back.
894
+ const cached = computed(() => cache.find(defaultedOptions().queryKey), ...(ngDevMode ? [{ debugName: "cached" }] : []));
895
+ // After removeQueries the observer keeps the query the cache dropped and
896
+ // shows what it had: nothing here brings the key back, as in TanStack, where
897
+ // a removal doesn't refetch. Whatever does bring it back (a write, a refetch,
898
+ // another component, a poll), the observer follows it there as on a key
899
+ // change: resolve() seeds initialData into an entry still pending. Without
900
+ // this, it would see the new entry only once its options change.
901
+ track(() => {
902
+ const entry = cached();
903
+ if (!entry || entry === untracked(switched))
904
+ return;
905
+ switchTo(untracked(() => resolve(entry.key)));
849
906
  });
850
907
  // How this observer would fetch q right now, from the live options; null
851
908
  // while it is disabled, or once the key has moved on. Before the key effect
@@ -926,12 +983,16 @@ function createQueryObserver(optionsFn, injector) {
926
983
  const ms = interval();
927
984
  if (!ms)
928
985
  return;
929
- // Fetches q with the options as they are when it fires, which may have
930
- // changed since the effect ran.
986
+ // Fetches the key with the options as they are when it fires, which may
987
+ // have changed since the effect ran. The key's entry is q, unless
988
+ // removeQueries dropped it: then the poll puts the key back, as TanStack's
989
+ // observer does before every fetch, and the follow effect moves this
990
+ // observer there.
931
991
  const poll = () => {
932
992
  const options = fetchOptionsFor(q);
933
- if (options)
934
- q.fetch(options.queryFn, options.retry, options.retryDelay);
993
+ if (options) {
994
+ resolve(q.key).fetch(options.queryFn, options.retry, options.retryDelay);
995
+ }
935
996
  };
936
997
  onCleanup(startPolling(ms, () => q.state().updatedAt, poll));
937
998
  });
@@ -1153,8 +1214,11 @@ function injectQueries(optionsFn, options) {
1153
1214
  * to trigger `mutationFn`. The `onMutate` / `onSuccess` / `onError` /
1154
1215
  * `onSettled` lifecycle hooks make optimistic updates and cache invalidation
1155
1216
  * straightforward. Mutations do not retry by default (a retried write is not
1156
- * idempotent); opt in via `options.retry`. Bound to the current injection
1157
- * context and cancelled when that context is destroyed.
1217
+ * idempotent); opt in via `options.retry`. `mutate()` and `reset()` are safe
1218
+ * to call from an effect: neither makes the effect depend on what it reads,
1219
+ * such as the options or the previous run. Bound to the current injection
1220
+ * context. Destroying it doesn't cancel a run in flight: the write has most
1221
+ * likely reached the server, so the run finishes and fires its hooks.
1158
1222
  *
1159
1223
  * Must run in an injection context, or be given an explicit `injector`.
1160
1224
  *
@@ -1197,25 +1261,30 @@ function injectMutation(optionsFn, options) {
1197
1261
  const state = computed(() => current()?.state() ??
1198
1262
  getInitialState(), ...(ngDevMode ? [{ debugName: "state" }] : []));
1199
1263
  return {
1200
- mutate: (variables) => {
1201
- // Stop observing the previous run. It isn't cancelled — if it's still
1202
- // in flight it finishes and fires its hooks; it just no longer feeds
1203
- // the signals below.
1204
- untracked(current)?.removeObserver();
1264
+ // mutate() and reset() run untracked, as the QueryClient's methods do. A
1265
+ // call made from an effect mustn't make the effect depend on what they
1266
+ // read to do their job: the previous run's state, the options, or what
1267
+ // onMutate and mutationFn read. Otherwise a change to any of them
1268
+ // re-runs the effect, and the effect repeats the call.
1269
+ mutate: (variables) => untracked(() => {
1270
+ // Stop observing the previous run. It isn't cancelled — if it's
1271
+ // still in flight it finishes and fires its hooks; it just no longer
1272
+ // feeds the signals below.
1273
+ current()?.removeObserver();
1205
1274
  // Options are read per call, so a signal used in them stays live.
1206
1275
  const run = cache.build(optionsFn());
1207
1276
  run.addObserver();
1208
1277
  current.set(run);
1209
1278
  run.execute(variables);
1210
- },
1211
- reset: () => {
1212
- // "Forget the result", not "stop the request". A run still in flight
1213
- // keeps going and fires its hooks, so the cache stays in step with the
1214
- // server — cancelling could not un-send the write anyway, it could only
1215
- // hide the fact that it happened.
1216
- untracked(current)?.removeObserver();
1279
+ }),
1280
+ reset: () => untracked(() => {
1281
+ // "Forget the result", not "stop the request". A run still in
1282
+ // flight keeps going and fires its hooks, so the cache stays in step
1283
+ // with the server — cancelling could not un-send the write anyway,
1284
+ // it could only hide the fact that it happened.
1285
+ current()?.removeObserver();
1217
1286
  current.set(null);
1218
- },
1287
+ }),
1219
1288
  data: computed(() => state().data),
1220
1289
  error: computed(() => state().error),
1221
1290
  variables: computed(() => state().variables),
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-signal-query.mjs","sources":["../../../projects/ngx-signal-query/src/lib/core/cache.ts","../../../projects/ngx-signal-query/src/lib/core/utils.ts","../../../projects/ngx-signal-query/src/lib/core/retryer.ts","../../../projects/ngx-signal-query/src/lib/core/query.ts","../../../projects/ngx-signal-query/src/lib/core/query-cache.ts","../../../projects/ngx-signal-query/src/lib/core/mutation.ts","../../../projects/ngx-signal-query/src/lib/core/mutation-cache.ts","../../../projects/ngx-signal-query/src/lib/core/injection-tokens.ts","../../../projects/ngx-signal-query/src/lib/core/query-client.ts","../../../projects/ngx-signal-query/src/lib/features/feature.ts","../../../projects/ngx-signal-query/src/lib/core/provider.ts","../../../projects/ngx-signal-query/src/lib/core/inject-query-client.ts","../../../projects/ngx-signal-query/src/lib/core/polling.ts","../../../projects/ngx-signal-query/src/lib/core/query-observer.ts","../../../projects/ngx-signal-query/src/lib/core/inject-query.ts","../../../projects/ngx-signal-query/src/lib/core/inject-queries.ts","../../../projects/ngx-signal-query/src/lib/core/inject-mutation.ts","../../../projects/ngx-signal-query/src/lib/core/inject-is-fetching.ts","../../../projects/ngx-signal-query/src/lib/core/inject-is-mutating.ts","../../../projects/ngx-signal-query/src/lib/core/query-options.ts","../../../projects/ngx-signal-query/src/lib/core/keep-previous-data.ts","../../../projects/ngx-signal-query/src/lib/core/mutation-options.ts","../../../projects/ngx-signal-query/src/lib/features/with-default-options.ts","../../../projects/ngx-signal-query/src/public-api.ts","../../../projects/ngx-signal-query/src/ngx-signal-query.ts"],"sourcesContent":["import { signal } from '@angular/core'\n\n/** @internal */\nexport abstract class Cache<TEntry> {\n readonly #entries = signal<TEntry[]>([])\n\n // Reactive snapshot of all entries; updated on add/remove/clear so that\n // findAll() (and its computed consumers like isFetching) react to the\n // collection. Protected: only subclasses read it, never external code.\n protected readonly entries = this.#entries.asReadonly()\n\n readonly #entriesMap = new Map<string, TEntry>()\n\n getAll(): TEntry[] {\n return Array.from(this.#entriesMap.values())\n }\n\n clear(): void {\n this.#entriesMap.clear()\n this.#sync()\n }\n\n protected addEntry(key: string, entry: TEntry): TEntry {\n this.#entriesMap.set(key, entry)\n this.#sync()\n\n return entry\n }\n\n protected getEntry(key: string): TEntry | undefined {\n return this.#entriesMap.get(key)\n }\n\n protected removeEntry(key: string): boolean {\n const removed = this.#entriesMap.delete(key)\n\n if (removed) this.#sync()\n\n return removed\n }\n\n #sync(): void {\n this.#entries.set(Array.from(this.#entriesMap.values()))\n }\n}\n","import type { QueryKey, Updater } from './types'\n\n// Resolves an updater: calls it with the previous value if it's a function,\n// otherwise uses it as the value directly.\n/** @internal */\nexport function functionalUpdate<TInput, TOutput>(\n updater: Updater<TInput, TOutput>,\n input: TInput,\n): TOutput {\n return typeof updater === 'function'\n ? (updater as (input: TInput) => TOutput)(input)\n : updater\n}\n\n// True when `filter` is a (deep) prefix of `key`, e.g. ['app'] matches\n// ['app', 1]. Used to invalidate/find groups of queries by partial key.\n/** @internal */\nexport function partialMatchKey(key: QueryKey, filter: QueryKey): boolean {\n return partialDeepEqual(key, filter)\n}\n\nfunction partialDeepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (typeof a !== typeof b) return false\n\n if (a && b && typeof a === 'object' && typeof b === 'object') {\n return Object.keys(b).every((key) =>\n partialDeepEqual(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key],\n ),\n )\n }\n\n return false\n}\n\n/** @internal */\nexport function hashKey(key: QueryKey): string {\n return JSON.stringify(key, (_, value) =>\n isPlainObject(value)\n ? Object.keys(value)\n .sort()\n .reduce<Record<string, unknown>>((result, k) => {\n result[k] = value[k]\n\n return result\n }, {})\n : value,\n )\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\n/** @internal */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isPlainObject(o: any): o is Record<PropertyKey, unknown> {\n if (!hasObjectPrototype(o)) {\n return false\n }\n\n // If has no constructor\n const ctor = o.constructor\n\n if (ctor === undefined) {\n return true\n }\n\n // If has modified prototype\n const prot = ctor.prototype\n\n if (!hasObjectPrototype(prot)) {\n return false\n }\n\n // If constructor does not have an Object-specific method\n if (!Object.prototype.hasOwnProperty.call(prot, 'isPrototypeOf')) {\n return false\n }\n\n // Handles Objects created by Object.create(<arbitrary prototype>)\n if (Object.getPrototypeOf(o) !== Object.prototype) {\n return false\n }\n\n // Most likely a plain Object\n return true\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction hasObjectPrototype(o: any): boolean {\n return Object.prototype.toString.call(o) === '[object Object]'\n}\n\n// The longest delay a browser timer holds, in ms. A longer one overflows and\n// the timer fires at once.\nconst MAX_TIMEOUT = 2 ** 31 - 1\n\n// True for a delay a timer can hold. For anything else, Infinity and negative\n// numbers included, a browser runs the timer at once. TanStack's\n// isValidTimeout checks the same, without the upper bound.\n/** @internal */\nexport function isValidTimeout(value: unknown): value is number {\n return typeof value === 'number' && value >= 0 && value <= MAX_TIMEOUT\n}\n","import type { RetryDelayValue, RetryValue } from './types'\n\n// Exponential backoff capped at 30s, matching TanStack's default.\n/** @internal */\nexport function defaultRetryDelay(failureCount: number): number {\n return Math.min(1000 * 2 ** failureCount, 30000)\n}\n\n/** @internal */\nexport function shouldRetry<TError>(\n retry: RetryValue<TError>,\n failureCount: number,\n error: TError,\n): boolean {\n if (typeof retry === 'function') return retry(failureCount, error)\n if (typeof retry === 'number') return failureCount < retry\n\n return retry\n}\n\n/** @internal */\nexport function resolveRetryDelay<TError>(\n retryDelay: RetryDelayValue<TError>,\n failureCount: number,\n error: TError,\n): number {\n return typeof retryDelay === 'function'\n ? retryDelay(failureCount, error)\n : retryDelay\n}\n","import { signal } from '@angular/core'\nimport {\n defer,\n from,\n retry as retryOperator,\n take,\n throwIfEmpty,\n timer,\n type Observable,\n type Subscription,\n} from 'rxjs'\n\nimport type { QueryCache } from './query-cache'\nimport { defaultRetryDelay, resolveRetryDelay, shouldRetry } from './retryer'\nimport type {\n DefaultedQueryOptions,\n QueryKey,\n QueryState,\n RetryDelayValue,\n RetryValue,\n} from './types'\n\nconst DEFAULT_GC_TIME = 5 * 60 * 1000\n\n/**\n * An observer of a query, as the query sees it: the query asks its observers\n * how to fetch it when it refetches on their behalf (after invalidation).\n *\n * @internal\n */\nexport interface QuerySubscriber<TData, TError = Error> {\n /**\n * How this observer would fetch the query right now, read from its live\n * options; `null` while it doesn't want the query fetched: it is disabled,\n * or its key has already moved on to another query.\n */\n fetchOptions(): Pick<\n DefaultedQueryOptions<TData, TError>,\n 'queryFn' | 'retry' | 'retryDelay'\n > | null\n}\n\n/** @internal */\nexport class Query<TData, TError = Error> {\n readonly #state = signal<QueryState<TData, TError>>({\n data: undefined,\n status: 'pending',\n error: null,\n isFetching: false,\n isInvalidated: false,\n failureCount: 0,\n failureReason: null,\n updatedAt: 0,\n })\n\n // `state` must follow `#state`: a public field can't precede the private\n // field it reads during initialization (field init order).\n // eslint-disable-next-line @typescript-eslint/member-ordering\n readonly state = this.#state.asReadonly()\n\n #subscription: Subscription | null = null\n readonly #observers = new Set<QuerySubscriber<TData, TError>>()\n #gcTime = DEFAULT_GC_TIME\n #gcTimer: ReturnType<typeof setTimeout> | null = null\n readonly #cache: QueryCache\n\n constructor(\n readonly key: QueryKey,\n readonly queryHash: string,\n cache: QueryCache,\n ) {\n this.#cache = cache\n }\n\n get observerCount(): number {\n return this.#observers.size\n }\n\n setGcTime(ms: number): void {\n this.#gcTime = ms\n }\n\n addObserver(observer: QuerySubscriber<TData, TError>): void {\n this.#observers.add(observer)\n this.#clearGcTimer()\n }\n\n removeObserver(observer: QuerySubscriber<TData, TError>): void {\n // An observer this query doesn't have changes nothing: it mustn't cancel\n // the fetch or schedule gc while others still watch.\n if (!this.#observers.delete(observer)) return\n\n // No observers left: cancel any in-flight fetch (nobody is waiting for it)\n // and schedule gc to dispose the query if no observer returns.\n if (this.#observers.size === 0) {\n this.cancel()\n this.#scheduleGc()\n }\n }\n\n // How to refetch this query on its observers' behalf: the first observer\n // that wants it fetched decides, as in TanStack; null if none does.\n activeFetchOptions(): ReturnType<\n QuerySubscriber<TData, TError>['fetchOptions']\n > {\n for (const observer of this.#observers) {\n const options = observer.fetchOptions()\n\n if (options) return options\n }\n\n return null\n }\n\n fetch(\n queryFn: () => Observable<TData> | Promise<TData>,\n retry: RetryValue<TError> = 0,\n retryDelay: RetryDelayValue<TError> = defaultRetryDelay,\n cancelRefetch = false,\n ): void {\n if (this.#subscription && !this.#subscription.closed) {\n // Already in-flight: dedupe unless the caller explicitly wants a fresh\n // fetch (e.g. invalidate/refetch) — then cancel the old one and restart.\n if (!cancelRefetch) return\n this.cancel()\n }\n\n this.#state.update((state) => ({\n ...state,\n isFetching: true,\n failureCount: 0,\n failureReason: null,\n }))\n\n // defer + from: normalize Observable/Promise and re-invoke queryFn on each\n // retry (a Promise is one-shot, so retry must produce a fresh one).\n this.#subscription = defer(() => from(queryFn()))\n .pipe(\n take(1),\n retryOperator({\n delay: (error, retryCount) => {\n // retryCount (1-based) is the number of failures so far; the retry\n // predicate/delay take a 0-based attempt index (0 = first retry).\n this.#state.update((state) => ({\n ...state,\n failureCount: retryCount,\n failureReason: error as TError,\n }))\n\n const attemptIndex = retryCount - 1\n\n if (!shouldRetry(retry, attemptIndex, error as TError)) throw error\n\n return timer(\n resolveRetryDelay(retryDelay, attemptIndex, error as TError),\n )\n },\n }),\n throwIfEmpty(\n () => new Error('Query function completed without emitting a value'),\n ),\n )\n .subscribe({\n next: (data) =>\n this.#state.set({\n data,\n status: 'success',\n error: null,\n isFetching: false,\n isInvalidated: false,\n failureCount: 0,\n failureReason: null,\n updatedAt: Date.now(),\n }),\n error: (err) =>\n this.#state.update((state) => ({\n ...state,\n status: 'error',\n error: err,\n isFetching: false,\n })),\n })\n }\n\n setData(data: TData, updatedAt: number = Date.now()): void {\n this.#state.update((state) => ({\n ...state,\n data,\n status: 'success',\n error: null,\n isInvalidated: false,\n failureCount: 0,\n failureReason: null,\n updatedAt,\n }))\n\n // Keep an orphaned query (no observers) alive for another gcTime so a\n // setQueryData write isn't collected before anyone subscribes.\n if (this.#observers.size === 0) this.#scheduleGc()\n }\n\n invalidate(): void {\n this.#state.update((state) => ({ ...state, isInvalidated: true }))\n }\n\n shouldFetch(staleTime: number): boolean {\n const state = this.state()\n\n return (\n state.status !== 'success' ||\n state.isInvalidated ||\n this.#isStale(staleTime)\n )\n }\n\n cancel(): void {\n this.#subscription?.unsubscribe()\n this.#subscription = null\n\n // The fetch is no longer running; clear the in-flight flag so isFetching\n // doesn't stay stuck true after a cancellation.\n if (this.state().isFetching) {\n this.#state.update((state) => ({ ...state, isFetching: false }))\n }\n }\n\n destroy(): void {\n this.cancel()\n this.#clearGcTimer()\n }\n\n // Inclusive: data fetched exactly `staleTime` ago is already stale. This\n // matters for seeded data (initialData is stamped with the current time), so\n // the default staleTime of 0 still means \"stale at once\" → background\n // refetch, rather than depending on whether a millisecond happened to pass.\n #isStale(staleTime: number): boolean {\n return Date.now() - this.state().updatedAt >= staleTime\n }\n\n #scheduleGc(): void {\n this.#clearGcTimer()\n\n this.#gcTimer = setTimeout(() => {\n this.#gcTimer = null\n this.#cache.remove(this)\n }, this.#gcTime)\n }\n\n #clearGcTimer(): void {\n if (this.#gcTimer === null) return\n\n clearTimeout(this.#gcTimer)\n this.#gcTimer = null\n }\n}\n","import { Injectable } from '@angular/core'\n\nimport { Cache } from './cache'\nimport { hashKey, partialMatchKey } from './utils'\nimport { Query } from './query'\nimport type { QueryFilters, QueryKey } from './types'\n\n/** @internal */\n@Injectable()\nexport class QueryCache extends Cache<Query<unknown, unknown>> {\n getOrCreate<TData, TError = Error>(key: QueryKey): Query<TData, TError> {\n const queryHash = hashKey(key)\n const exist = this.getEntry(queryHash)\n\n if (exist) return exist as Query<TData, TError>\n\n return this.addEntry(queryHash, new Query(key, queryHash, this)) as Query<\n TData,\n TError\n >\n }\n\n get<TData, TError = Error>(key: QueryKey): Query<TData, TError> | undefined {\n return this.getEntry(hashKey(key)) as Query<TData, TError> | undefined\n }\n\n findAll(filters: QueryFilters = {}): Array<Query<unknown, unknown>> {\n const { queryKey, exact } = filters\n\n // Reads the reactive `entries()` so findAll() works inside computed().\n const all = this.entries()\n\n if (!queryKey) return all\n\n if (exact) {\n const queryHash = hashKey(queryKey)\n\n return all.filter((query) => query.queryHash === queryHash)\n }\n\n return all.filter((query) => partialMatchKey(query.key, queryKey))\n }\n\n // Generic: a query is invariant in TError (its observers' retry options take\n // the error as an argument), so a typed one isn't a Query<unknown, unknown>.\n remove<TData, TError>(query: Query<TData, TError>): void {\n // Guard on identity, not just the hash: a stale instance (already removed\n // and recreated under the same key) must not evict the current query.\n if (this.getEntry(query.queryHash) === query) {\n this.removeEntry(query.queryHash)\n }\n }\n\n override clear(): void {\n this.getAll().forEach((query) => query.destroy())\n super.clear()\n }\n}\n","import { type Signal, signal } from '@angular/core'\nimport {\n defer,\n from,\n retry as retryOperator,\n take,\n throwIfEmpty,\n timer,\n type Observable,\n type Subscription,\n} from 'rxjs'\n\nimport type { MutationCache } from './mutation-cache'\nimport { defaultRetryDelay, resolveRetryDelay, shouldRetry } from './retryer'\nimport type { RetryDelayValue, RetryValue } from './types'\n\n/** Lifecycle status of a mutation: not yet run, running, succeeded, or failed. */\nexport type MutationStatus = 'idle' | 'pending' | 'success' | 'error'\n\n/** Selects which mutations an operation applies to (e.g. `injectIsMutating`). */\nexport type MutationFilters = {\n /** Match mutations in this status. */\n status?: MutationStatus\n}\n\n/** Full state snapshot of a mutation (the reactive source behind {@link MutationResult}). */\nexport type MutationState<TData, TError, TVariables, TContext> = {\n /** Current {@link MutationStatus}. */\n status: MutationStatus\n /** Data resolved by the last successful run, or `undefined`. */\n data: TData | undefined\n /** Error of the last failed run, or `null`. */\n error: TError | null\n /** Variables passed to the most recent `mutate()` call. */\n variables: TVariables | undefined\n /** Value returned by `onMutate` for the current run. */\n context: TContext | undefined\n /** Number of failed attempts in the current run. */\n failureCount: number\n /** Error of the most recent failed attempt, or `null`. */\n failureReason: TError | null\n /** Timestamp (ms) when the current run was submitted; `0` if never. */\n submittedAt: number\n}\n\n/**\n * Configuration for a mutation, passed to {@link injectMutation} /\n * {@link mutationOptions}. The hooks fire in order: `onMutate` →\n * (`onSuccess` | `onError`) → `onSettled`. The value returned by `onMutate`\n * is passed as `context` to the later hooks — handy for rollback.\n */\nexport type MutationOptions<TData, TError, TVariables, TContext> = {\n /** Performs the write; receives `mutate()`'s argument. Returns `Observable`/`Promise`. */\n mutationFn: (variables: TVariables) => Observable<TData> | Promise<TData>\n /** Retry policy. Defaults to no retry (writes are not idempotent). */\n retry?: RetryValue<TError>\n /** Delay between retries. See {@link RetryDelayValue}. */\n retryDelay?: RetryDelayValue<TError>\n /** Runs before `mutationFn`; its return value becomes `context` (e.g. for optimistic rollback). */\n onMutate?: (variables: TVariables) => TContext | undefined\n /** Runs after a successful `mutationFn`. */\n onSuccess?: (\n data: TData,\n variables: TVariables,\n context: TContext | undefined,\n ) => void\n /** Runs after a failed `mutationFn`. */\n onError?: (\n error: TError,\n variables: TVariables,\n context: TContext | undefined,\n ) => void\n /** Runs after success or error — for cleanup that should happen either way. */\n onSettled?: (\n data: TData | undefined,\n error: TError | null,\n variables: TVariables,\n context: TContext | undefined,\n ) => void\n}\n\n/** Reactive result returned by {@link injectMutation}; state fields are signals. */\nexport type MutationResult<TData, TError, TVariables> = {\n /** Triggers the mutation with the given variables. */\n mutate: (variables: TVariables) => void\n /** Resets state back to `idle`, cancelling any in-flight run. */\n reset: () => void\n /** Data from the last successful run, or `undefined`. */\n data: Signal<TData | undefined>\n /** Error from the last failed run, or `null`. */\n error: Signal<TError | null>\n /** Variables from the most recent `mutate()` call. */\n variables: Signal<TVariables | undefined>\n /** Current {@link MutationStatus}. */\n status: Signal<MutationStatus>\n /** Whether the mutation has not been run yet. */\n isIdle: Signal<boolean>\n /** Whether the mutation is currently running. */\n isPending: Signal<boolean>\n /** Whether the last run succeeded. */\n isSuccess: Signal<boolean>\n /** Whether the last run failed. */\n isError: Signal<boolean>\n /** Consecutive failures in the current run. */\n failureCount: Signal<number>\n /** Error of the most recent failed attempt, or `null`. */\n failureReason: Signal<TError | null>\n}\n\n/** @internal */\nexport function getInitialState<\n TData,\n TError,\n TVariables,\n TContext,\n>(): MutationState<TData, TError, TVariables, TContext> {\n return {\n status: 'idle',\n data: undefined,\n error: null,\n variables: undefined,\n context: undefined,\n failureCount: 0,\n failureReason: null,\n submittedAt: 0,\n }\n}\n\n/** @internal */\nexport class Mutation<\n TData = unknown,\n TError = Error,\n TVariables = void,\n TContext = unknown,\n> {\n readonly #state =\n signal<MutationState<TData, TError, TVariables, TContext>>(\n getInitialState(),\n )\n\n // `state` must follow `#state`: a public field can't precede the private\n // field it reads during initialization (field init order).\n // eslint-disable-next-line @typescript-eslint/member-ordering\n readonly state = this.#state.asReadonly()\n\n #subscription: Subscription | null = null\n #observers = 0\n readonly #options: MutationOptions<TData, TError, TVariables, TContext>\n readonly #cache: MutationCache\n\n constructor(\n readonly mutationId: number,\n options: MutationOptions<TData, TError, TVariables, TContext>,\n cache: MutationCache,\n ) {\n this.#options = options\n this.#cache = cache\n }\n\n get observerCount(): number {\n return this.#observers\n }\n\n addObserver(): void {\n this.#observers++\n }\n\n /**\n * Unlike a query, losing its last observer does not cancel a mutation: the\n * write has most likely reached the server already, so it must be allowed to\n * land and run its hooks. It is only dropped from the cache once it has both\n * settled and been abandoned — whichever of the two happens last.\n */\n removeObserver(): void {\n if (this.#observers === 0) return\n\n this.#observers--\n\n this.#disposeIfDone()\n }\n\n /** Runs the mutation once. `variables` are passed straight to `mutationFn`. */\n execute(variables: TVariables): void {\n const context = this.#options.onMutate?.(variables)\n // Mutations default to no retry (not idempotent — a retried POST could\n // create a duplicate); opt in explicitly via options.retry.\n const retry = this.#options.retry ?? 0\n const retryDelay = this.#options.retryDelay ?? defaultRetryDelay\n\n this.#state.set({\n status: 'pending',\n data: undefined,\n error: null,\n variables,\n context,\n failureCount: 0,\n failureReason: null,\n submittedAt: Date.now(),\n })\n\n // defer + from: normalize Observable/Promise and re-invoke mutationFn on\n // each retry (a Promise is one-shot, so retry must produce a fresh one).\n this.#subscription = defer(() => from(this.#options.mutationFn(variables)))\n .pipe(\n take(1),\n retryOperator({\n delay: (error, retryCount) => {\n this.#state.update((state) => ({\n ...state,\n failureCount: retryCount,\n failureReason: error as TError,\n }))\n\n const attemptIndex = retryCount - 1\n\n if (!shouldRetry(retry, attemptIndex, error as TError)) throw error\n\n return timer(\n resolveRetryDelay(retryDelay, attemptIndex, error as TError),\n )\n },\n }),\n throwIfEmpty(\n () =>\n new Error('Mutation function completed without emitting a value'),\n ),\n )\n .subscribe({\n // `finally`: a hook that throws must not leave the mutation stranded in\n // the cache (where injectIsMutating would keep counting it forever).\n next: (data) => {\n this.#state.update((state) => ({ ...state, status: 'success', data }))\n\n try {\n this.#options.onSuccess?.(data, variables, context)\n this.#options.onSettled?.(data, null, variables, context)\n } finally {\n this.#disposeIfDone()\n }\n },\n error: (error: TError) => {\n this.#state.update((state) => ({ ...state, status: 'error', error }))\n\n try {\n this.#options.onError?.(error, variables, context)\n this.#options.onSettled?.(undefined, error, variables, context)\n } finally {\n this.#disposeIfDone()\n }\n },\n })\n }\n\n cancel(): void {\n this.#subscription?.unsubscribe()\n this.#subscription = null\n }\n\n /**\n * A run nobody observes any more, and which is no longer in flight, has\n * nothing left to report — drop it. Called from both ends, since the two\n * conditions can be met in either order: a superseded run may settle later,\n * and a settled run may be abandoned later.\n */\n #disposeIfDone(): void {\n if (this.#observers > 0) return\n if (this.state().status === 'pending') return\n\n this.#cache.remove(this)\n }\n}\n","import { Injectable } from '@angular/core'\n\nimport { Cache } from './cache'\nimport {\n type MutationFilters,\n type MutationOptions,\n Mutation,\n} from './mutation'\n\n/** @internal */\n@Injectable()\nexport class MutationCache extends Cache<\n Mutation<unknown, unknown, unknown, unknown>\n> {\n #lastId = 0\n\n build<TData, TError, TVariables, TContext>(\n options: MutationOptions<TData, TError, TVariables, TContext>,\n ): Mutation<TData, TError, TVariables, TContext> {\n const mutation = new Mutation(++this.#lastId, options, this)\n\n this.addEntry(\n String(mutation.mutationId),\n mutation as Mutation<unknown, unknown, unknown, unknown>,\n )\n\n return mutation\n }\n\n findAll(\n filters: MutationFilters = {},\n ): Array<Mutation<unknown, unknown, unknown, unknown>> {\n // Reads the reactive `entries()` so findAll() works inside computed().\n const all = this.entries()\n\n if (!filters.status) return all\n\n return all.filter((mutation) => mutation.state().status === filters.status)\n }\n\n remove<TData, TError, TVariables, TContext>(\n mutation: Mutation<TData, TError, TVariables, TContext>,\n ): void {\n this.removeEntry(String(mutation.mutationId))\n }\n\n override clear(): void {\n this.getAll().forEach((mutation) => mutation.cancel())\n super.clear()\n }\n}\n","import { InjectionToken } from '@angular/core'\n\nimport type { RetryDelayValue, RetryValue } from './types'\n\n/** @internal */\nexport interface QueryClientConfig {\n defaultOptions?: {\n queries?: {\n staleTime?: number\n gcTime?: number\n retry?: RetryValue<unknown>\n retryDelay?: RetryDelayValue<unknown>\n }\n }\n}\n\n/** @internal */\nexport const QUERY_CLIENT_CONFIG = new InjectionToken<QueryClientConfig>(\n 'QUERY_CLIENT_CONFIG',\n)\n","import { inject, Injectable, untracked } from '@angular/core'\nimport type { Observable } from 'rxjs'\n\nimport { QueryCache } from './query-cache'\nimport { MutationCache } from './mutation-cache'\nimport { defaultRetryDelay } from './retryer'\nimport { functionalUpdate } from './utils'\nimport type {\n DefaultedQueryOptions,\n QueryFilters,\n QueryKey,\n QueryOptions,\n RetryDelayValue,\n RetryValue,\n Updater,\n} from './types'\nimport { QUERY_CLIENT_CONFIG } from './injection-tokens'\n\n/**\n * Central registry and cache for queries and mutations.\n *\n * Provided by {@link provideQueryClient} and retrieved with\n * {@link injectQueryClient}. Offers imperative cache access — reading and\n * writing data, and invalidating, cancelling, or removing queries — that\n * complements the reactive {@link injectQuery} / {@link injectMutation} APIs.\n */\n@Injectable()\nexport class QueryClient {\n readonly #cache = inject(QueryCache)\n readonly #mutationCache = inject(MutationCache)\n readonly #config = inject(QUERY_CLIENT_CONFIG, { optional: true }) ?? {}\n\n /** Returns the underlying query cache. Advanced/internal use. */\n getQueryCache(): QueryCache {\n return this.#cache\n }\n\n /** Returns the underlying mutation cache. Advanced/internal use. */\n getMutationCache(): MutationCache {\n return this.#mutationCache\n }\n\n /**\n * Merges per-query options with the configured defaults, filling in\n * `staleTime`, `gcTime`, `retry`, and `retryDelay`. Used internally by\n * {@link injectQuery}.\n */\n defaultQueryOptions<TData, TError = Error>(\n options: QueryOptions<TData, TError>,\n ): DefaultedQueryOptions<TData, TError> {\n const defaults = this.#config.defaultOptions?.queries\n\n return {\n ...options,\n staleTime: options.staleTime ?? defaults?.staleTime ?? 0,\n gcTime: options.gcTime ?? defaults?.gcTime,\n retry: options.retry ?? defaults?.retry ?? 3,\n retryDelay:\n options.retryDelay ?? defaults?.retryDelay ?? defaultRetryDelay,\n }\n }\n\n /**\n * Imperatively fetches and caches a query, unless fresh data already exists\n * (governed by `staleTime`). Prefer {@link injectQuery} in components; use\n * this for prefetching outside the reactive flow.\n *\n * @param key - The query key to fetch and cache under.\n * @param queryFn - Function returning the data as an `Observable` or `Promise`.\n * @param options - Fetch tuning (`staleTime`, `retry`, `retryDelay`,\n * `cancelRefetch`).\n */\n fetchQuery<TData>(\n key: QueryKey,\n queryFn: () => Observable<TData> | Promise<TData>,\n options: {\n staleTime?: number\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n retry?: RetryValue<any>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n retryDelay?: RetryDelayValue<any>\n cancelRefetch?: boolean\n } = {},\n ): void {\n const defaults = this.#config.defaultOptions?.queries\n const staleTime = options.staleTime ?? defaults?.staleTime ?? 0\n const retry = options.retry ?? defaults?.retry ?? 3\n const retryDelay =\n options.retryDelay ?? defaults?.retryDelay ?? defaultRetryDelay\n\n const query = this.#cache.getOrCreate<TData>(key)\n\n if (query.shouldFetch(staleTime)) {\n query.fetch(queryFn, retry, retryDelay, options.cancelRefetch)\n }\n }\n\n /**\n * Reads the current cached data for a query key, or `undefined` if the query\n * is not cached yet.\n *\n * @param key - The query key to read.\n * @returns The cached data, or `undefined`.\n */\n getQueryData<TData>(key: QueryKey): TData | undefined {\n return this.#cache.get<TData>(key)?.state().data\n }\n\n /**\n * Writes data into the cache for a query key, creating the entry if needed.\n * The `updater` may be a value or a function of the previous data; returning\n * `undefined` from the function is a no-op. Useful for optimistic updates.\n *\n * @param key - The query key to write.\n * @param updater - The new data, or a function `(prev) => next`.\n *\n * @example\n * ```ts\n * client.setQueryData<Todo[]>(['todos'], (prev = []) => [...prev, newTodo])\n * ```\n */\n setQueryData<TData>(\n key: QueryKey,\n updater: Updater<TData | undefined, TData>,\n ): void {\n const query = this.#cache.getOrCreate<TData>(key)\n const data = functionalUpdate(updater, query.state().data)\n\n // Matches TanStack: an updater returning undefined is a no-op.\n if (data === undefined) return\n\n query.setData(data)\n }\n\n /**\n * Marks matching queries as stale and refetches the actively observed ones,\n * once per query however many components observe it. The refetch starts\n * right away and replaces a fetch already in flight, which may predate the\n * change; this method doesn't wait for it. A query with no enabled observer\n * keeps the stale mark and refetches as soon as one appears. Commonly called\n * after a mutation succeeds.\n *\n * @param filters - Which queries to invalidate; omit to invalidate all.\n *\n * @example\n * ```ts\n * client.invalidateQueries({ queryKey: ['todos'] })\n * ```\n */\n invalidateQueries(filters?: QueryFilters): void {\n const queries = this.#cache.findAll(filters)\n\n queries.forEach((query) => query.invalidate())\n\n // Refetch each active query once, however many observers watch it; an\n // inactive one refetches when next observed, as shouldFetch sees the flag.\n // cancelRefetch: a fetch already in flight started before the\n // invalidation, so it may have missed the change. untracked: queryFn runs\n // synchronously here, and an effect calling this mustn't start tracking\n // what it reads.\n untracked(() =>\n queries.forEach((query) => {\n const options = query.activeFetchOptions()\n\n if (options) {\n query.fetch(options.queryFn, options.retry, options.retryDelay, true)\n }\n }),\n )\n }\n\n /**\n * Cancels any in-flight fetches for matching queries.\n *\n * @param filters - Which queries to cancel; omit to cancel all.\n */\n cancelQueries(filters?: QueryFilters): void {\n this.#cache.findAll(filters).forEach((query) => query.cancel())\n }\n\n /**\n * Removes matching queries from the cache entirely, discarding their data.\n *\n * @param filters - Which queries to remove; omit to remove all.\n */\n removeQueries(filters?: QueryFilters): void {\n this.#cache.findAll(filters).forEach((query) => {\n query.destroy()\n this.#cache.remove(query)\n })\n }\n\n /**\n * Returns the number of matching queries currently fetching. For a reactive\n * count, prefer {@link injectIsFetching}.\n *\n * @param filters - Which queries to count; omit to count all.\n */\n isFetching(filters?: QueryFilters): number {\n return this.#cache\n .findAll(filters)\n .filter((query) => query.state().isFetching).length\n }\n\n /**\n * Returns the number of mutations currently pending. For a reactive count,\n * prefer {@link injectIsMutating}.\n */\n isMutating(): number {\n return this.#mutationCache.findAll({ status: 'pending' }).length\n }\n}\n","import type { Provider } from '@angular/core'\n\n/**\n * Discriminator identifying each kind of {@link QueryClientFeature}.\n *\n * @internal\n */\nexport enum QueryClientFeatureKind {\n DefaultOptions,\n}\n\n/**\n * An opaque feature passed to {@link provideQueryClient}. Create one with a\n * `with*` helper such as {@link withDefaultOptions} rather than constructing it\n * directly; the `ɵ`-prefixed members are internal.\n */\nexport interface QueryClientFeature<\n K extends QueryClientFeatureKind = QueryClientFeatureKind,\n> {\n ɵkind: K\n ɵproviders: Provider[]\n}\n\n/** @internal */\nexport function queryClientFeature<K extends QueryClientFeatureKind>(\n kind: K,\n providers: Provider[],\n): QueryClientFeature<K> {\n return { ɵkind: kind, ɵproviders: providers }\n}\n","import {\n type EnvironmentProviders,\n makeEnvironmentProviders,\n} from '@angular/core'\n\nimport { QueryClient } from './query-client'\nimport { QueryCache } from './query-cache'\nimport { MutationCache } from './mutation-cache'\nimport {\n type QueryClientFeature,\n QueryClientFeatureKind,\n} from '../features/feature'\n\n/**\n * Registers the {@link QueryClient} and its caches for the application.\n *\n * Call once at the app root (in `ApplicationConfig.providers` or a root\n * `bootstrapApplication`). Pass features such as {@link withDefaultOptions} to\n * configure defaults. Registering the same feature twice throws.\n *\n * @param features - Optional {@link QueryClientFeature}s (e.g.\n * {@link withDefaultOptions}).\n * @returns Environment providers to add to the app's provider list.\n *\n * @example\n * ```ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(),\n * provideQueryClient(\n * withDefaultOptions({ queries: { staleTime: 30_000 } }),\n * ),\n * ],\n * }\n * ```\n */\nexport function provideQueryClient(\n ...features: QueryClientFeature[]\n): EnvironmentProviders {\n const seenKinds = new Set<QueryClientFeatureKind>()\n\n for (const feature of features) {\n if (seenKinds.has(feature.ɵkind)) {\n throw new Error(\n `provideQueryClient: feature \"${QueryClientFeatureKind[feature.ɵkind]}\" is registered more than once`,\n )\n }\n seenKinds.add(feature.ɵkind)\n }\n\n return makeEnvironmentProviders([\n QueryCache,\n MutationCache,\n QueryClient,\n ...features.flatMap((feature) => feature.ɵproviders),\n ])\n}\n","import { type Injector, assertInInjectionContext, inject } from '@angular/core'\n\nimport { QueryClient } from './query-client'\n\n/**\n * Returns the application's {@link QueryClient} for imperative cache access.\n *\n * Use it to read or write cached data (`getQueryData`, `setQueryData`) and to\n * invalidate, cancel, or remove queries — typically from mutation hooks or\n * event handlers. Requires {@link provideQueryClient} to be registered.\n *\n * Must run in an injection context, or be given an explicit `injector`.\n *\n * @param options - Optional `injector` to use outside an injection context.\n * @returns The shared {@link QueryClient} instance.\n *\n * @example\n * ```ts\n * const client = injectQueryClient()\n * client.setQueryData<Todo[]>(['todos'], (prev = []) => [...prev, newTodo])\n * client.invalidateQueries({ queryKey: ['todos'] })\n * ```\n */\nexport function injectQueryClient(options?: {\n injector?: Injector\n}): QueryClient {\n if (!options?.injector) assertInInjectionContext(injectQueryClient)\n\n return options?.injector?.get(QueryClient) ?? inject(QueryClient)\n}\n","/**\n * Calls `poll` every `ms`, but never sooner than `ms` after `updatedAt()`:\n * when the timer comes due earlier, it waits out the rest of the interval\n * from then. Returns a function that stops polling.\n *\n * @internal\n */\nexport function startPolling(\n ms: number,\n updatedAt: () => number,\n poll: () => void,\n): () => void {\n let timer: ReturnType<typeof setTimeout>\n\n const wait = (delay: number): void => {\n timer = setTimeout(() => {\n const elapsed = Date.now() - updatedAt()\n\n if (elapsed < ms) {\n wait(ms - elapsed)\n\n return\n }\n\n poll()\n wait(ms)\n }, delay)\n }\n\n wait(ms)\n\n return () => clearTimeout(timer)\n}\n","import {\n type EffectCleanupRegisterFn,\n type EffectRef,\n type Injector,\n computed,\n effect,\n signal,\n untracked,\n} from '@angular/core'\n\nimport { startPolling } from './polling'\nimport { QueryClient } from './query-client'\nimport type { Query, QuerySubscriber } from './query'\nimport type {\n PlaceholderDataFunction,\n QueryKey,\n QueryOptions,\n QueryResult,\n QueryStatus,\n} from './types'\nimport { hashKey, isValidTimeout } from './utils'\n\n/**\n * One observed query: its reactive {@link QueryResult} and a `destroy()` that\n * ends the observation (drops the cache observer, stops polling).\n *\n * @internal\n */\nexport interface QueryObserver<TData, TError = Error> {\n result: QueryResult<TData, TError>\n destroy: () => void\n}\n\n/**\n * Observes a single query and exposes its state as signals — the engine behind\n * {@link injectQuery} and {@link injectQueries}.\n *\n * Nothing is evaluated on creation: `optionsFn` is first called by the first\n * effect run or the first read of a result signal, so it may depend on state\n * that isn't ready while the owner is being constructed (inputs, fields\n * declared later).\n *\n * Effects are created on `injector` with `manualCleanup` so the observer can be\n * torn down on its own via `destroy()`, independently of the injector's\n * lifetime (a component may drop one query out of many). In a component\n * injector they run as view effects, elsewhere as root effects — the same as\n * `effect()` called directly in that context.\n *\n * @internal\n */\nexport function createQueryObserver<TData, TError = Error>(\n optionsFn: () => QueryOptions<TData, TError>,\n injector: Injector,\n): QueryObserver<TData, TError> {\n const client = injector.get(QueryClient)\n const cache = client.getQueryCache()\n\n // Every effect is registered here so destroy() covers all of them.\n const refs: EffectRef[] = []\n const track = (fn: (onCleanup: EffectCleanupRegisterFn) => void): void => {\n refs.push(effect(fn, { injector, manualCleanup: true }))\n }\n\n // Single source of truth for defaulted options; resolves config defaults\n // (staleTime, gcTime) once instead of scattering the logic across effects.\n const defaultedOptions = computed(() =>\n client.defaultQueryOptions(optionsFn()),\n )\n\n // Seed a fresh query (status 'pending', no data yet) with initialData so\n // it renders immediately as 'success'. Without an explicit\n // initialDataUpdatedAt the seed is treated as fetched right now, so\n // staleTime applies to it as it would to any other data (a staleTime of 0\n // still means \"stale immediately\" → background refetch).\n const applyInitialData = (q: Query<TData, TError>): void => {\n const { initialData, initialDataUpdatedAt } = untracked(defaultedOptions)\n\n if (initialData === undefined || q.state().status !== 'pending') return\n\n const data =\n typeof initialData === 'function'\n ? (initialData as () => TData)()\n : initialData\n const updatedAt =\n typeof initialDataUpdatedAt === 'function'\n ? initialDataUpdatedAt()\n : (initialDataUpdatedAt ?? Date.now())\n\n q.setData(data, updatedAt)\n }\n\n // Resolves the query for a key, seeding a fresh one with initialData. It\n // writes signals (the cache's entries, the query's state), so callers run it\n // untracked: reached from a computed, a tracked write throws NG0600.\n const resolve = (key: QueryKey): Query<TData, TError> => {\n const q = cache.getOrCreate<TData, TError>(key)\n\n applyInitialData(q)\n\n return q\n }\n\n // The query the key effect below last switched to; unset until it first runs.\n const switched = signal<Query<TData, TError> | undefined>(undefined)\n\n // The observed query, resolved lazily: on the first read of a result signal\n // or the first effect run, whichever comes first. Resolving it calls\n // optionsFn, which may read inputs or fields that don't exist yet while the\n // owner is being constructed. A read before the key effect's first run\n // resolves the current key on the spot, so it already sees cached data and\n // initialData; from then on only the key effect switches queries.\n const query = computed(\n () => switched() ?? untracked(() => resolve(defaultedOptions().queryKey)),\n )\n\n // Data of the last query that had any, fed to the placeholderData function\n // on key change (mirrors TanStack's lastQueryWithDefinedData). Captured\n // synchronously before the switch so it can't miss a just-resolved value.\n const lastData = signal<TData | undefined>(undefined)\n\n track(() => {\n const key = defaultedOptions().queryKey\n const q = untracked(() => resolve(key))\n\n untracked(() => {\n const prev = switched()\n\n if (prev && prev !== q && prev.state().data !== undefined) {\n lastData.set(prev.state().data)\n }\n })\n switched.set(q)\n })\n\n // How this observer would fetch q right now, from the live options; null\n // while it is disabled, or once the key has moved on. Before the key effect\n // above catches up, queryFn already fetches the next query's data, so q\n // must not be fetched with it. Both refetches made on our behalf go by it:\n // the invalidation one (through q's subscriber handle) and polling.\n const fetchOptionsFor = (\n q: Query<TData, TError>,\n ): ReturnType<QuerySubscriber<TData, TError>['fetchOptions']> => {\n const { queryKey, queryFn, retry, retryDelay, enabled } =\n untracked(defaultedOptions)\n\n if (enabled === false || hashKey(queryKey) !== q.queryHash) {\n return null\n }\n\n return { queryFn, retry, retryDelay }\n }\n\n track((cleanup) => {\n const q = query()\n const { gcTime } = untracked(defaultedOptions)\n\n if (gcTime !== undefined) {\n q.setGcTime(gcTime)\n }\n\n // This observer as q sees it.\n const subscriber: QuerySubscriber<TData, TError> = {\n fetchOptions: () => fetchOptionsFor(q),\n }\n\n q.addObserver(subscriber)\n cleanup(() => q.removeObserver(subscriber))\n })\n\n // Memoized so options re-evaluations that leave the flag alone don't wake\n // the fetch and polling effects.\n const enabled = computed(() => defaultedOptions().enabled !== false)\n\n // Fetch when the observed query switches (key change) or when it becomes\n // enabled — not on every re-evaluation of the options. defaultQueryOptions()\n // builds a fresh object each time, so tracking it whole would refetch stale\n // data whenever any signal read in optionsFn changes, even one unrelated to\n // the key. queryFn, staleTime and the retry policy only parameterise the\n // fetch and are read untracked (TanStack's shouldFetchOptionally).\n // Invalidation isn't a trigger: invalidateQueries() refetches each active\n // query once itself. A query it skipped (unobserved, or its observers\n // disabled) stays invalidated, so it fetches here once observed or enabled:\n // shouldFetch sees the flag.\n track(() => {\n query()\n\n if (!enabled()) return\n\n const { queryKey, queryFn, staleTime, retry, retryDelay } =\n untracked(defaultedOptions)\n\n untracked(() =>\n client.fetchQuery(queryKey, queryFn, { staleTime, retry, retryDelay }),\n )\n })\n\n // The polling interval this observer asks for, or false for none. Memoized,\n // so the polling effect wakes only when the value changes. The function form\n // is resolved against the query's state, so it is re-resolved on every\n // update of it, and a switch to false stops polling. 0 means no polling, and\n // so does a value no timer can hold: the timer would fire over and over.\n const interval = computed(() => {\n const { refetchInterval } = defaultedOptions()\n const value =\n typeof refetchInterval === 'function'\n ? refetchInterval({ state: query().state() })\n : refetchInterval\n\n return isValidTimeout(value) && value > 0 ? value : false\n })\n\n // Polling: refetch on an interval, independent of staleTime. The timer\n // restarts when the observed query switches, or when enabled or the interval\n // changes, as in TanStack's setOptions. It doesn't restart on every\n // re-evaluation of the options: defaultQueryOptions() builds a fresh object\n // each time, so tracking it whole would restart the timer whenever any\n // signal read in optionsFn changes. One that changes faster than the\n // interval would keep it from ever firing.\n //\n // Each poll comes ms after the query's last update, as in TanStack, whose\n // observer restarts its timer on every update of the query. So a fetch made\n // for any reason (another observer's poll, refetch(), an invalidation) or a\n // cache write pushes the next poll back. However many observers poll a key,\n // it's fetched once per interval. Unlike TanStack, the wait counts from\n // updatedAt, the last response or cache write, not from any change of\n // state: a fetch that starts or fails doesn't push it back.\n track((onCleanup) => {\n const q = query()\n\n if (!enabled()) return\n\n const ms = interval()\n\n if (!ms) return\n\n // Fetches q with the options as they are when it fires, which may have\n // changed since the effect ran.\n const poll = (): void => {\n const options = fetchOptionsFor(q)\n\n if (options) q.fetch(options.queryFn, options.retry, options.retryDelay)\n }\n\n onCleanup(startPolling(ms, () => q.state().updatedAt, poll))\n })\n\n // Placeholder layer: while the query is pending with no data, present\n // placeholderData as already-successful data. Purely presentational — the\n // cache entry stays 'pending' and the fetch proceeds, so isFetching keeps\n // reporting the real request and the placeholder is dropped on resolve.\n const resolved = computed<{\n data: TData | undefined\n status: QueryStatus\n isPlaceholderData: boolean\n }>(() => {\n const state = query().state()\n const { placeholderData } = defaultedOptions()\n\n if (\n placeholderData !== undefined &&\n state.data === undefined &&\n state.status === 'pending'\n ) {\n const data =\n typeof placeholderData === 'function'\n ? (placeholderData as PlaceholderDataFunction<TData>)(lastData())\n : placeholderData\n\n if (data !== undefined) {\n return { data, status: 'success', isPlaceholderData: true }\n }\n }\n\n return { data: state.data, status: state.status, isPlaceholderData: false }\n })\n\n return {\n result: {\n data: computed(() => resolved().data),\n status: computed(() => resolved().status),\n error: computed(() => query().state().error as TError | null),\n isFetching: computed(() => query().state().isFetching),\n // First fetch in-flight: fetching with no resolved data yet. An active\n // placeholder counts as data — the UI shows it, not a loading state.\n isLoading: computed(\n () => query().state().isFetching && resolved().status === 'pending',\n ),\n isPending: computed(() => resolved().status === 'pending'),\n isSuccess: computed(() => resolved().status === 'success'),\n isError: computed(() => resolved().status === 'error'),\n isPlaceholderData: computed(() => resolved().isPlaceholderData),\n failureCount: computed(() => query().state().failureCount),\n failureReason: computed(\n () => query().state().failureReason as TError | null,\n ),\n // Force a fresh fetch regardless of staleTime, cancelling any in-flight\n // request (explicit user intent — get current data).\n refetch: () => {\n const { queryKey, queryFn, retry, retryDelay } =\n untracked(defaultedOptions)\n\n client.fetchQuery(queryKey, queryFn, {\n staleTime: 0,\n retry,\n retryDelay,\n cancelRefetch: true,\n })\n },\n },\n destroy: () => refs.forEach((ref) => ref.destroy()),\n }\n}\n","import {\n assertInInjectionContext,\n DestroyRef,\n inject,\n Injector,\n} from '@angular/core'\n\nimport { createQueryObserver } from './query-observer'\nimport type { QueryOptions, QueryResult } from './types'\n\n/**\n * Runs a cached, reactive query and exposes its state as signals.\n *\n * The query is keyed by `queryKey`: calls with the same key share a single\n * cache entry and in-flight request (deduplication). `optionsFn` is read in a\n * reactive context, so when a value it depends on changes (e.g. a route or\n * input signal in the key), the query automatically switches to the new key\n * and fetches. `optionsFn` isn't called before the query is first needed (its\n * first effect run or the first read of a result signal), so it can read\n * inputs, `input.required` included, and fields declared after the query. The\n * query is bound to the current injection context and cleans up its cache\n * observer when that context is destroyed.\n *\n * Must run in an injection context, or be given an explicit `injector`.\n *\n * @typeParam TData - Type of the data resolved by `queryFn`.\n * @typeParam TError - Type of the error thrown by `queryFn`.\n * @param optionsFn - Factory returning the {@link QueryOptions}. Re-evaluated\n * reactively: a new `queryKey` switches to that query and fetches it, and\n * turning `enabled` on starts the fetch. Re-evaluating with the same key\n * does not refetch, so every value `queryFn` reads belongs in the key.\n * @param options - Optional `injector` to use outside an injection context.\n * @returns A {@link QueryResult} of signals (`data`, `status`, `error`,\n * `isLoading`, `isPending`, …) plus a `refetch()` that forces a fresh fetch.\n *\n * @example\n * ```ts\n * @Component({\n * template: `\n * @if (todo.isPending()) { <p>Loading…</p> }\n * @if (todo.data(); as data) { <p>{{ data.title }}</p> }\n * `,\n * })\n * class TodoComponent {\n * readonly id = input.required<number>()\n * private readonly http = inject(HttpClient)\n *\n * // Refetches automatically whenever `id()` changes.\n * readonly todo = injectQuery(() => ({\n * queryKey: ['todo', this.id()],\n * queryFn: () => this.http.get<Todo>(`/api/todos/${this.id()}`),\n * }))\n * }\n * ```\n */\nexport function injectQuery<TData, TError = Error>(\n optionsFn: () => QueryOptions<TData, TError>,\n options?: { injector?: Injector },\n): QueryResult<TData, TError> {\n if (!options?.injector) assertInInjectionContext(injectQuery)\n\n const injector = options?.injector ?? inject(Injector)\n const { result, destroy } = createQueryObserver(optionsFn, injector)\n\n // The observation lives as long as the owning context (component or\n // injector): tear it down with it.\n injector.get(DestroyRef).onDestroy(destroy)\n\n return result\n}\n","import {\n type Signal,\n type WritableSignal,\n assertInInjectionContext,\n computed,\n DestroyRef,\n effect,\n inject,\n Injector,\n signal,\n untracked,\n} from '@angular/core'\n\nimport { type QueryObserver, createQueryObserver } from './query-observer'\nimport type { QueryOptions, QueryResult } from './types'\nimport { hashKey } from './utils'\n\n/** Options for {@link injectQueries}. */\nexport interface InjectQueriesOptions<TData, TError = Error> {\n /**\n * One {@link QueryOptions} per query to run. The array may change between\n * evaluations: queries are matched to the previous set by `queryKey`, so a\n * new key starts a query and a missing key ends one.\n */\n queries: Array<QueryOptions<TData, TError>>\n}\n\n// A query kept alive by injectQueries: its observer plus the signal feeding it\n// options, written in place for as long as the key stays in the list.\ninterface Entry<TData, TError> {\n hash: string\n options: WritableSignal<QueryOptions<TData, TError>>\n observer: QueryObserver<TData, TError>\n}\n\n/**\n * Runs a dynamic number of queries in parallel and exposes their results as a\n * signal holding one {@link QueryResult} per entry of `queries`, in order.\n *\n * Reach for it when the set of queries depends on data — one query per id in\n * a list, say — where {@link injectQuery} can't be called in a loop. Each\n * query behaves exactly like a standalone `injectQuery`: its own cache entry,\n * `staleTime`, retries, error and observer. `optionsFn` is reactive: when the\n * array changes, queries whose `queryKey` is still present are kept (with\n * their options updated), new keys start fetching, and dropped keys release\n * their observer. As with `injectQuery`, `optionsFn` isn't called before the\n * results are first needed, so it can read inputs, `input.required` included,\n * and fields declared after the call. Aggregate across the results with\n * `computed`.\n *\n * Must run in an injection context, or be given an explicit `injector`.\n *\n * @typeParam TData - Type of the data resolved by each `queryFn`.\n * @typeParam TError - Type of the error thrown by each `queryFn`.\n * @param optionsFn - Factory returning the {@link InjectQueriesOptions}.\n * Re-evaluated reactively, so reading signals inside it re-syncs the set.\n * @param options - Optional `injector` to use outside an injection context.\n * @returns A signal of {@link QueryResult}s, one per query. The array identity\n * changes only when the set of queries changes, not on every data update.\n *\n * @example\n * ```ts\n * class TodoListComponent {\n * readonly #queries = inject(TodoQueries)\n *\n * readonly todoIds = input.required<number[]>()\n *\n * readonly todos = injectQueries(() => ({\n * queries: this.todoIds().map((id) => this.#queries.detail(id)),\n * }))\n *\n * readonly isPending = computed(() =>\n * this.todos().some((todo) => todo.isPending()),\n * )\n * }\n * ```\n */\nexport function injectQueries<TData, TError = Error>(\n optionsFn: () => InjectQueriesOptions<TData, TError>,\n options?: { injector?: Injector },\n): Signal<Array<QueryResult<TData, TError>>> {\n if (!options?.injector) assertInInjectionContext(injectQueries)\n\n const injector = options?.injector ?? inject(Injector)\n\n let entries: Array<Entry<TData, TError>> = []\n let current: Array<QueryResult<TData, TError>> = []\n let destroyed = false\n\n // Reconciles the entries with a new list, matching by key hash the way\n // TanStack's QueriesObserver does: a matching entry is reused and handed the\n // new options, an unmatched query gets a fresh observer, and whatever is\n // left over is destroyed. Duplicate keys are paired up one-to-one in order.\n const sync = (\n queries: Array<QueryOptions<TData, TError>>,\n ): Array<QueryResult<TData, TError>> => {\n const pool = new Map<string, Array<Entry<TData, TError>>>()\n\n for (const entry of entries) {\n const list = pool.get(entry.hash) ?? []\n\n list.push(entry)\n pool.set(entry.hash, list)\n }\n\n const next = queries.map((queryOptions) => {\n const hash = hashKey(queryOptions.queryKey)\n const match = pool.get(hash)?.shift()\n\n if (match) {\n match.options.set(queryOptions)\n\n return match\n }\n\n const optionsSignal = signal(queryOptions)\n\n return {\n hash,\n options: optionsSignal,\n observer: createQueryObserver(() => optionsSignal(), injector),\n }\n })\n\n for (const leftovers of pool.values()) {\n leftovers.forEach((entry) => entry.observer.destroy())\n }\n\n // Replace the result array only on a structural change, so a computed\n // over it doesn't recompute when merely the options were refreshed.\n const changed =\n next.length !== entries.length ||\n next.some((entry, index) => entry !== entries[index])\n\n entries = next\n\n if (changed) current = entries.map((entry) => entry.observer.result)\n\n return current\n }\n\n // The results of the effect's latest sync; unset until its first run.\n const synced = signal<Array<QueryResult<TData, TError>> | undefined>(\n undefined,\n )\n\n effect(\n () => {\n const { queries } = optionsFn()\n\n untracked(() => synced.set(sync(queries)))\n },\n { injector },\n )\n\n injector.get(DestroyRef).onDestroy(() => {\n destroyed = true\n entries.forEach((entry) => entry.observer.destroy())\n })\n\n // Nothing is synced until first needed: on the first read or the effect's\n // first run, whichever comes first. Syncing calls optionsFn, which may read\n // inputs or fields that don't exist yet while the owner is being\n // constructed. A read before the effect's first run syncs on the spot, so\n // it already sees the queries; once destroyed, it creates nothing.\n return computed(\n () =>\n synced() ?? (destroyed ? [] : untracked(() => sync(optionsFn().queries))),\n )\n}\n","import {\n assertInInjectionContext,\n computed,\n DestroyRef,\n inject,\n Injector,\n runInInjectionContext,\n signal,\n untracked,\n} from '@angular/core'\n\nimport { QueryClient } from './query-client'\nimport {\n type Mutation,\n type MutationOptions,\n type MutationResult,\n getInitialState,\n} from './mutation'\n\n/**\n * Creates a mutation for imperative writes (create/update/delete) and exposes\n * its state as signals.\n *\n * Unlike queries, a mutation does not run on its own — call `mutate(variables)`\n * to trigger `mutationFn`. The `onMutate` / `onSuccess` / `onError` /\n * `onSettled` lifecycle hooks make optimistic updates and cache invalidation\n * straightforward. Mutations do not retry by default (a retried write is not\n * idempotent); opt in via `options.retry`. Bound to the current injection\n * context and cancelled when that context is destroyed.\n *\n * Must run in an injection context, or be given an explicit `injector`.\n *\n * @typeParam TData - Type of the data resolved by `mutationFn`.\n * @typeParam TError - Type of the error thrown by `mutationFn`.\n * @typeParam TVariables - Type of the argument passed to `mutate()`.\n * @typeParam TContext - Type returned by `onMutate`, passed to later hooks.\n * @param optionsFn - Factory returning the {@link MutationOptions}.\n * @param options - Optional `injector` to use outside an injection context.\n * @returns A {@link MutationResult}: `mutate()`, `reset()`, and state signals\n * (`status`, `data`, `error`, `isPending`, …).\n *\n * @example\n * ```ts\n * const client = injectQueryClient()\n *\n * const addTodo = injectMutation(() => ({\n * mutationFn: (title: string) => http.post<Todo>('/api/todos', { title }),\n * onSuccess: () => client.invalidateQueries({ queryKey: ['todos'] }),\n * }))\n *\n * // <button (click)=\"addTodo.mutate('Buy milk')\" [disabled]=\"addTodo.isPending()\">Add</button>\n * ```\n */\nexport function injectMutation<\n TData,\n TError = Error,\n TVariables = void,\n TContext = unknown,\n>(\n optionsFn: () => MutationOptions<TData, TError, TVariables, TContext>,\n options?: { injector?: Injector },\n): MutationResult<TData, TError, TVariables> {\n if (!options?.injector) assertInInjectionContext(injectMutation)\n\n const injector = options?.injector ?? inject(Injector)\n\n return runInInjectionContext(injector, () => {\n const cache = inject(QueryClient).getMutationCache()\n\n // Every mutate() builds its own Mutation. Sharing one across calls meant a\n // second call overwrote the first's subscription (orphaning the request)\n // and its state (so the slower run, not the latest one, decided the result).\n const current = signal<Mutation<\n TData,\n TError,\n TVariables,\n TContext\n > | null>(null)\n\n // Detaching is all we do on destroy. A run still in flight keeps going —\n // the write has most likely reached the server already, so cancelling it\n // would only skip onSuccess and leave the cache out of sync. It drops\n // itself from the cache once it settles with nobody watching.\n inject(DestroyRef).onDestroy(() => untracked(current)?.removeObserver())\n\n const state = computed(\n () =>\n current()?.state() ??\n getInitialState<TData, TError, TVariables, TContext>(),\n )\n\n return {\n mutate: (variables) => {\n // Stop observing the previous run. It isn't cancelled — if it's still\n // in flight it finishes and fires its hooks; it just no longer feeds\n // the signals below.\n untracked(current)?.removeObserver()\n\n // Options are read per call, so a signal used in them stays live.\n const run = cache.build(optionsFn())\n\n run.addObserver()\n current.set(run)\n run.execute(variables)\n },\n reset: () => {\n // \"Forget the result\", not \"stop the request\". A run still in flight\n // keeps going and fires its hooks, so the cache stays in step with the\n // server — cancelling could not un-send the write anyway, it could only\n // hide the fact that it happened.\n untracked(current)?.removeObserver()\n\n current.set(null)\n },\n data: computed(() => state().data),\n error: computed(() => state().error as TError | null),\n variables: computed(() => state().variables),\n status: computed(() => state().status),\n isIdle: computed(() => state().status === 'idle'),\n isPending: computed(() => state().status === 'pending'),\n isSuccess: computed(() => state().status === 'success'),\n isError: computed(() => state().status === 'error'),\n failureCount: computed(() => state().failureCount),\n failureReason: computed(() => state().failureReason as TError | null),\n }\n })\n}\n","import {\n type Injector,\n type Signal,\n assertInInjectionContext,\n computed,\n inject,\n} from '@angular/core'\n\nimport { QueryClient } from './query-client'\nimport type { QueryFilters } from './types'\n\n/**\n * Returns a signal with the number of queries currently fetching — useful for a\n * global loading indicator.\n *\n * Pass {@link QueryFilters} to count only matching queries; omit them to count\n * every fetching query in the cache.\n *\n * Must run in an injection context, or be given an explicit `injector`.\n *\n * @param filters - Optional filters (e.g. `{ queryKey: ['todos'] }`) to narrow\n * the count.\n * @param options - Optional `injector` to use outside an injection context.\n * @returns A `Signal<number>` of active fetches.\n *\n * @example\n * ```ts\n * readonly isFetching = injectIsFetching()\n * // <app-spinner *ngIf=\"isFetching() > 0\" />\n * ```\n */\nexport function injectIsFetching(\n filters?: QueryFilters,\n options?: { injector?: Injector },\n): Signal<number> {\n if (!options?.injector) assertInInjectionContext(injectIsFetching)\n\n const client = options?.injector?.get(QueryClient) ?? inject(QueryClient)\n const cache = client.getQueryCache()\n\n return computed(\n () =>\n cache.findAll(filters).filter((query) => query.state().isFetching).length,\n )\n}\n","import {\n type Injector,\n type Signal,\n assertInInjectionContext,\n computed,\n inject,\n} from '@angular/core'\n\nimport { QueryClient } from './query-client'\n\n/**\n * Returns a signal with the number of mutations currently pending — useful for\n * a global \"saving…\" indicator.\n *\n * Must run in an injection context, or be given an explicit `injector`.\n *\n * @param options - Optional `injector` to use outside an injection context.\n * @returns A `Signal<number>` of in-flight mutations.\n *\n * @example\n * ```ts\n * readonly isMutating = injectIsMutating()\n * // <p *ngIf=\"isMutating() > 0\">Saving…</p>\n * ```\n */\nexport function injectIsMutating(options?: {\n injector?: Injector\n}): Signal<number> {\n if (!options?.injector) assertInInjectionContext(injectIsMutating)\n\n const client = options?.injector?.get(QueryClient) ?? inject(QueryClient)\n const cache = client.getMutationCache()\n\n return computed(() => cache.findAll({ status: 'pending' }).length)\n}\n","import type { QueryOptions } from './types'\n\n/**\n * Identity helper that defines a typed, reusable set of {@link QueryOptions}.\n *\n * Returns the options unchanged at runtime, but anchors type inference so the\n * same definition can be shared across {@link injectQuery},\n * {@link QueryClient.setQueryData}, and friends without re-declaring generics.\n * Keeping query definitions in a service (rather than inline) makes them easy\n * to reuse and unit-test.\n *\n * @typeParam TData - Type of the data resolved by `queryFn`.\n * @typeParam TError - Type of the error thrown by `queryFn`.\n * @param options - The {@link QueryOptions} to define.\n * @returns The same `options`, typed.\n *\n * @example\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class TodoQueries {\n * private readonly http = inject(HttpClient)\n *\n * todos() {\n * return queryOptions({\n * queryKey: ['todos'],\n * queryFn: () => this.http.get<Todo[]>('/api/todos'),\n * })\n * }\n * }\n *\n * // const todos = injectQuery(() => inject(TodoQueries).todos())\n * ```\n */\nexport function queryOptions<TData, TError = Error>(\n options: QueryOptions<TData, TError>,\n): QueryOptions<TData, TError> {\n return options\n}\n","/**\n * Placeholder function that keeps the previous query's data visible while the\n * next one loads — pass as `placeholderData` to avoid flicker when the query\n * key changes (e.g. pagination, search).\n *\n * While the placeholder is shown, `status` reads `'success'` and\n * `isPlaceholderData()` is `true`; `isFetching()` stays `true` so the UI can\n * indicate the data is stale.\n *\n * @example\n * ```ts\n * readonly todos = injectQuery(() => ({\n * queryKey: ['todos', this.page()],\n * queryFn: () => this.http.get<Todo[]>(`/api/todos?page=${this.page()}`),\n * placeholderData: keepPreviousData,\n * }))\n * ```\n */\nexport function keepPreviousData<TData>(\n previousData: TData | undefined,\n): TData | undefined {\n return previousData\n}\n","import type { MutationOptions } from './mutation'\n\n/**\n * Identity helper that defines a typed, reusable set of {@link MutationOptions}.\n *\n * Returns the options unchanged at runtime; its job is to anchor type inference\n * (notably linking `TContext` returned by `onMutate` to the later hooks) so a\n * mutation can be defined once in a service and passed to {@link injectMutation}.\n *\n * @typeParam TData - Type of the data resolved by `mutationFn`.\n * @typeParam TError - Type of the error thrown by `mutationFn`.\n * @typeParam TVariables - Type of the argument passed to `mutate()`.\n * @typeParam TContext - Type returned by `onMutate`, passed to later hooks.\n * @param options - The {@link MutationOptions} to define.\n * @returns The same `options`, typed.\n *\n * @example\n * ```ts\n * addTodo() {\n * return mutationOptions({\n * mutationFn: (title: string) => this.http.post<Todo>('/api/todos', { title }),\n * onSuccess: () => this.client.invalidateQueries({ queryKey: ['todos'] }),\n * })\n * }\n * ```\n */\nexport function mutationOptions<\n TData,\n TError = Error,\n TVariables = void,\n TContext = unknown,\n>(\n options: MutationOptions<TData, TError, TVariables, TContext>,\n): MutationOptions<TData, TError, TVariables, TContext> {\n return options\n}\n","import { QUERY_CLIENT_CONFIG } from '../core/injection-tokens'\nimport type { RetryDelayValue, RetryValue } from '../core/types'\nimport {\n type QueryClientFeature,\n QueryClientFeatureKind,\n queryClientFeature,\n} from './feature'\n\n/** Default query options applied to every query unless overridden per-query. */\nexport interface DefaultQueryOptions {\n /** How long fetched data is considered fresh, in ms. Defaults to `0`. */\n staleTime?: number\n /** How long unused (unobserved) data is kept before garbage collection, in ms. */\n gcTime?: number\n /** Retry policy on failure: a boolean, a count, or a predicate. Defaults to `3`. */\n retry?: RetryValue<unknown>\n /** Delay between retries, in ms or a function of the attempt. */\n retryDelay?: RetryDelayValue<unknown>\n}\n\n/** Application-wide defaults configured via {@link withDefaultOptions}. */\nexport interface DefaultOptions {\n /** Defaults applied to all queries. */\n queries?: DefaultQueryOptions\n}\n\n/**\n * Feature for {@link provideQueryClient} that sets application-wide default\n * query options. Per-query options always take precedence over these defaults.\n *\n * @param options - The {@link DefaultOptions} to apply.\n * @returns A {@link QueryClientFeature} to pass to {@link provideQueryClient}.\n *\n * @example\n * ```ts\n * provideQueryClient(\n * withDefaultOptions({ queries: { staleTime: 60_000, retry: 1 } }),\n * )\n * ```\n */\nexport function withDefaultOptions(\n options: DefaultOptions,\n): QueryClientFeature<QueryClientFeatureKind.DefaultOptions> {\n return queryClientFeature(QueryClientFeatureKind.DefaultOptions, [\n { provide: QUERY_CLIENT_CONFIG, useValue: { defaultOptions: options } },\n ])\n}\n","/*\n * Public API Surface of ngx-query\n */\n\nexport * from './lib/core/query-client'\nexport * from './lib/core/provider'\nexport * from './lib/core/inject-query-client'\nexport * from './lib/core/types'\nexport * from './lib/core/inject-query'\nexport * from './lib/core/inject-queries'\nexport * from './lib/core/inject-mutation'\nexport * from './lib/core/inject-is-fetching'\nexport * from './lib/core/inject-is-mutating'\nexport * from './lib/core/query-options'\nexport * from './lib/core/keep-previous-data'\nexport * from './lib/core/mutation-options'\nexport type {\n MutationFilters,\n MutationOptions,\n MutationResult,\n MutationState,\n MutationStatus,\n} from './lib/core/mutation'\nexport { QueryClientFeatureKind } from './lib/features/feature'\nexport type { QueryClientFeature } from './lib/features/feature'\nexport { withDefaultOptions } from './lib/features/with-default-options'\nexport type {\n DefaultOptions,\n DefaultQueryOptions,\n} from './lib/features/with-default-options'\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["retry","retryOperator"],"mappings":"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"}
1
+ {"version":3,"file":"ngx-signal-query.mjs","sources":["../../../projects/ngx-signal-query/src/lib/core/cache.ts","../../../projects/ngx-signal-query/src/lib/core/utils.ts","../../../projects/ngx-signal-query/src/lib/core/retryer.ts","../../../projects/ngx-signal-query/src/lib/core/query.ts","../../../projects/ngx-signal-query/src/lib/core/query-cache.ts","../../../projects/ngx-signal-query/src/lib/core/mutation.ts","../../../projects/ngx-signal-query/src/lib/core/mutation-cache.ts","../../../projects/ngx-signal-query/src/lib/core/injection-tokens.ts","../../../projects/ngx-signal-query/src/lib/core/query-client.ts","../../../projects/ngx-signal-query/src/lib/features/feature.ts","../../../projects/ngx-signal-query/src/lib/core/provider.ts","../../../projects/ngx-signal-query/src/lib/core/inject-query-client.ts","../../../projects/ngx-signal-query/src/lib/core/polling.ts","../../../projects/ngx-signal-query/src/lib/core/query-observer.ts","../../../projects/ngx-signal-query/src/lib/core/inject-query.ts","../../../projects/ngx-signal-query/src/lib/core/inject-queries.ts","../../../projects/ngx-signal-query/src/lib/core/inject-mutation.ts","../../../projects/ngx-signal-query/src/lib/core/inject-is-fetching.ts","../../../projects/ngx-signal-query/src/lib/core/inject-is-mutating.ts","../../../projects/ngx-signal-query/src/lib/core/query-options.ts","../../../projects/ngx-signal-query/src/lib/core/keep-previous-data.ts","../../../projects/ngx-signal-query/src/lib/core/mutation-options.ts","../../../projects/ngx-signal-query/src/lib/features/with-default-options.ts","../../../projects/ngx-signal-query/src/public-api.ts","../../../projects/ngx-signal-query/src/ngx-signal-query.ts"],"sourcesContent":["import { signal } from '@angular/core'\n\n/** @internal */\nexport abstract class Cache<TEntry> {\n readonly #entries = signal<TEntry[]>([])\n\n // Reactive snapshot of all entries; updated on add/remove/clear so that\n // findAll() (and its computed consumers like isFetching) react to the\n // collection. Protected: only subclasses read it, never external code.\n protected readonly entries = this.#entries.asReadonly()\n\n readonly #entriesMap = new Map<string, TEntry>()\n\n getAll(): TEntry[] {\n return Array.from(this.#entriesMap.values())\n }\n\n clear(): void {\n this.#entriesMap.clear()\n this.#sync()\n }\n\n protected addEntry(key: string, entry: TEntry): TEntry {\n this.#entriesMap.set(key, entry)\n this.#sync()\n\n return entry\n }\n\n protected getEntry(key: string): TEntry | undefined {\n return this.#entriesMap.get(key)\n }\n\n protected removeEntry(key: string): boolean {\n const removed = this.#entriesMap.delete(key)\n\n if (removed) this.#sync()\n\n return removed\n }\n\n #sync(): void {\n this.#entries.set(Array.from(this.#entriesMap.values()))\n }\n}\n","import type { QueryKey, Updater } from './types'\n\n// Resolves an updater: calls it with the previous value if it's a function,\n// otherwise uses it as the value directly.\n/** @internal */\nexport function functionalUpdate<TInput, TOutput>(\n updater: Updater<TInput, TOutput>,\n input: TInput,\n): TOutput {\n return typeof updater === 'function'\n ? (updater as (input: TInput) => TOutput)(input)\n : updater\n}\n\n// True when `filter` is a (deep) prefix of `key`, e.g. ['app'] matches\n// ['app', 1]. Used to invalidate/find groups of queries by partial key.\n/** @internal */\nexport function partialMatchKey(key: QueryKey, filter: QueryKey): boolean {\n return partialDeepEqual(key, filter)\n}\n\nfunction partialDeepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (typeof a !== typeof b) return false\n\n if (a && b && typeof a === 'object' && typeof b === 'object') {\n return Object.keys(b).every((key) =>\n partialDeepEqual(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key],\n ),\n )\n }\n\n return false\n}\n\n/** @internal */\nexport function hashKey(key: QueryKey): string {\n return JSON.stringify(key, (_, value) =>\n isPlainObject(value)\n ? Object.keys(value)\n .sort()\n .reduce<Record<string, unknown>>((result, k) => {\n result[k] = value[k]\n\n return result\n }, {})\n : value,\n )\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\n/** @internal */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isPlainObject(o: any): o is Record<PropertyKey, unknown> {\n if (!hasObjectPrototype(o)) {\n return false\n }\n\n // If has no constructor\n const ctor = o.constructor\n\n if (ctor === undefined) {\n return true\n }\n\n // If has modified prototype\n const prot = ctor.prototype\n\n if (!hasObjectPrototype(prot)) {\n return false\n }\n\n // If constructor does not have an Object-specific method\n if (!Object.prototype.hasOwnProperty.call(prot, 'isPrototypeOf')) {\n return false\n }\n\n // Handles Objects created by Object.create(<arbitrary prototype>)\n if (Object.getPrototypeOf(o) !== Object.prototype) {\n return false\n }\n\n // Most likely a plain Object\n return true\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction hasObjectPrototype(o: any): boolean {\n return Object.prototype.toString.call(o) === '[object Object]'\n}\n\n// The longest delay a browser timer holds, in ms. A longer one overflows and\n// the timer fires at once.\nconst MAX_TIMEOUT = 2 ** 31 - 1\n\n// True for a delay a timer can hold. For anything else, Infinity and negative\n// numbers included, a browser runs the timer at once. TanStack's\n// isValidTimeout checks the same, without the upper bound.\n/** @internal */\nexport function isValidTimeout(value: unknown): value is number {\n return typeof value === 'number' && value >= 0 && value <= MAX_TIMEOUT\n}\n","import type { RetryDelayValue, RetryValue } from './types'\n\n// Exponential backoff capped at 30s, matching TanStack's default.\n/** @internal */\nexport function defaultRetryDelay(failureCount: number): number {\n return Math.min(1000 * 2 ** failureCount, 30000)\n}\n\n/** @internal */\nexport function shouldRetry<TError>(\n retry: RetryValue<TError>,\n failureCount: number,\n error: TError,\n): boolean {\n if (typeof retry === 'function') return retry(failureCount, error)\n if (typeof retry === 'number') return failureCount < retry\n\n return retry\n}\n\n/** @internal */\nexport function resolveRetryDelay<TError>(\n retryDelay: RetryDelayValue<TError>,\n failureCount: number,\n error: TError,\n): number {\n return typeof retryDelay === 'function'\n ? retryDelay(failureCount, error)\n : retryDelay\n}\n","import { signal } from '@angular/core'\nimport {\n defer,\n from,\n retry as retryOperator,\n take,\n throwIfEmpty,\n timer,\n type Observable,\n type Subscription,\n} from 'rxjs'\n\nimport type { QueryCache } from './query-cache'\nimport { defaultRetryDelay, resolveRetryDelay, shouldRetry } from './retryer'\nimport type {\n DefaultedQueryOptions,\n QueryKey,\n QueryState,\n RetryDelayValue,\n RetryValue,\n} from './types'\n\nconst DEFAULT_GC_TIME = 5 * 60 * 1000\n\n/**\n * An observer of a query, as the query sees it: the query asks its observers\n * how to fetch it when it refetches on their behalf (after invalidation).\n *\n * @internal\n */\nexport interface QuerySubscriber<TData, TError = Error> {\n /**\n * How this observer would fetch the query right now, read from its live\n * options; `null` while it doesn't want the query fetched: it is disabled,\n * or its key has already moved on to another query.\n */\n fetchOptions(): Pick<\n DefaultedQueryOptions<TData, TError>,\n 'queryFn' | 'retry' | 'retryDelay'\n > | null\n}\n\n/** @internal */\nexport class Query<TData, TError = Error> {\n readonly #state = signal<QueryState<TData, TError>>({\n data: undefined,\n status: 'pending',\n error: null,\n isFetching: false,\n isInvalidated: false,\n failureCount: 0,\n failureReason: null,\n updatedAt: 0,\n })\n\n // `state` must follow `#state`: a public field can't precede the private\n // field it reads during initialization (field init order).\n // eslint-disable-next-line @typescript-eslint/member-ordering\n readonly state = this.#state.asReadonly()\n\n #subscription: Subscription | null = null\n readonly #observers = new Set<QuerySubscriber<TData, TError>>()\n #gcTime = DEFAULT_GC_TIME\n #gcTimer: ReturnType<typeof setTimeout> | null = null\n readonly #cache: QueryCache\n\n constructor(\n readonly key: QueryKey,\n readonly queryHash: string,\n cache: QueryCache,\n ) {\n this.#cache = cache\n }\n\n get observerCount(): number {\n return this.#observers.size\n }\n\n setGcTime(ms: number): void {\n this.#gcTime = ms\n }\n\n addObserver(observer: QuerySubscriber<TData, TError>): void {\n this.#observers.add(observer)\n this.#clearGcTimer()\n }\n\n removeObserver(observer: QuerySubscriber<TData, TError>): void {\n // An observer this query doesn't have changes nothing: it mustn't cancel\n // the fetch or schedule gc while others still watch.\n if (!this.#observers.delete(observer)) return\n\n // No observers left: cancel any in-flight fetch (nobody is waiting for it)\n // and schedule gc to dispose the query if no observer returns.\n if (this.#observers.size === 0) {\n this.cancel()\n this.#scheduleGc()\n }\n }\n\n // How to refetch this query on its observers' behalf: the first observer\n // that wants it fetched decides, as in TanStack; null if none does.\n activeFetchOptions(): ReturnType<\n QuerySubscriber<TData, TError>['fetchOptions']\n > {\n for (const observer of this.#observers) {\n const options = observer.fetchOptions()\n\n if (options) return options\n }\n\n return null\n }\n\n fetch(\n queryFn: () => Observable<TData> | Promise<TData>,\n retry: RetryValue<TError> = 0,\n retryDelay: RetryDelayValue<TError> = defaultRetryDelay,\n cancelRefetch = false,\n ): void {\n if (this.#subscription && !this.#subscription.closed) {\n // Already in-flight: dedupe unless the caller explicitly wants a fresh\n // fetch (e.g. invalidate/refetch) — then cancel the old one and restart.\n if (!cancelRefetch) return\n this.cancel()\n }\n\n this.#state.update((state) => ({\n ...state,\n isFetching: true,\n failureCount: 0,\n failureReason: null,\n }))\n\n // defer + from: normalize Observable/Promise and re-invoke queryFn on each\n // retry (a Promise is one-shot, so retry must produce a fresh one).\n this.#subscription = defer(() => from(queryFn()))\n .pipe(\n take(1),\n retryOperator({\n delay: (error, retryCount) => {\n // retryCount (1-based) is the number of failures so far; the retry\n // predicate/delay take a 0-based attempt index (0 = first retry).\n this.#state.update((state) => ({\n ...state,\n failureCount: retryCount,\n failureReason: error as TError,\n }))\n\n const attemptIndex = retryCount - 1\n\n if (!shouldRetry(retry, attemptIndex, error as TError)) throw error\n\n return timer(\n resolveRetryDelay(retryDelay, attemptIndex, error as TError),\n )\n },\n }),\n throwIfEmpty(\n () => new Error('Query function completed without emitting a value'),\n ),\n )\n .subscribe({\n next: (data) =>\n this.#state.set({\n data,\n status: 'success',\n error: null,\n isFetching: false,\n isInvalidated: false,\n failureCount: 0,\n failureReason: null,\n updatedAt: Date.now(),\n }),\n error: (err) =>\n this.#state.update((state) => ({\n ...state,\n status: 'error',\n error: err,\n isFetching: false,\n })),\n })\n }\n\n setData(data: TData, updatedAt: number = Date.now()): void {\n this.#state.update((state) => ({\n ...state,\n data,\n status: 'success',\n error: null,\n isInvalidated: false,\n failureCount: 0,\n failureReason: null,\n updatedAt,\n }))\n\n // Keep an orphaned query (no observers) alive for another gcTime so a\n // setQueryData write isn't collected before anyone subscribes.\n if (this.#observers.size === 0) this.#scheduleGc()\n }\n\n invalidate(): void {\n this.#state.update((state) => ({ ...state, isInvalidated: true }))\n }\n\n shouldFetch(staleTime: number): boolean {\n const state = this.state()\n\n return (\n state.status !== 'success' ||\n state.isInvalidated ||\n this.#isStale(staleTime)\n )\n }\n\n cancel(): void {\n this.#subscription?.unsubscribe()\n this.#subscription = null\n\n // The fetch is no longer running; clear the in-flight flag so isFetching\n // doesn't stay stuck true after a cancellation.\n if (this.state().isFetching) {\n this.#state.update((state) => ({ ...state, isFetching: false }))\n }\n }\n\n destroy(): void {\n this.cancel()\n this.#clearGcTimer()\n }\n\n // Inclusive: data fetched exactly `staleTime` ago is already stale. This\n // matters for seeded data (initialData is stamped with the current time), so\n // the default staleTime of 0 still means \"stale at once\" → background\n // refetch, rather than depending on whether a millisecond happened to pass.\n #isStale(staleTime: number): boolean {\n return Date.now() - this.state().updatedAt >= staleTime\n }\n\n #scheduleGc(): void {\n this.#clearGcTimer()\n\n this.#gcTimer = setTimeout(() => {\n this.#gcTimer = null\n this.#cache.remove(this)\n }, this.#gcTime)\n }\n\n #clearGcTimer(): void {\n if (this.#gcTimer === null) return\n\n clearTimeout(this.#gcTimer)\n this.#gcTimer = null\n }\n}\n","import { Injectable } from '@angular/core'\n\nimport { Cache } from './cache'\nimport { hashKey, partialMatchKey } from './utils'\nimport { Query } from './query'\nimport type { QueryFilters, QueryKey } from './types'\n\n/** @internal */\n@Injectable()\nexport class QueryCache extends Cache<Query<unknown, unknown>> {\n getOrCreate<TData, TError = Error>(key: QueryKey): Query<TData, TError> {\n const queryHash = hashKey(key)\n const exist = this.getEntry(queryHash)\n\n if (exist) return exist as Query<TData, TError>\n\n return this.addEntry(queryHash, new Query(key, queryHash, this)) as Query<\n TData,\n TError\n >\n }\n\n get<TData, TError = Error>(key: QueryKey): Query<TData, TError> | undefined {\n return this.getEntry(hashKey(key)) as Query<TData, TError> | undefined\n }\n\n /**\n * Like get(), but reactive, as findAll() is: a computed or an effect that\n * calls it re-runs when an entry is added or removed.\n */\n find<TData, TError = Error>(key: QueryKey): Query<TData, TError> | undefined {\n this.entries()\n\n return this.get<TData, TError>(key)\n }\n\n findAll(filters: QueryFilters = {}): Array<Query<unknown, unknown>> {\n const { queryKey, exact } = filters\n\n // Reads the reactive `entries()` so findAll() works inside computed().\n const all = this.entries()\n\n if (!queryKey) return all\n\n if (exact) {\n const queryHash = hashKey(queryKey)\n\n return all.filter((query) => query.queryHash === queryHash)\n }\n\n return all.filter((query) => partialMatchKey(query.key, queryKey))\n }\n\n // Generic: a query is invariant in TError (its observers' retry options take\n // the error as an argument), so a typed one isn't a Query<unknown, unknown>.\n remove<TData, TError>(query: Query<TData, TError>): void {\n // Guard on identity, not just the hash: a stale instance (already removed\n // and recreated under the same key) must not evict the current query.\n if (this.getEntry(query.queryHash) === query) {\n this.removeEntry(query.queryHash)\n }\n }\n\n override clear(): void {\n this.getAll().forEach((query) => query.destroy())\n super.clear()\n }\n}\n","import { type Signal, signal } from '@angular/core'\nimport {\n defer,\n from,\n retry as retryOperator,\n take,\n throwIfEmpty,\n timer,\n type Observable,\n type Subscription,\n} from 'rxjs'\n\nimport type { MutationCache } from './mutation-cache'\nimport { defaultRetryDelay, resolveRetryDelay, shouldRetry } from './retryer'\nimport type { RetryDelayValue, RetryValue } from './types'\n\n/** Lifecycle status of a mutation: not yet run, running, succeeded, or failed. */\nexport type MutationStatus = 'idle' | 'pending' | 'success' | 'error'\n\n/** Selects which mutations an operation applies to (e.g. `injectIsMutating`). */\nexport type MutationFilters = {\n /** Match mutations in this status. */\n status?: MutationStatus\n}\n\n/** Full state snapshot of a mutation (the reactive source behind {@link MutationResult}). */\nexport type MutationState<TData, TError, TVariables, TContext> = {\n /** Current {@link MutationStatus}. */\n status: MutationStatus\n /** Data resolved by the last successful run, or `undefined`. */\n data: TData | undefined\n /** Error of the last failed run, or `null`. */\n error: TError | null\n /** Variables passed to the most recent `mutate()` call. */\n variables: TVariables | undefined\n /** Value returned by `onMutate` for the current run. */\n context: TContext | undefined\n /** Number of failed attempts in the current run. */\n failureCount: number\n /** Error of the most recent failed attempt, or `null`. */\n failureReason: TError | null\n /** Timestamp (ms) when the current run was submitted; `0` if never. */\n submittedAt: number\n}\n\n/**\n * Configuration for a mutation, passed to {@link injectMutation} /\n * {@link mutationOptions}. The hooks fire in order: `onMutate` →\n * (`onSuccess` | `onError`) → `onSettled`. The value returned by `onMutate`\n * is passed as `context` to the later hooks — handy for rollback.\n */\nexport type MutationOptions<TData, TError, TVariables, TContext> = {\n /** Performs the write; receives `mutate()`'s argument. Returns `Observable`/`Promise`. */\n mutationFn: (variables: TVariables) => Observable<TData> | Promise<TData>\n /** Retry policy. Defaults to no retry (writes are not idempotent). */\n retry?: RetryValue<TError>\n /** Delay between retries. See {@link RetryDelayValue}. */\n retryDelay?: RetryDelayValue<TError>\n /** Runs before `mutationFn`; its return value becomes `context` (e.g. for optimistic rollback). */\n onMutate?: (variables: TVariables) => TContext | undefined\n /** Runs after a successful `mutationFn`. */\n onSuccess?: (\n data: TData,\n variables: TVariables,\n context: TContext | undefined,\n ) => void\n /** Runs after a failed `mutationFn`. */\n onError?: (\n error: TError,\n variables: TVariables,\n context: TContext | undefined,\n ) => void\n /** Runs after success or error — for cleanup that should happen either way. */\n onSettled?: (\n data: TData | undefined,\n error: TError | null,\n variables: TVariables,\n context: TContext | undefined,\n ) => void\n}\n\n/** Reactive result returned by {@link injectMutation}; state fields are signals. */\nexport type MutationResult<TData, TError, TVariables> = {\n /** Triggers the mutation with the given variables. */\n mutate: (variables: TVariables) => void\n /**\n * Resets the state to `idle`. It forgets the result and doesn't stop the\n * request: a run in flight finishes and fires its hooks.\n */\n reset: () => void\n /** Data from the last successful run, or `undefined`. */\n data: Signal<TData | undefined>\n /** Error from the last failed run, or `null`. */\n error: Signal<TError | null>\n /** Variables from the most recent `mutate()` call. */\n variables: Signal<TVariables | undefined>\n /** Current {@link MutationStatus}. */\n status: Signal<MutationStatus>\n /** Whether the mutation has not been run yet. */\n isIdle: Signal<boolean>\n /** Whether the mutation is currently running. */\n isPending: Signal<boolean>\n /** Whether the last run succeeded. */\n isSuccess: Signal<boolean>\n /** Whether the last run failed. */\n isError: Signal<boolean>\n /** Consecutive failures in the current run. */\n failureCount: Signal<number>\n /** Error of the most recent failed attempt, or `null`. */\n failureReason: Signal<TError | null>\n}\n\n/** @internal */\nexport function getInitialState<\n TData,\n TError,\n TVariables,\n TContext,\n>(): MutationState<TData, TError, TVariables, TContext> {\n return {\n status: 'idle',\n data: undefined,\n error: null,\n variables: undefined,\n context: undefined,\n failureCount: 0,\n failureReason: null,\n submittedAt: 0,\n }\n}\n\n/** @internal */\nexport class Mutation<\n TData = unknown,\n TError = Error,\n TVariables = void,\n TContext = unknown,\n> {\n readonly #state =\n signal<MutationState<TData, TError, TVariables, TContext>>(\n getInitialState(),\n )\n\n // `state` must follow `#state`: a public field can't precede the private\n // field it reads during initialization (field init order).\n // eslint-disable-next-line @typescript-eslint/member-ordering\n readonly state = this.#state.asReadonly()\n\n #subscription: Subscription | null = null\n #observers = 0\n readonly #options: MutationOptions<TData, TError, TVariables, TContext>\n readonly #cache: MutationCache\n\n constructor(\n readonly mutationId: number,\n options: MutationOptions<TData, TError, TVariables, TContext>,\n cache: MutationCache,\n ) {\n this.#options = options\n this.#cache = cache\n }\n\n get observerCount(): number {\n return this.#observers\n }\n\n addObserver(): void {\n this.#observers++\n }\n\n /**\n * Unlike a query, losing its last observer does not cancel a mutation: the\n * write has most likely reached the server already, so it must be allowed to\n * land and run its hooks. It is only dropped from the cache once it has both\n * settled and been abandoned — whichever of the two happens last.\n */\n removeObserver(): void {\n if (this.#observers === 0) return\n\n this.#observers--\n\n this.#disposeIfDone()\n }\n\n /** Runs the mutation once. `variables` are passed straight to `mutationFn`. */\n execute(variables: TVariables): void {\n const context = this.#options.onMutate?.(variables)\n // Mutations default to no retry (not idempotent — a retried POST could\n // create a duplicate); opt in explicitly via options.retry.\n const retry = this.#options.retry ?? 0\n const retryDelay = this.#options.retryDelay ?? defaultRetryDelay\n\n this.#state.set({\n status: 'pending',\n data: undefined,\n error: null,\n variables,\n context,\n failureCount: 0,\n failureReason: null,\n submittedAt: Date.now(),\n })\n\n // defer + from: normalize Observable/Promise and re-invoke mutationFn on\n // each retry (a Promise is one-shot, so retry must produce a fresh one).\n this.#subscription = defer(() => from(this.#options.mutationFn(variables)))\n .pipe(\n take(1),\n retryOperator({\n delay: (error, retryCount) => {\n this.#state.update((state) => ({\n ...state,\n failureCount: retryCount,\n failureReason: error as TError,\n }))\n\n const attemptIndex = retryCount - 1\n\n if (!shouldRetry(retry, attemptIndex, error as TError)) throw error\n\n return timer(\n resolveRetryDelay(retryDelay, attemptIndex, error as TError),\n )\n },\n }),\n throwIfEmpty(\n () =>\n new Error('Mutation function completed without emitting a value'),\n ),\n )\n .subscribe({\n // `finally`: a hook that throws must not leave the mutation stranded in\n // the cache (where injectIsMutating would keep counting it forever).\n next: (data) => {\n this.#state.update((state) => ({ ...state, status: 'success', data }))\n\n try {\n this.#options.onSuccess?.(data, variables, context)\n this.#options.onSettled?.(data, null, variables, context)\n } finally {\n this.#disposeIfDone()\n }\n },\n error: (error: TError) => {\n this.#state.update((state) => ({ ...state, status: 'error', error }))\n\n try {\n this.#options.onError?.(error, variables, context)\n this.#options.onSettled?.(undefined, error, variables, context)\n } finally {\n this.#disposeIfDone()\n }\n },\n })\n }\n\n cancel(): void {\n this.#subscription?.unsubscribe()\n this.#subscription = null\n }\n\n /**\n * A run nobody observes any more, and which is no longer in flight, has\n * nothing left to report — drop it. Called from both ends, since the two\n * conditions can be met in either order: a superseded run may settle later,\n * and a settled run may be abandoned later.\n */\n #disposeIfDone(): void {\n if (this.#observers > 0) return\n if (this.state().status === 'pending') return\n\n this.#cache.remove(this)\n }\n}\n","import { Injectable } from '@angular/core'\n\nimport { Cache } from './cache'\nimport {\n type MutationFilters,\n type MutationOptions,\n Mutation,\n} from './mutation'\n\n/** @internal */\n@Injectable()\nexport class MutationCache extends Cache<\n Mutation<unknown, unknown, unknown, unknown>\n> {\n #lastId = 0\n\n build<TData, TError, TVariables, TContext>(\n options: MutationOptions<TData, TError, TVariables, TContext>,\n ): Mutation<TData, TError, TVariables, TContext> {\n const mutation = new Mutation(++this.#lastId, options, this)\n\n this.addEntry(\n String(mutation.mutationId),\n mutation as Mutation<unknown, unknown, unknown, unknown>,\n )\n\n return mutation\n }\n\n findAll(\n filters: MutationFilters = {},\n ): Array<Mutation<unknown, unknown, unknown, unknown>> {\n // Reads the reactive `entries()` so findAll() works inside computed().\n const all = this.entries()\n\n if (!filters.status) return all\n\n return all.filter((mutation) => mutation.state().status === filters.status)\n }\n\n remove<TData, TError, TVariables, TContext>(\n mutation: Mutation<TData, TError, TVariables, TContext>,\n ): void {\n this.removeEntry(String(mutation.mutationId))\n }\n\n override clear(): void {\n this.getAll().forEach((mutation) => mutation.cancel())\n super.clear()\n }\n}\n","import { InjectionToken } from '@angular/core'\n\nimport type { RetryDelayValue, RetryValue } from './types'\n\n/** @internal */\nexport interface QueryClientConfig {\n defaultOptions?: {\n queries?: {\n staleTime?: number\n gcTime?: number\n retry?: RetryValue<unknown>\n retryDelay?: RetryDelayValue<unknown>\n }\n }\n}\n\n/** @internal */\nexport const QUERY_CLIENT_CONFIG = new InjectionToken<QueryClientConfig>(\n 'QUERY_CLIENT_CONFIG',\n)\n","import { inject, Injectable, untracked } from '@angular/core'\nimport type { Observable } from 'rxjs'\n\nimport { QueryCache } from './query-cache'\nimport { MutationCache } from './mutation-cache'\nimport { defaultRetryDelay } from './retryer'\nimport { functionalUpdate } from './utils'\nimport type {\n DefaultedQueryOptions,\n QueryFilters,\n QueryKey,\n QueryOptions,\n RetryDelayValue,\n RetryValue,\n Updater,\n} from './types'\nimport { QUERY_CLIENT_CONFIG } from './injection-tokens'\n\n/**\n * Central registry and cache for queries and mutations.\n *\n * Provided by {@link provideQueryClient} and retrieved with\n * {@link injectQueryClient}. Offers imperative cache access — reading and\n * writing data, and invalidating, cancelling, or removing queries — that\n * complements the reactive {@link injectQuery} / {@link injectMutation} APIs.\n *\n * Its methods aren't reactive. Called from an effect, a method doesn't make\n * the effect depend on the cache, on a query's state, or on what `queryFn` or\n * an updater reads: the effect re-runs only when what it reads itself\n * changes. A read is a snapshot, in a template or a `computed` too; for state\n * that updates, use {@link injectQuery}, {@link injectIsFetching} and\n * {@link injectIsMutating}.\n */\n@Injectable()\nexport class QueryClient {\n // Every method that reads or writes the cache runs its body untracked. A\n // call made from an effect mustn't make the effect depend on what the\n // method reads to do its job: the cache, a query's state, or what queryFn\n // or an updater reads. Otherwise a change to any of them re-runs the effect,\n // and the effect repeats the call.\n readonly #cache = inject(QueryCache)\n readonly #mutationCache = inject(MutationCache)\n readonly #config = inject(QUERY_CLIENT_CONFIG, { optional: true }) ?? {}\n\n /** Returns the underlying query cache. Advanced/internal use. */\n getQueryCache(): QueryCache {\n return this.#cache\n }\n\n /** Returns the underlying mutation cache. Advanced/internal use. */\n getMutationCache(): MutationCache {\n return this.#mutationCache\n }\n\n /**\n * Merges per-query options with the configured defaults, filling in\n * `staleTime`, `gcTime`, `retry`, and `retryDelay`. Used internally by\n * {@link injectQuery}.\n */\n defaultQueryOptions<TData, TError = Error>(\n options: QueryOptions<TData, TError>,\n ): DefaultedQueryOptions<TData, TError> {\n const defaults = this.#config.defaultOptions?.queries\n\n return {\n ...options,\n staleTime: options.staleTime ?? defaults?.staleTime ?? 0,\n gcTime: options.gcTime ?? defaults?.gcTime,\n retry: options.retry ?? defaults?.retry ?? 3,\n retryDelay:\n options.retryDelay ?? defaults?.retryDelay ?? defaultRetryDelay,\n }\n }\n\n /**\n * Imperatively fetches and caches a query, unless fresh data already exists\n * (governed by `staleTime`). Prefer {@link injectQuery} in components; use\n * this to prefetch, from an event handler or an effect.\n *\n * @param key - The query key to fetch and cache under.\n * @param queryFn - Function returning the data as an `Observable` or `Promise`.\n * @param options - Fetch tuning (`staleTime`, `retry`, `retryDelay`,\n * `cancelRefetch`).\n */\n fetchQuery<TData>(\n key: QueryKey,\n queryFn: () => Observable<TData> | Promise<TData>,\n options: {\n staleTime?: number\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n retry?: RetryValue<any>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n retryDelay?: RetryDelayValue<any>\n cancelRefetch?: boolean\n } = {},\n ): void {\n untracked(() => {\n const defaults = this.#config.defaultOptions?.queries\n const staleTime = options.staleTime ?? defaults?.staleTime ?? 0\n const retry = options.retry ?? defaults?.retry ?? 3\n const retryDelay =\n options.retryDelay ?? defaults?.retryDelay ?? defaultRetryDelay\n\n const query = this.#cache.getOrCreate<TData>(key)\n\n if (query.shouldFetch(staleTime)) {\n query.fetch(queryFn, retry, retryDelay, options.cancelRefetch)\n }\n })\n }\n\n /**\n * Reads the current cached data for a query key, or `undefined` if the query\n * is not cached yet. A snapshot: it doesn't update a template, a `computed`\n * or an effect when the data changes. For data that updates, use\n * {@link injectQuery}.\n *\n * @param key - The query key to read.\n * @returns The cached data, or `undefined`.\n */\n getQueryData<TData>(key: QueryKey): TData | undefined {\n return untracked(() => this.#cache.get<TData>(key)?.state().data)\n }\n\n /**\n * Writes data into the cache for a query key, creating the entry if needed.\n * The `updater` may be a value or a function of the previous data; returning\n * `undefined` from the function is a no-op. Useful for optimistic updates.\n *\n * @param key - The query key to write.\n * @param updater - The new data, or a function `(prev) => next`.\n *\n * @example\n * ```ts\n * client.setQueryData<Todo[]>(['todos'], (prev = []) => [...prev, newTodo])\n * ```\n */\n setQueryData<TData>(\n key: QueryKey,\n updater: Updater<TData | undefined, TData>,\n ): void {\n untracked(() => {\n const query = this.#cache.getOrCreate<TData>(key)\n const data = functionalUpdate(updater, query.state().data)\n\n // Matches TanStack: an updater returning undefined is a no-op.\n if (data === undefined) return\n\n query.setData(data)\n })\n }\n\n /**\n * Marks matching queries as stale and refetches the actively observed ones,\n * once per query however many components observe it. The refetch starts\n * right away and replaces a fetch already in flight, which may predate the\n * change; this method doesn't wait for it. A query with no enabled observer\n * keeps the stale mark and refetches as soon as one appears. Commonly called\n * after a mutation succeeds.\n *\n * @param filters - Which queries to invalidate; omit to invalidate all.\n *\n * @example\n * ```ts\n * client.invalidateQueries({ queryKey: ['todos'] })\n * ```\n */\n invalidateQueries(filters?: QueryFilters): void {\n untracked(() => {\n const queries = this.#cache.findAll(filters)\n\n queries.forEach((query) => query.invalidate())\n\n // Refetch each active query once, however many observers watch it; an\n // inactive one refetches when next observed, as shouldFetch sees the\n // flag. cancelRefetch: a fetch already in flight started before the\n // invalidation, so it may have missed the change.\n queries.forEach((query) => {\n const options = query.activeFetchOptions()\n\n if (options) {\n query.fetch(options.queryFn, options.retry, options.retryDelay, true)\n }\n })\n })\n }\n\n /**\n * Cancels any in-flight fetches for matching queries.\n *\n * @param filters - Which queries to cancel; omit to cancel all.\n */\n cancelQueries(filters?: QueryFilters): void {\n untracked(() =>\n this.#cache.findAll(filters).forEach((query) => query.cancel()),\n )\n }\n\n /**\n * Removes matching queries from the cache entirely, discarding their data\n * and cancelling their fetches. Nothing is refetched: a component still\n * showing a removed key keeps what it shows until something puts the key\n * back in the cache (a write, a refetch, another component, its own\n * polling), then shows what the cache holds, as after a key change.\n *\n * @param filters - Which queries to remove; omit to remove all.\n */\n removeQueries(filters?: QueryFilters): void {\n untracked(() =>\n this.#cache.findAll(filters).forEach((query) => {\n query.destroy()\n this.#cache.remove(query)\n }),\n )\n }\n\n /**\n * Returns the number of matching queries currently fetching. A snapshot: it\n * doesn't update a template, a `computed` or an effect. For a count that\n * updates, use {@link injectIsFetching}.\n *\n * @param filters - Which queries to count; omit to count all.\n */\n isFetching(filters?: QueryFilters): number {\n return untracked(() => {\n const fetching = this.#cache\n .findAll(filters)\n .filter((query) => query.state().isFetching)\n\n return fetching.length\n })\n }\n\n /**\n * Returns the number of mutations currently pending. A snapshot: it doesn't\n * update a template, a `computed` or an effect. For a count that updates,\n * use {@link injectIsMutating}.\n */\n isMutating(): number {\n return untracked(\n () => this.#mutationCache.findAll({ status: 'pending' }).length,\n )\n }\n}\n","import type { Provider } from '@angular/core'\n\n/**\n * Discriminator identifying each kind of {@link QueryClientFeature}.\n *\n * @internal\n */\nexport enum QueryClientFeatureKind {\n DefaultOptions,\n}\n\n/**\n * An opaque feature passed to {@link provideQueryClient}. Create one with a\n * `with*` helper such as {@link withDefaultOptions} rather than constructing it\n * directly; the `ɵ`-prefixed members are internal.\n */\nexport interface QueryClientFeature<\n K extends QueryClientFeatureKind = QueryClientFeatureKind,\n> {\n ɵkind: K\n ɵproviders: Provider[]\n}\n\n/** @internal */\nexport function queryClientFeature<K extends QueryClientFeatureKind>(\n kind: K,\n providers: Provider[],\n): QueryClientFeature<K> {\n return { ɵkind: kind, ɵproviders: providers }\n}\n","import {\n type EnvironmentProviders,\n makeEnvironmentProviders,\n} from '@angular/core'\n\nimport { QueryClient } from './query-client'\nimport { QueryCache } from './query-cache'\nimport { MutationCache } from './mutation-cache'\nimport {\n type QueryClientFeature,\n QueryClientFeatureKind,\n} from '../features/feature'\n\n/**\n * Registers the {@link QueryClient} and its caches for the application.\n *\n * Call once at the app root (in `ApplicationConfig.providers` or a root\n * `bootstrapApplication`). Pass features such as {@link withDefaultOptions} to\n * configure defaults. Registering the same feature twice throws.\n *\n * @param features - Optional {@link QueryClientFeature}s (e.g.\n * {@link withDefaultOptions}).\n * @returns Environment providers to add to the app's provider list.\n *\n * @example\n * ```ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(),\n * provideQueryClient(\n * withDefaultOptions({ queries: { staleTime: 30_000 } }),\n * ),\n * ],\n * }\n * ```\n */\nexport function provideQueryClient(\n ...features: QueryClientFeature[]\n): EnvironmentProviders {\n const seenKinds = new Set<QueryClientFeatureKind>()\n\n for (const feature of features) {\n if (seenKinds.has(feature.ɵkind)) {\n throw new Error(\n `provideQueryClient: feature \"${QueryClientFeatureKind[feature.ɵkind]}\" is registered more than once`,\n )\n }\n seenKinds.add(feature.ɵkind)\n }\n\n return makeEnvironmentProviders([\n QueryCache,\n MutationCache,\n QueryClient,\n ...features.flatMap((feature) => feature.ɵproviders),\n ])\n}\n","import { type Injector, assertInInjectionContext, inject } from '@angular/core'\n\nimport { QueryClient } from './query-client'\n\n/**\n * Returns the application's {@link QueryClient} for imperative cache access.\n *\n * Use it to read or write cached data (`getQueryData`, `setQueryData`) and to\n * invalidate, cancel, or remove queries — typically from mutation hooks or\n * event handlers. Requires {@link provideQueryClient} to be registered.\n *\n * Must run in an injection context, or be given an explicit `injector`.\n *\n * @param options - Optional `injector` to use outside an injection context.\n * @returns The shared {@link QueryClient} instance.\n *\n * @example\n * ```ts\n * const client = injectQueryClient()\n * client.setQueryData<Todo[]>(['todos'], (prev = []) => [...prev, newTodo])\n * client.invalidateQueries({ queryKey: ['todos'] })\n * ```\n */\nexport function injectQueryClient(options?: {\n injector?: Injector\n}): QueryClient {\n if (!options?.injector) assertInInjectionContext(injectQueryClient)\n\n return options?.injector?.get(QueryClient) ?? inject(QueryClient)\n}\n","/**\n * Calls `poll` every `ms`, but never sooner than `ms` after `updatedAt()`:\n * when the timer comes due earlier, it waits out the rest of the interval\n * from then. Returns a function that stops polling.\n *\n * @internal\n */\nexport function startPolling(\n ms: number,\n updatedAt: () => number,\n poll: () => void,\n): () => void {\n let timer: ReturnType<typeof setTimeout>\n\n const wait = (delay: number): void => {\n timer = setTimeout(() => {\n const elapsed = Date.now() - updatedAt()\n\n if (elapsed < ms) {\n wait(ms - elapsed)\n\n return\n }\n\n poll()\n wait(ms)\n }, delay)\n }\n\n wait(ms)\n\n return () => clearTimeout(timer)\n}\n","import {\n type EffectCleanupRegisterFn,\n type EffectRef,\n type Injector,\n computed,\n effect,\n signal,\n untracked,\n} from '@angular/core'\n\nimport { startPolling } from './polling'\nimport { QueryClient } from './query-client'\nimport type { Query, QuerySubscriber } from './query'\nimport type {\n PlaceholderDataFunction,\n QueryKey,\n QueryOptions,\n QueryResult,\n QueryStatus,\n} from './types'\nimport { hashKey, isValidTimeout } from './utils'\n\n/**\n * One observed query: its reactive {@link QueryResult} and a `destroy()` that\n * ends the observation (drops the cache observer, stops polling).\n *\n * @internal\n */\nexport interface QueryObserver<TData, TError = Error> {\n result: QueryResult<TData, TError>\n destroy: () => void\n}\n\n/**\n * Observes a single query and exposes its state as signals — the engine behind\n * {@link injectQuery} and {@link injectQueries}.\n *\n * Nothing is evaluated on creation: `optionsFn` is first called by the first\n * effect run or the first read of a result signal, so it may depend on state\n * that isn't ready while the owner is being constructed (inputs, fields\n * declared later).\n *\n * Effects are created on `injector` with `manualCleanup` so the observer can be\n * torn down on its own via `destroy()`, independently of the injector's\n * lifetime (a component may drop one query out of many). In a component\n * injector they run as view effects, elsewhere as root effects — the same as\n * `effect()` called directly in that context.\n *\n * @internal\n */\nexport function createQueryObserver<TData, TError = Error>(\n optionsFn: () => QueryOptions<TData, TError>,\n injector: Injector,\n): QueryObserver<TData, TError> {\n const client = injector.get(QueryClient)\n const cache = client.getQueryCache()\n\n // Every effect is registered here so destroy() covers all of them.\n const refs: EffectRef[] = []\n const track = (fn: (onCleanup: EffectCleanupRegisterFn) => void): void => {\n refs.push(effect(fn, { injector, manualCleanup: true }))\n }\n\n // Single source of truth for defaulted options; resolves config defaults\n // (staleTime, gcTime) once instead of scattering the logic across effects.\n const defaultedOptions = computed(() =>\n client.defaultQueryOptions(optionsFn()),\n )\n\n // Seed a fresh query (status 'pending', no data yet) with initialData so\n // it renders immediately as 'success'. Without an explicit\n // initialDataUpdatedAt the seed is treated as fetched right now, so\n // staleTime applies to it as it would to any other data (a staleTime of 0\n // still means \"stale immediately\" → background refetch).\n const applyInitialData = (q: Query<TData, TError>): void => {\n const { initialData, initialDataUpdatedAt } = untracked(defaultedOptions)\n\n if (initialData === undefined || q.state().status !== 'pending') return\n\n const data =\n typeof initialData === 'function'\n ? (initialData as () => TData)()\n : initialData\n const updatedAt =\n typeof initialDataUpdatedAt === 'function'\n ? initialDataUpdatedAt()\n : (initialDataUpdatedAt ?? Date.now())\n\n q.setData(data, updatedAt)\n }\n\n // Resolves the query for a key, seeding a fresh one with initialData. It\n // writes signals (the cache's entries, the query's state), so callers run it\n // untracked: reached from a computed, a tracked write throws NG0600.\n const resolve = (key: QueryKey): Query<TData, TError> => {\n const q = cache.getOrCreate<TData, TError>(key)\n\n applyInitialData(q)\n\n return q\n }\n\n // The query the observer last switched to, by the key effect or the follow\n // effect below; unset until the key effect first runs.\n const switched = signal<Query<TData, TError> | undefined>(undefined)\n\n // The observed query, resolved lazily: on the first read of a result signal\n // or the first effect run, whichever comes first. Resolving it calls\n // optionsFn, which may read inputs or fields that don't exist yet while the\n // owner is being constructed. A read before the key effect's first run\n // resolves the current key on the spot, so it already sees cached data and\n // initialData; from then on the key and follow effects switch queries.\n const query = computed(\n () => switched() ?? untracked(() => resolve(defaultedOptions().queryKey)),\n )\n\n // Data of the last query that had any, fed to the placeholderData function\n // on a switch: a key change, or the key coming back after a removal\n // (mirrors TanStack's lastQueryWithDefinedData). Captured synchronously\n // before the switch so it can't miss a just-resolved value.\n const lastData = signal<TData | undefined>(undefined)\n\n // Switches the observer to q, first keeping the data of the query it\n // leaves for the placeholderData function.\n const switchTo = (q: Query<TData, TError>): void => {\n untracked(() => {\n const prev = switched()\n\n if (prev && prev !== q && prev.state().data !== undefined) {\n lastData.set(prev.state().data)\n }\n })\n switched.set(q)\n }\n\n track(() => {\n const key = defaultedOptions().queryKey\n\n switchTo(untracked(() => resolve(key)))\n })\n\n // The query cached under the key right now, read reactively: undefined once\n // removeQueries drops it, and the new entry once something brings the key\n // back.\n const cached = computed(() =>\n cache.find<TData, TError>(defaultedOptions().queryKey),\n )\n\n // After removeQueries the observer keeps the query the cache dropped and\n // shows what it had: nothing here brings the key back, as in TanStack, where\n // a removal doesn't refetch. Whatever does bring it back (a write, a refetch,\n // another component, a poll), the observer follows it there as on a key\n // change: resolve() seeds initialData into an entry still pending. Without\n // this, it would see the new entry only once its options change.\n track(() => {\n const entry = cached()\n\n if (!entry || entry === untracked(switched)) return\n\n switchTo(untracked(() => resolve(entry.key)))\n })\n\n // How this observer would fetch q right now, from the live options; null\n // while it is disabled, or once the key has moved on. Before the key effect\n // above catches up, queryFn already fetches the next query's data, so q\n // must not be fetched with it. Both refetches made on our behalf go by it:\n // the invalidation one (through q's subscriber handle) and polling.\n const fetchOptionsFor = (\n q: Query<TData, TError>,\n ): ReturnType<QuerySubscriber<TData, TError>['fetchOptions']> => {\n const { queryKey, queryFn, retry, retryDelay, enabled } =\n untracked(defaultedOptions)\n\n if (enabled === false || hashKey(queryKey) !== q.queryHash) {\n return null\n }\n\n return { queryFn, retry, retryDelay }\n }\n\n track((cleanup) => {\n const q = query()\n const { gcTime } = untracked(defaultedOptions)\n\n if (gcTime !== undefined) {\n q.setGcTime(gcTime)\n }\n\n // This observer as q sees it.\n const subscriber: QuerySubscriber<TData, TError> = {\n fetchOptions: () => fetchOptionsFor(q),\n }\n\n q.addObserver(subscriber)\n cleanup(() => q.removeObserver(subscriber))\n })\n\n // Memoized so options re-evaluations that leave the flag alone don't wake\n // the fetch and polling effects.\n const enabled = computed(() => defaultedOptions().enabled !== false)\n\n // Fetch when the observed query switches (key change) or when it becomes\n // enabled — not on every re-evaluation of the options. defaultQueryOptions()\n // builds a fresh object each time, so tracking it whole would refetch stale\n // data whenever any signal read in optionsFn changes, even one unrelated to\n // the key. queryFn, staleTime and the retry policy only parameterise the\n // fetch and are read untracked (TanStack's shouldFetchOptionally).\n // Invalidation isn't a trigger: invalidateQueries() refetches each active\n // query once itself. A query it skipped (unobserved, or its observers\n // disabled) stays invalidated, so it fetches here once observed or enabled:\n // shouldFetch sees the flag.\n track(() => {\n query()\n\n if (!enabled()) return\n\n const { queryKey, queryFn, staleTime, retry, retryDelay } =\n untracked(defaultedOptions)\n\n untracked(() =>\n client.fetchQuery(queryKey, queryFn, { staleTime, retry, retryDelay }),\n )\n })\n\n // The polling interval this observer asks for, or false for none. Memoized,\n // so the polling effect wakes only when the value changes. The function form\n // is resolved against the query's state, so it is re-resolved on every\n // update of it, and a switch to false stops polling. 0 means no polling, and\n // so does a value no timer can hold: the timer would fire over and over.\n const interval = computed(() => {\n const { refetchInterval } = defaultedOptions()\n const value =\n typeof refetchInterval === 'function'\n ? refetchInterval({ state: query().state() })\n : refetchInterval\n\n return isValidTimeout(value) && value > 0 ? value : false\n })\n\n // Polling: refetch on an interval, independent of staleTime. The timer\n // restarts when the observed query switches, or when enabled or the interval\n // changes, as in TanStack's setOptions. It doesn't restart on every\n // re-evaluation of the options: defaultQueryOptions() builds a fresh object\n // each time, so tracking it whole would restart the timer whenever any\n // signal read in optionsFn changes. One that changes faster than the\n // interval would keep it from ever firing.\n //\n // Each poll comes ms after the query's last update, as in TanStack, whose\n // observer restarts its timer on every update of the query. So a fetch made\n // for any reason (another observer's poll, refetch(), an invalidation) or a\n // cache write pushes the next poll back. However many observers poll a key,\n // it's fetched once per interval. Unlike TanStack, the wait counts from\n // updatedAt, the last response or cache write, not from any change of\n // state: a fetch that starts or fails doesn't push it back.\n track((onCleanup) => {\n const q = query()\n\n if (!enabled()) return\n\n const ms = interval()\n\n if (!ms) return\n\n // Fetches the key with the options as they are when it fires, which may\n // have changed since the effect ran. The key's entry is q, unless\n // removeQueries dropped it: then the poll puts the key back, as TanStack's\n // observer does before every fetch, and the follow effect moves this\n // observer there.\n const poll = (): void => {\n const options = fetchOptionsFor(q)\n\n if (options) {\n resolve(q.key).fetch(options.queryFn, options.retry, options.retryDelay)\n }\n }\n\n onCleanup(startPolling(ms, () => q.state().updatedAt, poll))\n })\n\n // Placeholder layer: while the query is pending with no data, present\n // placeholderData as already-successful data. Purely presentational — the\n // cache entry stays 'pending' and the fetch proceeds, so isFetching keeps\n // reporting the real request and the placeholder is dropped on resolve.\n const resolved = computed<{\n data: TData | undefined\n status: QueryStatus\n isPlaceholderData: boolean\n }>(() => {\n const state = query().state()\n const { placeholderData } = defaultedOptions()\n\n if (\n placeholderData !== undefined &&\n state.data === undefined &&\n state.status === 'pending'\n ) {\n const data =\n typeof placeholderData === 'function'\n ? (placeholderData as PlaceholderDataFunction<TData>)(lastData())\n : placeholderData\n\n if (data !== undefined) {\n return { data, status: 'success', isPlaceholderData: true }\n }\n }\n\n return { data: state.data, status: state.status, isPlaceholderData: false }\n })\n\n return {\n result: {\n data: computed(() => resolved().data),\n status: computed(() => resolved().status),\n error: computed(() => query().state().error as TError | null),\n isFetching: computed(() => query().state().isFetching),\n // First fetch in-flight: fetching with no resolved data yet. An active\n // placeholder counts as data — the UI shows it, not a loading state.\n isLoading: computed(\n () => query().state().isFetching && resolved().status === 'pending',\n ),\n isPending: computed(() => resolved().status === 'pending'),\n isSuccess: computed(() => resolved().status === 'success'),\n isError: computed(() => resolved().status === 'error'),\n isPlaceholderData: computed(() => resolved().isPlaceholderData),\n failureCount: computed(() => query().state().failureCount),\n failureReason: computed(\n () => query().state().failureReason as TError | null,\n ),\n // Force a fresh fetch regardless of staleTime, cancelling any in-flight\n // request (explicit user intent — get current data).\n refetch: () => {\n const { queryKey, queryFn, retry, retryDelay } =\n untracked(defaultedOptions)\n\n client.fetchQuery(queryKey, queryFn, {\n staleTime: 0,\n retry,\n retryDelay,\n cancelRefetch: true,\n })\n },\n },\n destroy: () => refs.forEach((ref) => ref.destroy()),\n }\n}\n","import {\n assertInInjectionContext,\n DestroyRef,\n inject,\n Injector,\n} from '@angular/core'\n\nimport { createQueryObserver } from './query-observer'\nimport type { QueryOptions, QueryResult } from './types'\n\n/**\n * Runs a cached, reactive query and exposes its state as signals.\n *\n * The query is keyed by `queryKey`: calls with the same key share a single\n * cache entry and in-flight request (deduplication). `optionsFn` is read in a\n * reactive context, so when a value it depends on changes (e.g. a route or\n * input signal in the key), the query automatically switches to the new key\n * and fetches. `optionsFn` isn't called before the query is first needed (its\n * first effect run or the first read of a result signal), so it can read\n * inputs, `input.required` included, and fields declared after the query. The\n * query is bound to the current injection context and cleans up its cache\n * observer when that context is destroyed.\n *\n * Must run in an injection context, or be given an explicit `injector`.\n *\n * @typeParam TData - Type of the data resolved by `queryFn`.\n * @typeParam TError - Type of the error thrown by `queryFn`.\n * @param optionsFn - Factory returning the {@link QueryOptions}. Re-evaluated\n * reactively: a new `queryKey` switches to that query and fetches it, and\n * turning `enabled` on starts the fetch. Re-evaluating with the same key\n * does not refetch, so every value `queryFn` reads belongs in the key.\n * @param options - Optional `injector` to use outside an injection context.\n * @returns A {@link QueryResult} of signals (`data`, `status`, `error`,\n * `isLoading`, `isPending`, …) plus a `refetch()` that forces a fresh fetch.\n *\n * @example\n * ```ts\n * @Component({\n * template: `\n * @if (todo.isPending()) { <p>Loading…</p> }\n * @if (todo.data(); as data) { <p>{{ data.title }}</p> }\n * `,\n * })\n * class TodoComponent {\n * readonly id = input.required<number>()\n * private readonly http = inject(HttpClient)\n *\n * // Refetches automatically whenever `id()` changes.\n * readonly todo = injectQuery(() => ({\n * queryKey: ['todo', this.id()],\n * queryFn: () => this.http.get<Todo>(`/api/todos/${this.id()}`),\n * }))\n * }\n * ```\n */\nexport function injectQuery<TData, TError = Error>(\n optionsFn: () => QueryOptions<TData, TError>,\n options?: { injector?: Injector },\n): QueryResult<TData, TError> {\n if (!options?.injector) assertInInjectionContext(injectQuery)\n\n const injector = options?.injector ?? inject(Injector)\n const { result, destroy } = createQueryObserver(optionsFn, injector)\n\n // The observation lives as long as the owning context (component or\n // injector): tear it down with it.\n injector.get(DestroyRef).onDestroy(destroy)\n\n return result\n}\n","import {\n type Signal,\n type WritableSignal,\n assertInInjectionContext,\n computed,\n DestroyRef,\n effect,\n inject,\n Injector,\n signal,\n untracked,\n} from '@angular/core'\n\nimport { type QueryObserver, createQueryObserver } from './query-observer'\nimport type { QueryOptions, QueryResult } from './types'\nimport { hashKey } from './utils'\n\n/** Options for {@link injectQueries}. */\nexport interface InjectQueriesOptions<TData, TError = Error> {\n /**\n * One {@link QueryOptions} per query to run. The array may change between\n * evaluations: queries are matched to the previous set by `queryKey`, so a\n * new key starts a query and a missing key ends one.\n */\n queries: Array<QueryOptions<TData, TError>>\n}\n\n// A query kept alive by injectQueries: its observer plus the signal feeding it\n// options, written in place for as long as the key stays in the list.\ninterface Entry<TData, TError> {\n hash: string\n options: WritableSignal<QueryOptions<TData, TError>>\n observer: QueryObserver<TData, TError>\n}\n\n/**\n * Runs a dynamic number of queries in parallel and exposes their results as a\n * signal holding one {@link QueryResult} per entry of `queries`, in order.\n *\n * Reach for it when the set of queries depends on data — one query per id in\n * a list, say — where {@link injectQuery} can't be called in a loop. Each\n * query behaves exactly like a standalone `injectQuery`: its own cache entry,\n * `staleTime`, retries, error and observer. `optionsFn` is reactive: when the\n * array changes, queries whose `queryKey` is still present are kept (with\n * their options updated), new keys start fetching, and dropped keys release\n * their observer. As with `injectQuery`, `optionsFn` isn't called before the\n * results are first needed, so it can read inputs, `input.required` included,\n * and fields declared after the call. Aggregate across the results with\n * `computed`.\n *\n * Must run in an injection context, or be given an explicit `injector`.\n *\n * @typeParam TData - Type of the data resolved by each `queryFn`.\n * @typeParam TError - Type of the error thrown by each `queryFn`.\n * @param optionsFn - Factory returning the {@link InjectQueriesOptions}.\n * Re-evaluated reactively, so reading signals inside it re-syncs the set.\n * @param options - Optional `injector` to use outside an injection context.\n * @returns A signal of {@link QueryResult}s, one per query. The array identity\n * changes only when the set of queries changes, not on every data update.\n *\n * @example\n * ```ts\n * class TodoListComponent {\n * readonly #queries = inject(TodoQueries)\n *\n * readonly todoIds = input.required<number[]>()\n *\n * readonly todos = injectQueries(() => ({\n * queries: this.todoIds().map((id) => this.#queries.detail(id)),\n * }))\n *\n * readonly isPending = computed(() =>\n * this.todos().some((todo) => todo.isPending()),\n * )\n * }\n * ```\n */\nexport function injectQueries<TData, TError = Error>(\n optionsFn: () => InjectQueriesOptions<TData, TError>,\n options?: { injector?: Injector },\n): Signal<Array<QueryResult<TData, TError>>> {\n if (!options?.injector) assertInInjectionContext(injectQueries)\n\n const injector = options?.injector ?? inject(Injector)\n\n let entries: Array<Entry<TData, TError>> = []\n let current: Array<QueryResult<TData, TError>> = []\n let destroyed = false\n\n // Reconciles the entries with a new list, matching by key hash the way\n // TanStack's QueriesObserver does: a matching entry is reused and handed the\n // new options, an unmatched query gets a fresh observer, and whatever is\n // left over is destroyed. Duplicate keys are paired up one-to-one in order.\n const sync = (\n queries: Array<QueryOptions<TData, TError>>,\n ): Array<QueryResult<TData, TError>> => {\n const pool = new Map<string, Array<Entry<TData, TError>>>()\n\n for (const entry of entries) {\n const list = pool.get(entry.hash) ?? []\n\n list.push(entry)\n pool.set(entry.hash, list)\n }\n\n const next = queries.map((queryOptions) => {\n const hash = hashKey(queryOptions.queryKey)\n const match = pool.get(hash)?.shift()\n\n if (match) {\n match.options.set(queryOptions)\n\n return match\n }\n\n const optionsSignal = signal(queryOptions)\n\n return {\n hash,\n options: optionsSignal,\n observer: createQueryObserver(() => optionsSignal(), injector),\n }\n })\n\n for (const leftovers of pool.values()) {\n leftovers.forEach((entry) => entry.observer.destroy())\n }\n\n // Replace the result array only on a structural change, so a computed\n // over it doesn't recompute when merely the options were refreshed.\n const changed =\n next.length !== entries.length ||\n next.some((entry, index) => entry !== entries[index])\n\n entries = next\n\n if (changed) current = entries.map((entry) => entry.observer.result)\n\n return current\n }\n\n // The results of the effect's latest sync; unset until its first run.\n const synced = signal<Array<QueryResult<TData, TError>> | undefined>(\n undefined,\n )\n\n effect(\n () => {\n const { queries } = optionsFn()\n\n untracked(() => synced.set(sync(queries)))\n },\n { injector },\n )\n\n injector.get(DestroyRef).onDestroy(() => {\n destroyed = true\n entries.forEach((entry) => entry.observer.destroy())\n })\n\n // Nothing is synced until first needed: on the first read or the effect's\n // first run, whichever comes first. Syncing calls optionsFn, which may read\n // inputs or fields that don't exist yet while the owner is being\n // constructed. A read before the effect's first run syncs on the spot, so\n // it already sees the queries; once destroyed, it creates nothing.\n return computed(\n () =>\n synced() ?? (destroyed ? [] : untracked(() => sync(optionsFn().queries))),\n )\n}\n","import {\n assertInInjectionContext,\n computed,\n DestroyRef,\n inject,\n Injector,\n runInInjectionContext,\n signal,\n untracked,\n} from '@angular/core'\n\nimport { QueryClient } from './query-client'\nimport {\n type Mutation,\n type MutationOptions,\n type MutationResult,\n getInitialState,\n} from './mutation'\n\n/**\n * Creates a mutation for imperative writes (create/update/delete) and exposes\n * its state as signals.\n *\n * Unlike queries, a mutation does not run on its own — call `mutate(variables)`\n * to trigger `mutationFn`. The `onMutate` / `onSuccess` / `onError` /\n * `onSettled` lifecycle hooks make optimistic updates and cache invalidation\n * straightforward. Mutations do not retry by default (a retried write is not\n * idempotent); opt in via `options.retry`. `mutate()` and `reset()` are safe\n * to call from an effect: neither makes the effect depend on what it reads,\n * such as the options or the previous run. Bound to the current injection\n * context. Destroying it doesn't cancel a run in flight: the write has most\n * likely reached the server, so the run finishes and fires its hooks.\n *\n * Must run in an injection context, or be given an explicit `injector`.\n *\n * @typeParam TData - Type of the data resolved by `mutationFn`.\n * @typeParam TError - Type of the error thrown by `mutationFn`.\n * @typeParam TVariables - Type of the argument passed to `mutate()`.\n * @typeParam TContext - Type returned by `onMutate`, passed to later hooks.\n * @param optionsFn - Factory returning the {@link MutationOptions}.\n * @param options - Optional `injector` to use outside an injection context.\n * @returns A {@link MutationResult}: `mutate()`, `reset()`, and state signals\n * (`status`, `data`, `error`, `isPending`, …).\n *\n * @example\n * ```ts\n * const client = injectQueryClient()\n *\n * const addTodo = injectMutation(() => ({\n * mutationFn: (title: string) => http.post<Todo>('/api/todos', { title }),\n * onSuccess: () => client.invalidateQueries({ queryKey: ['todos'] }),\n * }))\n *\n * // <button (click)=\"addTodo.mutate('Buy milk')\" [disabled]=\"addTodo.isPending()\">Add</button>\n * ```\n */\nexport function injectMutation<\n TData,\n TError = Error,\n TVariables = void,\n TContext = unknown,\n>(\n optionsFn: () => MutationOptions<TData, TError, TVariables, TContext>,\n options?: { injector?: Injector },\n): MutationResult<TData, TError, TVariables> {\n if (!options?.injector) assertInInjectionContext(injectMutation)\n\n const injector = options?.injector ?? inject(Injector)\n\n return runInInjectionContext(injector, () => {\n const cache = inject(QueryClient).getMutationCache()\n\n // Every mutate() builds its own Mutation. Sharing one across calls meant a\n // second call overwrote the first's subscription (orphaning the request)\n // and its state (so the slower run, not the latest one, decided the result).\n const current = signal<Mutation<\n TData,\n TError,\n TVariables,\n TContext\n > | null>(null)\n\n // Detaching is all we do on destroy. A run still in flight keeps going —\n // the write has most likely reached the server already, so cancelling it\n // would only skip onSuccess and leave the cache out of sync. It drops\n // itself from the cache once it settles with nobody watching.\n inject(DestroyRef).onDestroy(() => untracked(current)?.removeObserver())\n\n const state = computed(\n () =>\n current()?.state() ??\n getInitialState<TData, TError, TVariables, TContext>(),\n )\n\n return {\n // mutate() and reset() run untracked, as the QueryClient's methods do. A\n // call made from an effect mustn't make the effect depend on what they\n // read to do their job: the previous run's state, the options, or what\n // onMutate and mutationFn read. Otherwise a change to any of them\n // re-runs the effect, and the effect repeats the call.\n mutate: (variables) =>\n untracked(() => {\n // Stop observing the previous run. It isn't cancelled — if it's\n // still in flight it finishes and fires its hooks; it just no longer\n // feeds the signals below.\n current()?.removeObserver()\n\n // Options are read per call, so a signal used in them stays live.\n const run = cache.build(optionsFn())\n\n run.addObserver()\n current.set(run)\n run.execute(variables)\n }),\n reset: () =>\n untracked(() => {\n // \"Forget the result\", not \"stop the request\". A run still in\n // flight keeps going and fires its hooks, so the cache stays in step\n // with the server — cancelling could not un-send the write anyway,\n // it could only hide the fact that it happened.\n current()?.removeObserver()\n\n current.set(null)\n }),\n data: computed(() => state().data),\n error: computed(() => state().error as TError | null),\n variables: computed(() => state().variables),\n status: computed(() => state().status),\n isIdle: computed(() => state().status === 'idle'),\n isPending: computed(() => state().status === 'pending'),\n isSuccess: computed(() => state().status === 'success'),\n isError: computed(() => state().status === 'error'),\n failureCount: computed(() => state().failureCount),\n failureReason: computed(() => state().failureReason as TError | null),\n }\n })\n}\n","import {\n type Injector,\n type Signal,\n assertInInjectionContext,\n computed,\n inject,\n} from '@angular/core'\n\nimport { QueryClient } from './query-client'\nimport type { QueryFilters } from './types'\n\n/**\n * Returns a signal with the number of queries currently fetching — useful for a\n * global loading indicator.\n *\n * Pass {@link QueryFilters} to count only matching queries; omit them to count\n * every fetching query in the cache.\n *\n * Must run in an injection context, or be given an explicit `injector`.\n *\n * @param filters - Optional filters (e.g. `{ queryKey: ['todos'] }`) to narrow\n * the count.\n * @param options - Optional `injector` to use outside an injection context.\n * @returns A `Signal<number>` of active fetches.\n *\n * @example\n * ```ts\n * readonly isFetching = injectIsFetching()\n * // <app-spinner *ngIf=\"isFetching() > 0\" />\n * ```\n */\nexport function injectIsFetching(\n filters?: QueryFilters,\n options?: { injector?: Injector },\n): Signal<number> {\n if (!options?.injector) assertInInjectionContext(injectIsFetching)\n\n const client = options?.injector?.get(QueryClient) ?? inject(QueryClient)\n const cache = client.getQueryCache()\n\n return computed(\n () =>\n cache.findAll(filters).filter((query) => query.state().isFetching).length,\n )\n}\n","import {\n type Injector,\n type Signal,\n assertInInjectionContext,\n computed,\n inject,\n} from '@angular/core'\n\nimport { QueryClient } from './query-client'\n\n/**\n * Returns a signal with the number of mutations currently pending — useful for\n * a global \"saving…\" indicator.\n *\n * Must run in an injection context, or be given an explicit `injector`.\n *\n * @param options - Optional `injector` to use outside an injection context.\n * @returns A `Signal<number>` of in-flight mutations.\n *\n * @example\n * ```ts\n * readonly isMutating = injectIsMutating()\n * // <p *ngIf=\"isMutating() > 0\">Saving…</p>\n * ```\n */\nexport function injectIsMutating(options?: {\n injector?: Injector\n}): Signal<number> {\n if (!options?.injector) assertInInjectionContext(injectIsMutating)\n\n const client = options?.injector?.get(QueryClient) ?? inject(QueryClient)\n const cache = client.getMutationCache()\n\n return computed(() => cache.findAll({ status: 'pending' }).length)\n}\n","import type { QueryOptions } from './types'\n\n/**\n * Identity helper that defines a typed, reusable set of {@link QueryOptions}.\n *\n * Returns the options unchanged at runtime, but anchors type inference so the\n * same definition can be shared across {@link injectQuery},\n * {@link QueryClient.setQueryData}, and friends without re-declaring generics.\n * Keeping query definitions in a service (rather than inline) makes them easy\n * to reuse and unit-test.\n *\n * @typeParam TData - Type of the data resolved by `queryFn`.\n * @typeParam TError - Type of the error thrown by `queryFn`.\n * @param options - The {@link QueryOptions} to define.\n * @returns The same `options`, typed.\n *\n * @example\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class TodoQueries {\n * private readonly http = inject(HttpClient)\n *\n * todos() {\n * return queryOptions({\n * queryKey: ['todos'],\n * queryFn: () => this.http.get<Todo[]>('/api/todos'),\n * })\n * }\n * }\n *\n * // const todos = injectQuery(() => inject(TodoQueries).todos())\n * ```\n */\nexport function queryOptions<TData, TError = Error>(\n options: QueryOptions<TData, TError>,\n): QueryOptions<TData, TError> {\n return options\n}\n","/**\n * Placeholder function that keeps the previous query's data visible while the\n * next one loads — pass as `placeholderData` to avoid flicker when the query\n * key changes (e.g. pagination, search).\n *\n * While the placeholder is shown, `status` reads `'success'` and\n * `isPlaceholderData()` is `true`; `isFetching()` stays `true` so the UI can\n * indicate the data is stale.\n *\n * @example\n * ```ts\n * readonly todos = injectQuery(() => ({\n * queryKey: ['todos', this.page()],\n * queryFn: () => this.http.get<Todo[]>(`/api/todos?page=${this.page()}`),\n * placeholderData: keepPreviousData,\n * }))\n * ```\n */\nexport function keepPreviousData<TData>(\n previousData: TData | undefined,\n): TData | undefined {\n return previousData\n}\n","import type { MutationOptions } from './mutation'\n\n/**\n * Identity helper that defines a typed, reusable set of {@link MutationOptions}.\n *\n * Returns the options unchanged at runtime; its job is to anchor type inference\n * (notably linking `TContext` returned by `onMutate` to the later hooks) so a\n * mutation can be defined once in a service and passed to {@link injectMutation}.\n *\n * @typeParam TData - Type of the data resolved by `mutationFn`.\n * @typeParam TError - Type of the error thrown by `mutationFn`.\n * @typeParam TVariables - Type of the argument passed to `mutate()`.\n * @typeParam TContext - Type returned by `onMutate`, passed to later hooks.\n * @param options - The {@link MutationOptions} to define.\n * @returns The same `options`, typed.\n *\n * @example\n * ```ts\n * addTodo() {\n * return mutationOptions({\n * mutationFn: (title: string) => this.http.post<Todo>('/api/todos', { title }),\n * onSuccess: () => this.client.invalidateQueries({ queryKey: ['todos'] }),\n * })\n * }\n * ```\n */\nexport function mutationOptions<\n TData,\n TError = Error,\n TVariables = void,\n TContext = unknown,\n>(\n options: MutationOptions<TData, TError, TVariables, TContext>,\n): MutationOptions<TData, TError, TVariables, TContext> {\n return options\n}\n","import { QUERY_CLIENT_CONFIG } from '../core/injection-tokens'\nimport type { RetryDelayValue, RetryValue } from '../core/types'\nimport {\n type QueryClientFeature,\n QueryClientFeatureKind,\n queryClientFeature,\n} from './feature'\n\n/** Default query options applied to every query unless overridden per-query. */\nexport interface DefaultQueryOptions {\n /** How long fetched data is considered fresh, in ms. Defaults to `0`. */\n staleTime?: number\n /** How long unused (unobserved) data is kept before garbage collection, in ms. */\n gcTime?: number\n /** Retry policy on failure: a boolean, a count, or a predicate. Defaults to `3`. */\n retry?: RetryValue<unknown>\n /** Delay between retries, in ms or a function of the attempt. */\n retryDelay?: RetryDelayValue<unknown>\n}\n\n/** Application-wide defaults configured via {@link withDefaultOptions}. */\nexport interface DefaultOptions {\n /** Defaults applied to all queries. */\n queries?: DefaultQueryOptions\n}\n\n/**\n * Feature for {@link provideQueryClient} that sets application-wide default\n * query options. Per-query options always take precedence over these defaults.\n *\n * @param options - The {@link DefaultOptions} to apply.\n * @returns A {@link QueryClientFeature} to pass to {@link provideQueryClient}.\n *\n * @example\n * ```ts\n * provideQueryClient(\n * withDefaultOptions({ queries: { staleTime: 60_000, retry: 1 } }),\n * )\n * ```\n */\nexport function withDefaultOptions(\n options: DefaultOptions,\n): QueryClientFeature<QueryClientFeatureKind.DefaultOptions> {\n return queryClientFeature(QueryClientFeatureKind.DefaultOptions, [\n { provide: QUERY_CLIENT_CONFIG, useValue: { defaultOptions: options } },\n ])\n}\n","/*\n * Public API Surface of ngx-query\n */\n\nexport * from './lib/core/query-client'\nexport * from './lib/core/provider'\nexport * from './lib/core/inject-query-client'\nexport * from './lib/core/types'\nexport * from './lib/core/inject-query'\nexport * from './lib/core/inject-queries'\nexport * from './lib/core/inject-mutation'\nexport * from './lib/core/inject-is-fetching'\nexport * from './lib/core/inject-is-mutating'\nexport * from './lib/core/query-options'\nexport * from './lib/core/keep-previous-data'\nexport * from './lib/core/mutation-options'\nexport type {\n MutationFilters,\n MutationOptions,\n MutationResult,\n MutationState,\n MutationStatus,\n} from './lib/core/mutation'\nexport { QueryClientFeatureKind } from './lib/features/feature'\nexport type { QueryClientFeature } from './lib/features/feature'\nexport { withDefaultOptions } from './lib/features/with-default-options'\nexport type {\n DefaultOptions,\n DefaultQueryOptions,\n} from './lib/features/with-default-options'\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["retry","retryOperator"],"mappings":"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"}
package/index.d.ts CHANGED
@@ -183,6 +183,11 @@ declare class Query<TData, TError = Error> {
183
183
  declare class QueryCache extends Cache<Query<unknown, unknown>> {
184
184
  getOrCreate<TData, TError = Error>(key: QueryKey): Query<TData, TError>;
185
185
  get<TData, TError = Error>(key: QueryKey): Query<TData, TError> | undefined;
186
+ /**
187
+ * Like get(), but reactive, as findAll() is: a computed or an effect that
188
+ * calls it re-runs when an entry is added or removed.
189
+ */
190
+ find<TData, TError = Error>(key: QueryKey): Query<TData, TError> | undefined;
186
191
  findAll(filters?: QueryFilters): Array<Query<unknown, unknown>>;
187
192
  remove<TData, TError>(query: Query<TData, TError>): void;
188
193
  clear(): void;
@@ -242,7 +247,10 @@ type MutationOptions<TData, TError, TVariables, TContext> = {
242
247
  type MutationResult<TData, TError, TVariables> = {
243
248
  /** Triggers the mutation with the given variables. */
244
249
  mutate: (variables: TVariables) => void;
245
- /** Resets state back to `idle`, cancelling any in-flight run. */
250
+ /**
251
+ * Resets the state to `idle`. It forgets the result and doesn't stop the
252
+ * request: a run in flight finishes and fires its hooks.
253
+ */
246
254
  reset: () => void;
247
255
  /** Data from the last successful run, or `undefined`. */
248
256
  data: Signal<TData | undefined>;
@@ -303,6 +311,13 @@ declare class MutationCache extends Cache<Mutation<unknown, unknown, unknown, un
303
311
  * {@link injectQueryClient}. Offers imperative cache access — reading and
304
312
  * writing data, and invalidating, cancelling, or removing queries — that
305
313
  * complements the reactive {@link injectQuery} / {@link injectMutation} APIs.
314
+ *
315
+ * Its methods aren't reactive. Called from an effect, a method doesn't make
316
+ * the effect depend on the cache, on a query's state, or on what `queryFn` or
317
+ * an updater reads: the effect re-runs only when what it reads itself
318
+ * changes. A read is a snapshot, in a template or a `computed` too; for state
319
+ * that updates, use {@link injectQuery}, {@link injectIsFetching} and
320
+ * {@link injectIsMutating}.
306
321
  */
307
322
  declare class QueryClient {
308
323
  #private;
@@ -319,7 +334,7 @@ declare class QueryClient {
319
334
  /**
320
335
  * Imperatively fetches and caches a query, unless fresh data already exists
321
336
  * (governed by `staleTime`). Prefer {@link injectQuery} in components; use
322
- * this for prefetching outside the reactive flow.
337
+ * this to prefetch, from an event handler or an effect.
323
338
  *
324
339
  * @param key - The query key to fetch and cache under.
325
340
  * @param queryFn - Function returning the data as an `Observable` or `Promise`.
@@ -334,7 +349,9 @@ declare class QueryClient {
334
349
  }): void;
335
350
  /**
336
351
  * Reads the current cached data for a query key, or `undefined` if the query
337
- * is not cached yet.
352
+ * is not cached yet. A snapshot: it doesn't update a template, a `computed`
353
+ * or an effect when the data changes. For data that updates, use
354
+ * {@link injectQuery}.
338
355
  *
339
356
  * @param key - The query key to read.
340
357
  * @returns The cached data, or `undefined`.
@@ -377,21 +394,27 @@ declare class QueryClient {
377
394
  */
378
395
  cancelQueries(filters?: QueryFilters): void;
379
396
  /**
380
- * Removes matching queries from the cache entirely, discarding their data.
397
+ * Removes matching queries from the cache entirely, discarding their data
398
+ * and cancelling their fetches. Nothing is refetched: a component still
399
+ * showing a removed key keeps what it shows until something puts the key
400
+ * back in the cache (a write, a refetch, another component, its own
401
+ * polling), then shows what the cache holds, as after a key change.
381
402
  *
382
403
  * @param filters - Which queries to remove; omit to remove all.
383
404
  */
384
405
  removeQueries(filters?: QueryFilters): void;
385
406
  /**
386
- * Returns the number of matching queries currently fetching. For a reactive
387
- * count, prefer {@link injectIsFetching}.
407
+ * Returns the number of matching queries currently fetching. A snapshot: it
408
+ * doesn't update a template, a `computed` or an effect. For a count that
409
+ * updates, use {@link injectIsFetching}.
388
410
  *
389
411
  * @param filters - Which queries to count; omit to count all.
390
412
  */
391
413
  isFetching(filters?: QueryFilters): number;
392
414
  /**
393
- * Returns the number of mutations currently pending. For a reactive count,
394
- * prefer {@link injectIsMutating}.
415
+ * Returns the number of mutations currently pending. A snapshot: it doesn't
416
+ * update a template, a `computed` or an effect. For a count that updates,
417
+ * use {@link injectIsMutating}.
395
418
  */
396
419
  isMutating(): number;
397
420
  static ɵfac: i0.ɵɵFactoryDeclaration<QueryClient, never>;
@@ -576,8 +599,11 @@ declare function injectQueries<TData, TError = Error>(optionsFn: () => InjectQue
576
599
  * to trigger `mutationFn`. The `onMutate` / `onSuccess` / `onError` /
577
600
  * `onSettled` lifecycle hooks make optimistic updates and cache invalidation
578
601
  * straightforward. Mutations do not retry by default (a retried write is not
579
- * idempotent); opt in via `options.retry`. Bound to the current injection
580
- * context and cancelled when that context is destroyed.
602
+ * idempotent); opt in via `options.retry`. `mutate()` and `reset()` are safe
603
+ * to call from an effect: neither makes the effect depend on what it reads,
604
+ * such as the options or the previous run. Bound to the current injection
605
+ * context. Destroying it doesn't cancel a run in flight: the write has most
606
+ * likely reached the server, so the run finishes and fires its hooks.
581
607
  *
582
608
  * Must run in an injection context, or be given an explicit `injector`.
583
609
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-signal-query",
3
- "version": "1.3.1",
3
+ "version": "1.3.2-dev.2",
4
4
  "description": "Signal-first data fetching, caching, and mutations for Angular — inspired by TanStack Query.",
5
5
  "keywords": [
6
6
  "angular",