@mmstack/resource 20.5.2 → 20.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -123,15 +123,15 @@ All three return a signal-typed ref — `value()`, `status()`, `error()`, `heade
123
123
 
124
124
  When the cache interceptor is registered (`createCacheInterceptor()`) and a query resource opts in via `cache`, responses are stored in the shared `Cache` keyed by a string derived from the request.
125
125
 
126
- **Default key**: `${method} ${urlWithParams(request)}` — produced by `urlWithParams()` (`util/url-with-params.ts:24`). It includes method, URL path, and sorted query params. **It does not include headers, body, or `HttpContext`.**
126
+ **Default key**: produced by `hashRequest()` (`util/hash-request.ts`). Composition is `${method}:${url}:${responseType}[:${params}][:${body}]` sorted query params, stable body hashing (incl. `File`/`Blob`/`FormData`/`URLSearchParams`/`ArrayBuffer` markers). **It does not include headers or `HttpContext`.**
127
127
 
128
- If two requests should _not_ share a cache entry but the default key would collide (e.g. different `Authorization` headers, request body in a GET-equivalent POST), pass a custom hash:
128
+ If two requests should _not_ share a cache entry but the default key would collide (e.g. different `Authorization` headers), pass a custom hash:
129
129
 
130
130
  ```typescript
131
131
  queryResource<Post>(() => ({ url, headers }), {
132
132
  cache: {
133
133
  hash: (req) =>
134
- `${req.method}:${req.urlWithParams}:${req.headers.get('Authorization') ?? ''}`,
134
+ `${hashRequest(req)}:${(req.headers as HttpHeaders | undefined)?.get('Authorization') ?? ''}`,
135
135
  },
136
136
  });
137
137
  ```
@@ -321,7 +321,7 @@ provideQueryCache({
321
321
  | -------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------- |
322
322
  | `staleTime` | from `provideQueryCache` | Per-resource override. |
323
323
  | `ttl` | from `provideQueryCache` | Per-resource override. |
324
- | `hash` | `urlWithParams` | Custom cache key function. See [cache + cache keys](#cache--cache-keys). |
324
+ | `hash` | `hashRequest` | Custom cache key function. See [cache + cache keys](#cache--cache-keys). |
325
325
  | `persist` | `false` | Mirror this resource's responses to IndexedDB (only effective if the cache itself was created with `persist: true`). |
326
326
  | `ignoreCacheControl` | `false` | Ignore HTTP `Cache-Control` directives and use only `staleTime`/`ttl`. |
327
327
 
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { isDevMode, untracked, computed, InjectionToken, inject, signal, effect, Injector, linkedSignal, Injectable, DestroyRef } from '@angular/core';
3
3
  import { mutable, toWritable, sensor, nestedEffect } from '@mmstack/primitives';
4
- import { HttpHeaders, HttpResponse, HttpContextToken, HttpContext, HttpParams, httpResource, HttpClient } from '@angular/common/http';
4
+ import { HttpHeaders, HttpResponse, HttpParams, HttpContextToken, HttpContext, httpResource, HttpClient } from '@angular/common/http';
5
5
  import { of, tap, map, finalize, shareReplay, interval, firstValueFrom, catchError, combineLatestWith, filter } from 'rxjs';
6
6
  import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
7
7
 
@@ -550,6 +550,173 @@ function injectQueryCache(injector) {
550
550
  return cache;
551
551
  }
552
552
 
553
+ /**
554
+ * Returns `true` for any object-like value whose own enumerable keys should
555
+ * be sorted for stable hashing. Excludes arrays (positional), `Date`
556
+ * (handled by `toJSON`), `Map`/`Set` (handled explicitly), and binary types
557
+ * (`Blob`/`FormData`/`URLSearchParams`/`ArrayBuffer`/typed arrays — these
558
+ * should be branched on before reaching `hash()`, typically by `hashRequest`).
559
+ *
560
+ * Plain objects, class instances, and `Object.create(null)` all qualify.
561
+ */
562
+ function isHashableObject(value) {
563
+ if (value === null || typeof value !== 'object')
564
+ return false;
565
+ if (Array.isArray(value))
566
+ return false;
567
+ if (value instanceof Date)
568
+ return false;
569
+ if (value instanceof Map)
570
+ return false;
571
+ if (value instanceof Set)
572
+ return false;
573
+ if (typeof Blob !== 'undefined' && value instanceof Blob)
574
+ return false;
575
+ if (typeof FormData !== 'undefined' && value instanceof FormData)
576
+ return false;
577
+ if (typeof URLSearchParams !== 'undefined' &&
578
+ value instanceof URLSearchParams)
579
+ return false;
580
+ if (value instanceof ArrayBuffer)
581
+ return false;
582
+ if (ArrayBuffer.isView(value))
583
+ return false;
584
+ return true;
585
+ }
586
+ function sortKeys(val) {
587
+ return Object.keys(val)
588
+ .toSorted()
589
+ .reduce((result, key) => {
590
+ result[key] = val[key];
591
+ return result;
592
+ }, {});
593
+ }
594
+ /**
595
+ * Internal helper to generate a stable JSON string from an array.
596
+ * - Object-like values (plain, class instances, null-proto) get their own
597
+ * enumerable keys sorted alphabetically.
598
+ * - `Map` → marker object with sorted entries (sorted by `JSON.stringify(key)`).
599
+ * - `Set` → marker object with sorted values (sorted by `JSON.stringify(value)`).
600
+ * - Arrays preserve order. `Date` serializes via `toJSON`.
601
+ *
602
+ * @internal
603
+ */
604
+ function hashKey(queryKey) {
605
+ return JSON.stringify(queryKey, (_, val) => {
606
+ if (val instanceof Map) {
607
+ // Schwartzian: compute each entry's sort key (recursive hash of the
608
+ // Map key) once, then sort by the cheap string compare.
609
+ const entries = [...val.entries()]
610
+ .map((e) => [hash(e[0]), e])
611
+ .sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))
612
+ .map(([, e]) => e);
613
+ return { __map__: entries };
614
+ }
615
+ if (val instanceof Set) {
616
+ const values = [...val]
617
+ .map((v) => [hash(v), v])
618
+ .sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))
619
+ .map(([, v]) => v);
620
+ return { __set__: values };
621
+ }
622
+ if (isHashableObject(val))
623
+ return sortKeys(val);
624
+ return val;
625
+ });
626
+ }
627
+ /**
628
+ * Generates a stable, unique string hash from one or more arguments.
629
+ * Useful for creating cache keys or identifiers where object key order shouldn't matter.
630
+ *
631
+ * How it works:
632
+ * - Object-like values (plain objects, class instances, `Object.create(null)`) have
633
+ * their own enumerable keys sorted alphabetically before hashing. This ensures
634
+ * `{ a: 1, b: 2 }` and `{ b: 2, a: 1 }` produce the same hash.
635
+ * - `Map` and `Set` are serialized via stable, sorted markers (`__map__` / `__set__`).
636
+ * - Arrays preserve positional order; `Date` uses its ISO string via `toJSON`.
637
+ *
638
+ * @param {...unknown} args Values to include in the hash.
639
+ * @returns A stable string hash representing the input arguments.
640
+ * @example
641
+ * hash('posts', 10);
642
+ * // => '["posts",10]'
643
+ *
644
+ * hash({ a: 1, b: 2 }) === hash({ b: 2, a: 1 }); // true
645
+ *
646
+ * hash(new Map([['a', 1]])) === hash(new Map([['a', 1]])); // true
647
+ *
648
+ * // Be mindful of values JSON.stringify cannot handle (functions, undefined, Symbols)
649
+ * // hash('a', undefined, function() {}) => '["a",null,null]'
650
+ */
651
+ function hash(...args) {
652
+ return hashKey(args);
653
+ }
654
+
655
+ function normalizeParams(params) {
656
+ const p = params instanceof HttpParams
657
+ ? params
658
+ : new HttpParams({ fromObject: params });
659
+ return p
660
+ .keys()
661
+ .toSorted()
662
+ .map((key) => {
663
+ const encodedKey = encodeURIComponent(key);
664
+ return (p.getAll(key) ?? [])
665
+ .map((v) => `${encodedKey}=${encodeURIComponent(v)}`)
666
+ .join('&');
667
+ })
668
+ .join('&');
669
+ }
670
+ function hashBody(body) {
671
+ // File extends Blob — must check File first
672
+ if (typeof File !== 'undefined' && body instanceof File) {
673
+ return `File:${body.name}:${body.type}:${body.size}:${body.lastModified}`;
674
+ }
675
+ if (typeof Blob !== 'undefined' && body instanceof Blob) {
676
+ return `Blob:${body.type}:${body.size}`;
677
+ }
678
+ if (typeof FormData !== 'undefined' && body instanceof FormData) {
679
+ const entries = [];
680
+ body.forEach((value, key) => {
681
+ entries.push([key, hashBody(value)]);
682
+ });
683
+ entries.sort(([ak, av], [bk, bv]) => ak.localeCompare(bk) || av.localeCompare(bv));
684
+ return `FormData:${entries.map(([k, v]) => `${k}=${v}`).join('&')}`;
685
+ }
686
+ if (typeof URLSearchParams !== 'undefined' &&
687
+ body instanceof URLSearchParams) {
688
+ const sp = new URLSearchParams(body);
689
+ sp.sort();
690
+ return `URLSearchParams:${sp.toString()}`;
691
+ }
692
+ if (body instanceof ArrayBuffer) {
693
+ return `ArrayBuffer:${body.byteLength}`;
694
+ }
695
+ if (ArrayBuffer.isView(body)) {
696
+ return `${body.constructor.name}:${body.byteLength}`;
697
+ }
698
+ return hash(body);
699
+ }
700
+ /**
701
+ * Builds a stable cache/dedupe key from an HTTP request shape (accepts both
702
+ * `HttpRequest` and `HttpResourceRequest`).
703
+ *
704
+ * Key composition: `${method}:${url}:${responseType}[:${params}][:${body}]`
705
+ * - `method` defaults to `'GET'`, `responseType` to `'json'` (Angular defaults).
706
+ * - Query params are sorted alphabetically and URL-encoded for stability.
707
+ * - Body hashing handles `File`/`Blob`/`FormData`/`URLSearchParams`/`ArrayBuffer`
708
+ * and typed arrays explicitly; everything else flows through key-sorted
709
+ * `JSON.stringify` via `hash()`.
710
+ */
711
+ function hashRequest(req) {
712
+ const method = req.method ?? 'GET';
713
+ const responseType = req.responseType ?? 'json';
714
+ const base = `${method}:${req.url}:${responseType}`;
715
+ const params = req.params ? `:${normalizeParams(req.params)}` : '';
716
+ const body = req.body != null ? `:${hashBody(req.body)}` : '';
717
+ return base + params + body;
718
+ }
719
+
553
720
  const CACHE_CONTEXT = new HttpContextToken(() => ({
554
721
  cache: false,
555
722
  }));
@@ -693,7 +860,7 @@ function createCacheInterceptor(allowedMethods = ['GET', 'HEAD', 'OPTIONS']) {
693
860
  const opt = getCacheContext(req.context);
694
861
  if (!opt.cache)
695
862
  return next(req);
696
- const key = opt.key ?? req.urlWithParams;
863
+ const key = opt.key ?? hashRequest(req);
697
864
  const entry = cache.getUntracked(key); // null if expired or not found
698
865
  // If the entry is not stale, return it
699
866
  if (entry && !entry.isStale)
@@ -976,6 +1143,9 @@ function noDedupe(ctx = new HttpContext()) {
976
1143
  *
977
1144
  * @param allowed - An array of HTTP methods for which deduplication should be enabled.
978
1145
  * Defaults to `['GET', 'DELETE', 'HEAD', 'OPTIONS']`.
1146
+ * @param keyFn - Optional function to compute the dedupe key from a request.
1147
+ * Defaults to `hashRequest`, which includes method, URL,
1148
+ * response type, params, and body.
979
1149
  *
980
1150
  * @returns An `HttpInterceptorFn` that implements the request deduplication logic.
981
1151
  *
@@ -999,97 +1169,22 @@ function noDedupe(ctx = new HttpContext()) {
999
1169
  * ],
1000
1170
  * };
1001
1171
  */
1002
- function createDedupeRequestsInterceptor(allowed = ['GET', 'DELETE', 'HEAD', 'OPTIONS']) {
1172
+ function createDedupeRequestsInterceptor(allowed = ['GET', 'DELETE', 'HEAD', 'OPTIONS'], keyFn = hashRequest) {
1003
1173
  const inFlight = new Map();
1004
1174
  const DEDUPE_METHODS = new Set(allowed);
1005
1175
  return (req, next) => {
1006
1176
  if (!DEDUPE_METHODS.has(req.method) || req.context.get(NO_DEDUPE))
1007
1177
  return next(req);
1008
- const found = inFlight.get(req.urlWithParams);
1178
+ const key = keyFn(req);
1179
+ const found = inFlight.get(key);
1009
1180
  if (found)
1010
1181
  return found;
1011
- const request = next(req).pipe(finalize(() => inFlight.delete(req.urlWithParams)), shareReplay());
1012
- inFlight.set(req.urlWithParams, request);
1182
+ const request = next(req).pipe(finalize(() => inFlight.delete(key)), shareReplay({ bufferSize: 1, refCount: true }));
1183
+ inFlight.set(key, request);
1013
1184
  return request;
1014
1185
  };
1015
1186
  }
1016
1187
 
1017
- /**
1018
- * Checks if `value` is a plain JavaScript object (e.g., `{}` or `new Object()`).
1019
- * Distinguishes from arrays, null, and class instances. Acts as a type predicate,
1020
- * narrowing `value` to `UnknownObject` if `true`.
1021
- *
1022
- * @param value The value to check.
1023
- * @returns {value is UnknownObject} `true` if `value` is a plain object, otherwise `false`.
1024
- * @example
1025
- * isPlainObject({}) // => true
1026
- * isPlainObject([]) // => false
1027
- * isPlainObject(null) // => false
1028
- * isPlainObject(new Date()) // => false
1029
- */
1030
- function isPlainObject(value) {
1031
- if (value === null || typeof value !== 'object')
1032
- return false;
1033
- const proto = Object.getPrototypeOf(value);
1034
- if (proto === null)
1035
- return false; // remove Object.create(null);
1036
- return proto === Object.prototype;
1037
- }
1038
- /**
1039
- * Internal helper to generate a stable JSON string from an array.
1040
- * Sorts keys of plain objects within the array alphabetically before serialization
1041
- * to ensure hash stability regardless of key order.
1042
- *
1043
- * @param queryKey The array of values to serialize.
1044
- * @returns A stable JSON string representation.
1045
- * @internal
1046
- */
1047
- function hashKey(queryKey) {
1048
- return JSON.stringify(queryKey, (_, val) => isPlainObject(val)
1049
- ? Object.keys(val)
1050
- .toSorted()
1051
- .reduce((result, key) => {
1052
- result[key] = val[key];
1053
- return result;
1054
- }, {})
1055
- : val);
1056
- }
1057
- /**
1058
- * Generates a stable, unique string hash from one or more arguments.
1059
- * Useful for creating cache keys or identifiers where object key order shouldn't matter.
1060
- *
1061
- * How it works:
1062
- * - Plain objects within the arguments have their keys sorted alphabetically before hashing.
1063
- * This ensures that `{ a: 1, b: 2 }` and `{ b: 2, a: 1 }` produce the same hash.
1064
- * - Uses `JSON.stringify` internally with custom sorting for plain objects via `hashKey`.
1065
- * - Non-plain objects (arrays, Dates, etc.) and primitives are serialized naturally.
1066
- *
1067
- * @param {...unknown} args Values to include in the hash.
1068
- * @returns A stable string hash representing the input arguments.
1069
- * @example
1070
- * const userQuery = (id: number) => ['user', { id, timestamp: Date.now() }];
1071
- *
1072
- * const obj1 = { a: 1, b: 2 };
1073
- * const obj2 = { b: 2, a: 1 }; // Same keys/values, different order
1074
- *
1075
- * hash('posts', 10);
1076
- * // => '["posts",10]'
1077
- *
1078
- * hash('config', obj1);
1079
- * // => '["config",{"a":1,"b":2}]'
1080
- *
1081
- * hash('config', obj2);
1082
- * // => '["config",{"a":1,"b":2}]' (Same as above due to key sorting)
1083
- *
1084
- * hash(['todos', { status: 'done', owner: obj1 }]);
1085
- * // => '[["todos",{"owner":{"a":1,"b":2},"status":"done"}]]'
1086
- *
1087
- * // Be mindful of values JSON.stringify cannot handle (functions, undefined, Symbols)
1088
- * // hash('a', undefined, function() {}) => '["a",null,null]'
1089
- */
1090
- function hash(...args) {
1091
- return hashKey(args);
1092
- }
1093
1188
  function equalTransferCache(a, b) {
1094
1189
  if (!a && !b)
1095
1190
  return true;
@@ -1394,29 +1489,6 @@ function toResourceObject(res) {
1394
1489
  };
1395
1490
  }
1396
1491
 
1397
- function normalizeParams(params) {
1398
- if (params instanceof HttpParams)
1399
- return params.toString();
1400
- const paramMap = new Map();
1401
- for (const [key, value] of Object.entries(params)) {
1402
- if (Array.isArray(value)) {
1403
- paramMap.set(key, value.map(encodeURIComponent).join(','));
1404
- }
1405
- else {
1406
- paramMap.set(key, encodeURIComponent(value.toString()));
1407
- }
1408
- }
1409
- return Array.from(paramMap.entries())
1410
- .sort(([a], [b]) => a.localeCompare(b))
1411
- .map(([key, value]) => `${key}=${value}`)
1412
- .join('&');
1413
- }
1414
- function urlWithParams(req) {
1415
- if (!req.params)
1416
- return req.url;
1417
- return `${req.url}?${normalizeParams(req.params)}`;
1418
- }
1419
-
1420
1492
  function queryResource(request, options) {
1421
1493
  const cache = injectQueryCache(options?.injector);
1422
1494
  const destroyRef = options?.injector
@@ -1460,8 +1532,8 @@ function queryResource(request, options) {
1460
1532
  },
1461
1533
  }]));
1462
1534
  const hashFn = typeof options?.cache === 'object'
1463
- ? (options.cache.hash ?? urlWithParams)
1464
- : urlWithParams;
1535
+ ? (options.cache.hash ?? hashRequest)
1536
+ : hashRequest;
1465
1537
  const staleTime = typeof options?.cache === 'object' ? options.cache.staleTime : 0;
1466
1538
  const ttl = typeof options?.cache === 'object' ? options.cache.ttl : undefined;
1467
1539
  const cacheKey = computed(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"mmstack-resource.mjs","sources":["../../../../packages/resource/src/lib/util/cache/persistence.ts","../../../../packages/resource/src/lib/util/cache/cache.ts","../../../../packages/resource/src/lib/util/cache/cache-interceptor.ts","../../../../packages/resource/src/lib/util/catch-value-error.ts","../../../../packages/resource/src/lib/util/circuit-breaker.ts","../../../../packages/resource/src/lib/util/dedupe-interceptor.ts","../../../../packages/resource/src/lib/util/equality.ts","../../../../packages/resource/src/lib/util/has-slow-connection.ts","../../../../packages/resource/src/lib/util/persist.ts","../../../../packages/resource/src/lib/util/refresh.ts","../../../../packages/resource/src/lib/util/retry-on-error.ts","../../../../packages/resource/src/lib/util/sensors.ts","../../../../packages/resource/src/lib/util/to-resource-object.ts","../../../../packages/resource/src/lib/util/url-with-params.ts","../../../../packages/resource/src/lib/query-resource.ts","../../../../packages/resource/src/lib/manual-query.ts","../../../../packages/resource/src/lib/mutation-resource.ts","../../../../packages/resource/src/mmstack-resource.ts"],"sourcesContent":["import { isDevMode } from '@angular/core';\nimport { CacheEntry } from './cache';\n\ntype StoredEntry<T> = Omit<CacheEntry<T>, 'timeout'>;\n\nexport type CacheDB<T> = {\n getAll: () => Promise<StoredEntry<T>[]>;\n store: (value: StoredEntry<T>) => Promise<void>;\n remove: (key: string) => Promise<void>;\n};\n\nexport function createNoopDB<T>(): CacheDB<T> {\n return {\n getAll: async () => [],\n store: async () => {\n // noop\n },\n remove: async () => {\n // noop\n },\n };\n}\n\nfunction toCacheDB<T>(db: IDBDatabase, storeName: string): CacheDB<T> {\n const getAll = async () => {\n const now = Date.now();\n return new Promise<StoredEntry<T>[]>((res, rej) => {\n const transaction = db.transaction(storeName, 'readonly');\n const store = transaction.objectStore(storeName);\n const request = store.getAll();\n\n request.onsuccess = () => res(request.result);\n request.onerror = () => rej(request.error);\n })\n .then((entries) => entries.filter((e) => e.expiresAt > now))\n .catch((err) => {\n if (isDevMode())\n console.error('Error getting all items from cache DB:', err);\n return [];\n });\n };\n\n const store = (value: StoredEntry<T>) => {\n return new Promise<void>((res, rej) => {\n const transaction = db.transaction(storeName, 'readwrite');\n const store = transaction.objectStore(storeName);\n\n store.put(value);\n\n transaction.oncomplete = () => res();\n transaction.onerror = () => rej(transaction.error);\n }).catch((err) => {\n if (isDevMode()) console.error('Error storing item in cache DB:', err);\n });\n };\n\n const remove = (key: string) => {\n return new Promise<void>((res, rej) => {\n const transaction = db.transaction(storeName, 'readwrite');\n const store = transaction.objectStore(storeName);\n\n store.delete(key);\n\n transaction.oncomplete = () => res();\n transaction.onerror = () => rej(transaction.error);\n }).catch((err) => {\n if (isDevMode()) console.error('Error removing item from cache DB:', err);\n });\n };\n\n return {\n getAll,\n store,\n remove,\n };\n}\n\nexport function createSingleStoreDB<T>(\n name: string,\n getStoreName: (version: number) => string,\n version = 1,\n): Promise<CacheDB<T>> {\n const storeName = getStoreName(version);\n\n if (!globalThis.indexedDB) return Promise.resolve(createNoopDB());\n\n return new Promise<IDBDatabase>((res, rej) => {\n if (version < 1) rej(new Error('Version must be 1 or greater'));\n\n const req = indexedDB.open(name, version);\n\n req.onupgradeneeded = (event) => {\n const db = req.result;\n const oldVersion = event.oldVersion;\n\n db.createObjectStore(storeName, { keyPath: 'key' });\n\n if (oldVersion > 0) {\n db.deleteObjectStore(getStoreName(oldVersion));\n }\n };\n\n req.onerror = () => {\n rej(req.error);\n };\n\n req.onsuccess = () => res(req.result);\n })\n .then((db) => toCacheDB<T>(db, storeName))\n .catch((err) => {\n if (isDevMode()) console.error('Error creating query DB:', err);\n return createNoopDB();\n });\n}\n","import { HttpHeaders, HttpResponse } from '@angular/common/http';\nimport {\n computed,\n inject,\n InjectionToken,\n Injector,\n isDevMode,\n type Provider,\n type Signal,\n untracked,\n} from '@angular/core';\nimport { mutable } from '@mmstack/primitives';\nimport { CacheDB, createNoopDB, createSingleStoreDB } from './persistence';\n\nfunction generateID() {\n if (globalThis.crypto?.randomUUID) {\n return globalThis.crypto.randomUUID();\n }\n return Math.random().toString(36).substring(2);\n}\n\ntype BaseSyncMessage<TEntry, TAction extends string> = {\n entry: TEntry;\n action: TAction;\n};\n\ntype InvalidateMessage<T> = BaseSyncMessage<\n Pick<CacheEntry<T>, 'key'>,\n 'invalidate'\n>;\n\ntype StoreMessage<T> = BaseSyncMessage<Omit<CacheEntry<T>, 'timeout'>, 'store'>;\n\ntype InternalSyncMessage<T> = InvalidateMessage<T> | StoreMessage<T>;\n\n/**\n * A message type used for synchronizing cache updates across tabs.\n * @internal\n * @template T - The type of data being cached.\n */\ntype SyncMessage<T> = InternalSyncMessage<T> & {\n cacheId: string;\n type: 'cache-sync-message';\n};\n\nfunction isSyncMessage<T>(msg: unknown): msg is SyncMessage<T> {\n return (\n typeof msg === 'object' &&\n msg !== null &&\n 'type' in msg &&\n (msg as SyncMessage<T>).type === 'cache-sync-message'\n );\n}\n\n/**\n * Options for configuring the Least Recently Used (LRU) cache cleanup strategy.\n * @internal\n */\ntype LRUCleanupType = {\n type: 'lru';\n /**\n * How often to check for expired or excess entries, in milliseconds.\n */\n checkInterval: number;\n /**\n * The maximum number of entries to keep in the cache. When the cache exceeds this size,\n * the least recently used entries will be removed.\n */\n maxSize: number;\n};\n\n/**\n * Options for configuring the \"oldest first\" cache cleanup strategy.\n * @internal\n */\ntype OldsetCleanupType = {\n type: 'oldest';\n /**\n * How often to check for expired or excess entries, in milliseconds.\n */\n checkInterval: number;\n /**\n * The maximum number of entries to keep in the cache. When the cache exceeds this size,\n * the oldest entries will be removed.\n */\n maxSize: number;\n};\n\n/**\n * Represents an entry in the cache.\n * @internal\n */\nexport type CacheEntry<T> = {\n value: T;\n created: number;\n updated: number;\n stale: number;\n useCount: number;\n expiresAt: number;\n timeout: ReturnType<typeof setTimeout>;\n key: string;\n};\n\n/**\n * Defines the types of cleanup strategies available for the cache.\n * - `lru`: Least Recently Used. Removes the least recently accessed entries when the cache is full.\n * - `oldest`: Removes the oldest entries when the cache is full.\n */\nexport type CleanupType = LRUCleanupType | OldsetCleanupType;\n\nconst ONE_DAY = 1000 * 60 * 60 * 24;\nconst ONE_HOUR = 1000 * 60 * 60;\n\nconst DEFAULT_CLEANUP_OPT = {\n type: 'lru',\n maxSize: 200,\n checkInterval: ONE_HOUR,\n} satisfies LRUCleanupType;\n\n/**\n * A generic cache implementation that stores data with time-to-live (TTL) and stale-while-revalidate capabilities.\n *\n * @typeParam T - The type of data to be stored in the cache.\n */\nexport class Cache<T> {\n private readonly internal = mutable(new Map<string, CacheEntry<T>>());\n private readonly cleanupOpt: CleanupType;\n private readonly id = generateID();\n\n /**\n * Destroys the cache instance, cleaning up any resources used by the cache.\n * This method is called automatically when the cache instance is garbage collected.\n */\n readonly destroy: () => void;\n\n private readonly broadcast: (msg: InternalSyncMessage<T>) => void = () => {\n // noop\n };\n\n /**\n * Creates a new `Cache` instance.\n *\n * @param ttl - The default Time To Live (TTL) for cache entries, in milliseconds. Defaults to one day.\n * @param staleTime - The default duration, in milliseconds, during which a cache entry is considered\n * stale but can still be used while revalidation occurs in the background. Defaults to 1 hour.\n * @param cleanupOpt - Options for configuring the cache cleanup strategy. Defaults to LRU with a\n * `maxSize` of 200 and a `checkInterval` of one hour.\n * @param syncTabs - If provided, the cache will use the options a BroadcastChannel to send updates between tabs.\n * Defaults to `undefined`, meaning no synchronization across tabs.\n */\n constructor(\n protected readonly ttl: number = ONE_DAY,\n protected readonly staleTime: number = ONE_HOUR,\n cleanupOpt: Partial<CleanupType> = {\n type: 'lru',\n maxSize: 1000,\n checkInterval: ONE_HOUR,\n },\n syncTabs?: {\n id: string;\n serialize: (value: T) => string;\n deserialize: (value: string) => T | null;\n },\n\n private readonly db: Promise<CacheDB<T>> = Promise.resolve(\n createNoopDB<T>(),\n ),\n ) {\n this.cleanupOpt = {\n ...DEFAULT_CLEANUP_OPT,\n ...cleanupOpt,\n };\n\n if (this.cleanupOpt.maxSize <= 0)\n throw new Error('maxSize must be greater than 0');\n\n // cleanup cache based on provided options regularly\n const cleanupInterval = setInterval(() => {\n this.cleanup();\n }, cleanupOpt.checkInterval);\n\n let destroySyncTabs = () => {\n // noop\n };\n\n if (syncTabs) {\n const channel = new BroadcastChannel(syncTabs.id);\n this.broadcast = (msg: InternalSyncMessage<T>) => {\n if (msg.action === 'invalidate')\n return channel.postMessage({\n action: 'invalidate',\n entry: { key: msg.entry.key },\n cacheId: this.id,\n type: 'cache-sync-message',\n } satisfies SyncMessage<string>);\n\n return channel.postMessage({\n ...msg,\n entry: {\n ...msg.entry,\n value: syncTabs.serialize(msg.entry.value),\n },\n cacheId: this.id,\n type: 'cache-sync-message',\n } satisfies SyncMessage<string>);\n };\n\n channel.onmessage = (event) => {\n const msg = event.data;\n if (!isSyncMessage<string>(msg)) return;\n if (msg.cacheId === this.id) return; // ignore messages from this cache\n\n if (msg.action === 'store') {\n const value = syncTabs.deserialize(msg.entry.value);\n if (value === null) return;\n\n // Last-write-wins by `updated` timestamp. If our local entry was\n // written more recently than the broadcast we just received, the\n // broadcast is stale (in-flight when we wrote locally) — drop it.\n const existing = untracked(this.internal).get(msg.entry.key);\n if (existing && existing.updated >= msg.entry.updated) return;\n\n this.storeInternal(\n msg.entry.key,\n value,\n msg.entry.stale - msg.entry.updated,\n msg.entry.expiresAt - msg.entry.updated,\n true,\n false,\n );\n } else if (msg.action === 'invalidate') {\n this.invalidateInternal(msg.entry.key, true);\n }\n };\n\n destroySyncTabs = () => {\n channel.close();\n };\n }\n\n let destroyed = false;\n const destroy = () => {\n if (destroyed) return;\n destroyed = true;\n clearInterval(cleanupInterval);\n destroySyncTabs();\n };\n\n this.db\n .then(async (db) => {\n if (destroyed) return [];\n return db.getAll();\n })\n .then((entries) => {\n if (destroyed) return;\n // load entries into the cache\n\n const current = untracked(this.internal);\n entries.forEach((entry) => {\n if (current.has(entry.key)) return;\n this.storeInternal(\n entry.key,\n entry.value,\n entry.stale - entry.updated,\n entry.expiresAt - entry.updated,\n true, // like from sync because we dont want to trigger sync or db writes\n );\n });\n });\n\n this.destroy = destroy;\n\n // cleanup if object is garbage collected, this is because the cache can be quite large from a memory standpoint & we dont want all that floating garbage\n const registry = new FinalizationRegistry((id: string) => {\n if (id === this.id) {\n destroy();\n }\n });\n\n registry.register(this, this.id);\n }\n\n /** @internal */\n private getInternal(\n key: () => string | null,\n ): Signal<(CacheEntry<T> & { isStale: boolean }) | null> {\n const keySignal = computed(() => key());\n\n return computed(() => {\n const key = keySignal();\n if (!key) return null;\n const found = this.internal().get(key);\n\n const now = Date.now();\n\n if (!found || found.expiresAt <= now) return null;\n found.useCount++;\n return {\n ...found,\n isStale: found.stale <= now,\n };\n });\n }\n\n /**\n * Retrieves a cache entry without affecting its usage count (for LRU). This is primarily\n * for internal use or debugging.\n * @internal\n * @param key - The key of the entry to retrieve.\n * @returns The cache entry, or `null` if not found or expired.\n */\n getUntracked(key: string): (CacheEntry<T> & { isStale: boolean }) | null {\n return untracked(this.getInternal(() => key));\n }\n\n /**\n * Retrieves a cache entry as a signal.\n *\n * @param key - A function that returns the cache key. The key is a signal, allowing for dynamic keys. If the function returns null the value is also null.\n * @returns A signal that holds the cache entry, or `null` if not found or expired. The signal\n * updates whenever the cache entry changes (e.g., due to revalidation or expiration).\n */\n get(\n key: () => string | null,\n ): Signal<(CacheEntry<T> & { isStale: boolean }) | null> {\n return this.getInternal(key);\n }\n\n /**\n * Retrieves a cache entry or an object with the key if not found.\n *\n * @param key - A function that returns the cache key. The key is a signal, allowing for dynamic keys. If the function returns null the value is also null.\n * @returns A signal that holds the cache entry or an object with the key if not found. The signal\n * updates whenever the cache entry changes (e.g., due to revalidation or expiration).\n */\n getEntryOrKey(\n key: () => string | null,\n ): Signal<(CacheEntry<T> & { isStale: boolean }) | string | null> {\n const valueSig = this.getInternal(key);\n return computed(() => valueSig() ?? key());\n }\n\n /**\n * Stores a value in the cache.\n *\n * @param key - The key under which to store the value.\n * @param value - The value to store.\n * @param staleTime - (Optional) The stale time for this entry, in milliseconds. Overrides the default `staleTime`.\n * @param ttl - (Optional) The TTL for this entry, in milliseconds. Overrides the default `ttl`.\n */\n store(\n key: string,\n value: T,\n staleTime = this.staleTime,\n ttl = this.ttl,\n persist = false,\n ) {\n this.storeInternal(key, value, staleTime, ttl, false, persist);\n }\n\n private storeInternal(\n key: string,\n value: T,\n staleTime = this.staleTime,\n ttl = this.ttl,\n fromSync = false,\n persist = false,\n ) {\n const entry = this.getUntracked(key);\n if (entry) {\n clearTimeout(entry.timeout); // stop invalidation\n }\n\n const prevCount = entry?.useCount ?? 0;\n\n // ttl cannot be less than staleTime\n if (ttl < staleTime) staleTime = ttl;\n\n const now = Date.now();\n\n const next: Omit<CacheEntry<T>, 'timeout'> = {\n value,\n created: entry?.created ?? now,\n updated: now,\n useCount: prevCount + 1,\n stale: now + staleTime,\n expiresAt: now + ttl,\n key,\n };\n\n this.internal.mutate((map) => {\n map.set(key, {\n ...next,\n timeout: setTimeout(() => this.invalidate(key), ttl),\n });\n return map;\n });\n\n if (!fromSync) {\n if (persist) this.db.then((db) => db.store(next));\n\n this.broadcast({\n action: 'store',\n entry: next,\n });\n }\n }\n\n /**\n * Invalidates (removes) a cache entry.\n *\n * @param key - The key of the entry to invalidate.\n */\n invalidate(key: string) {\n this.invalidateInternal(key);\n }\n\n /**\n * Invalidates every cache entry whose key starts with `prefix`. Common after a\n * list-mutating operation (e.g. invalidate every paginated `GET /api/posts*`\n * after a POST). Returns the number of entries removed.\n *\n * @example\n * cache.invalidatePrefix('GET https://api.example.com/posts');\n */\n invalidatePrefix(prefix: string): number {\n return this.invalidateWhere((key) => key.startsWith(prefix));\n }\n\n /**\n * Invalidates every cache entry whose key matches the predicate. Use for\n * arbitrary bulk invalidation that doesn't fit prefix matching (e.g.\n * \"everything containing `userId=42`\"). Returns the number of entries removed.\n *\n * @example\n * cache.invalidateWhere((key) => key.includes('/me/'));\n */\n invalidateWhere(predicate: (key: string) => boolean): number {\n const keys = Array.from(untracked(this.internal).keys()).filter(predicate);\n for (const key of keys) this.invalidateInternal(key);\n return keys.length;\n }\n\n private invalidateInternal(key: string, fromSync = false) {\n const entry = this.getUntracked(key);\n if (!entry) return;\n clearTimeout(entry.timeout);\n this.internal.mutate((map) => {\n map.delete(key);\n return map;\n });\n if (!fromSync) {\n this.db.then((db) => db.remove(key));\n this.broadcast({ action: 'invalidate', entry: { key } });\n }\n }\n\n /** @internal */\n private cleanup() {\n if (untracked(this.internal).size <= this.cleanupOpt.maxSize) return;\n\n const sorted = Array.from(untracked(this.internal).entries()).toSorted(\n (a, b) => {\n if (this.cleanupOpt.type === 'lru') {\n return a[1].useCount - b[1].useCount; // least used first\n } else {\n return a[1].created - b[1].created; // oldest first\n }\n },\n );\n\n const keepCount = Math.floor(this.cleanupOpt.maxSize / 2);\n\n const removed = sorted.slice(0, sorted.length - keepCount);\n const keep = sorted.slice(removed.length, sorted.length);\n\n removed.forEach(([, e]) => {\n clearTimeout(e.timeout);\n });\n\n this.internal.set(new Map(keep));\n }\n}\n\n/**\n * Options for configuring the cache.\n */\ntype CacheOptions = {\n /**\n * The default Time To Live (TTL) for cache entries, in milliseconds.\n */\n ttl?: number;\n /**\n * The default duration, in milliseconds, during which a cache entry is considered\n * stale but can still be used while revalidation occurs in the background.\n */\n staleTime?: number;\n /**\n * Options for configuring the cache cleanup strategy.\n */\n cleanup?: Partial<CleanupType>;\n /**\n * Whether to synchronize cache across tabs. If true, the cache will use a BroadcastChannel to send updates between tabs.\n */\n syncTabs?: boolean;\n /**\n * Globally disable persistence of cache entries.\n * If set to `false`, cache entries will not be persisted to the database.\n * `true` means, cache entries can be persisted, they must still be opted into on the resource level & allowed by server headers.\n * @default true\n */\n persist?: boolean;\n /**\n * Version of the caches database, increment this if the interfaces change, this will cause the old data to be deleted.\n * Minimum value is 1, so first increment should be 2.\n * @default 1\n */\n version?: number;\n};\n\nconst CLIENT_CACHE_TOKEN = new InjectionToken<Cache<HttpResponse<unknown>>>(\n 'INTERNAL_CLIENT_CACHE',\n);\n\n/**\n * Provides the instance of the QueryCache for queryResource. This should probably be called\n * in your application's root configuration, but can also be overriden with component/module providers.\n *\n * @param options - Optional configuration options for the cache.\n * @returns An Angular `Provider` for the cache.\n *\n * @example\n * // In your app.config.ts or AppModule providers:\n *\n * import { provideQueryCache } from './your-cache';\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideQueryCache({\n * ttl: 60000, // Default TTL of 60 seconds\n * staleTime: 30000, // Default staleTime of 30 seconds\n * }),\n * // ... other providers\n * ]\n * };\n */\nexport function provideQueryCache(opt?: CacheOptions): Provider {\n const serialize = (value: HttpResponse<unknown>) => {\n const headersRecord: Record<string, string[]> = {};\n\n const headerKeys = value.headers.keys();\n headerKeys.forEach((key) => {\n const values = value.headers.getAll(key);\n if (!values) return;\n headersRecord[key] = values;\n });\n\n return JSON.stringify({\n body: value.body,\n status: value.status,\n statusText: value.statusText,\n headers: headerKeys.length > 0 ? headersRecord : undefined,\n url: value.url,\n });\n };\n\n const deserialize = (value: string) => {\n try {\n const parsed = JSON.parse(value);\n\n if (!parsed || typeof parsed !== 'object' || !('body' in parsed))\n throw new Error('Invalid cache entry format');\n\n const headers = parsed.headers\n ? new HttpHeaders(parsed.headers)\n : undefined;\n\n return new HttpResponse({\n body: parsed.body,\n status: parsed.status,\n statusText: parsed.statusText,\n headers: headers,\n url: parsed.url,\n });\n } catch (err) {\n if (isDevMode()) console.error('Failed to deserialize cache entry:', err);\n return null;\n }\n };\n\n const syncTabsOpt = opt?.syncTabs\n ? {\n id: 'mmstack-query-cache-sync',\n serialize,\n deserialize,\n }\n : undefined;\n\n const db =\n opt?.persist === false\n ? undefined\n : createSingleStoreDB<string>(\n 'mmstack-query-cache-db',\n (version) => `query-store_v${version}`,\n opt?.version,\n ).then((db): CacheDB<HttpResponse<unknown>> => {\n return {\n getAll: () => {\n return db.getAll().then((entries) => {\n return entries\n .map((entry) => {\n const value = deserialize(entry.value);\n if (value === null) return null;\n return {\n ...entry,\n value,\n };\n })\n .filter((e) => e !== null);\n });\n },\n store: (entry) => {\n return db.store({ ...entry, value: serialize(entry.value) });\n },\n remove: db.remove,\n };\n });\n\n return {\n provide: CLIENT_CACHE_TOKEN,\n useValue: new Cache(\n opt?.ttl,\n opt?.staleTime,\n opt?.cleanup,\n syncTabsOpt,\n db,\n ),\n };\n}\n\nclass NoopCache<T> extends Cache<T> {\n override store(_: string, __: T, ___ = super.staleTime, ____ = super.ttl) {\n // noop\n }\n}\n\n/**\n * Injects the `QueryCache` instance that is used within queryResource.\n * Allows for direct modification of cached data, but is mostly meant for internal use.\n *\n * @param injector - (Optional) The injector to use. If not provided, the current\n * injection context is used.\n * @returns The `QueryCache` instance.\n *\n * @example\n * // In your component or service:\n *\n * import { injectQueryCache } from './your-cache';\n *\n * constructor() {\n * const cache = injectQueryCache();\n *\n * const myData = cache.get(() => 'my-data-key');\n * if (myData() !== null) {\n * // ... use cached data ...\n * }\n * }\n */\nexport function injectQueryCache<TRaw = unknown>(\n injector?: Injector,\n): Cache<HttpResponse<TRaw>> {\n const cache = injector\n ? injector.get(CLIENT_CACHE_TOKEN, null, {\n optional: true,\n })\n : inject(CLIENT_CACHE_TOKEN, {\n optional: true,\n });\n\n if (!cache) {\n if (isDevMode())\n throw new Error(\n 'Cache not provided, please add provideQueryCache() to providers array',\n );\n else return new NoopCache();\n }\n\n return cache as Cache<HttpResponse<TRaw>>;\n}\n","import {\n HttpContext,\n HttpContextToken,\n type HttpEvent,\n type HttpHandlerFn,\n type HttpInterceptorFn,\n type HttpRequest,\n HttpResponse,\n} from '@angular/common/http';\nimport { map, Observable, of, tap } from 'rxjs';\nimport { injectQueryCache } from './cache';\n\ntype CacheEntryOptions = {\n key?: string;\n ttl?: number;\n staleTime?: number;\n cache: boolean;\n bustBrowserCache?: boolean;\n ignoreCacheControl?: boolean;\n parse?: (val: unknown) => unknown;\n persist?: boolean;\n};\n\nconst CACHE_CONTEXT = new HttpContextToken<CacheEntryOptions>(() => ({\n cache: false,\n}));\n\nexport function setCacheContext(\n ctx = new HttpContext(),\n opt: Omit<CacheEntryOptions, 'cache' | 'key'> & {\n key: Required<CacheEntryOptions>['key'];\n },\n) {\n return ctx.set(CACHE_CONTEXT, { ...opt, cache: true });\n}\n\nfunction getCacheContext(ctx: HttpContext): CacheEntryOptions {\n return ctx.get(CACHE_CONTEXT);\n}\n\ntype ResolvedCacheControl = {\n noStore: boolean;\n noCache: boolean;\n mustRevalidate: boolean;\n immutable: boolean;\n maxAge: number | null;\n staleWhileRevalidate: number | null;\n};\n\nfunction parseCacheControlHeader(\n req: HttpResponse<unknown>,\n): ResolvedCacheControl {\n const header = req.headers.get('Cache-Control');\n\n let sMaxAge: number | null = null;\n const directives: ResolvedCacheControl = {\n noStore: false,\n noCache: false,\n mustRevalidate: false,\n immutable: false,\n maxAge: null,\n staleWhileRevalidate: null,\n };\n\n if (!header) return directives;\n\n const parts = header.split(',');\n\n for (const part of parts) {\n const [unparsedKey, value] = part.trim().split('=');\n const key = unparsedKey.trim().toLowerCase();\n\n switch (key) {\n case 'no-store':\n directives.noStore = true;\n break;\n case 'no-cache':\n directives.noCache = true;\n break;\n case 'must-revalidate':\n case 'proxy-revalidate':\n directives.mustRevalidate = true;\n break;\n case 'immutable':\n directives.immutable = true;\n break;\n case 'max-age': {\n if (!value) break;\n const parsedValue = parseInt(value, 10);\n if (!isNaN(parsedValue)) directives.maxAge = parsedValue;\n break;\n }\n case 's-max-age': {\n if (!value) break;\n const parsedValue = parseInt(value, 10);\n if (!isNaN(parsedValue)) sMaxAge = parsedValue;\n break;\n }\n case 'stale-while-revalidate': {\n if (!value) break;\n const parsedValue = parseInt(value, 10);\n if (!isNaN(parsedValue)) directives.staleWhileRevalidate = parsedValue;\n break;\n }\n }\n }\n\n // s-max-age takes precedence over max-age\n if (sMaxAge !== null) directives.maxAge = sMaxAge;\n\n // if no store nothing else is relevant\n if (directives.noStore)\n return {\n noStore: true,\n noCache: false,\n mustRevalidate: false,\n immutable: false,\n maxAge: null,\n staleWhileRevalidate: null,\n };\n\n // max age does not apply to immutable resources\n if (directives.immutable)\n return {\n ...directives,\n maxAge: null,\n };\n\n return directives;\n}\n\nfunction resolveTimings(\n cacheControl: ResolvedCacheControl,\n optStaleTime?: number,\n optTTL?: number,\n): { staleTime?: number; ttl?: number } {\n let staleTime = optStaleTime;\n let ttl = optTTL;\n\n if (cacheControl.immutable)\n return {\n staleTime: Infinity,\n ttl: Infinity,\n };\n\n if (cacheControl.maxAge !== null) ttl = cacheControl.maxAge * 1000;\n\n if (cacheControl.staleWhileRevalidate !== null)\n staleTime = cacheControl.staleWhileRevalidate * 1000;\n\n // if no-cache is set, we must always revalidate\n if (cacheControl.noCache || cacheControl.mustRevalidate) staleTime = 0;\n\n if (ttl !== undefined && staleTime !== undefined && ttl < staleTime) {\n staleTime = ttl;\n }\n\n return { staleTime, ttl };\n}\n\n/**\n * Creates an `HttpInterceptorFn` that implements caching for HTTP requests. This interceptor\n * checks for a caching configuration in the request's `HttpContext` (internally set by the queryResource).\n * If caching is enabled, it attempts to retrieve responses from the cache. If a cached response\n * is found and is not stale, it's returned directly. If the cached response is stale, it's returned,\n * and a background revalidation request is made. If no cached response is found, the request\n * is made to the server, and the response is cached according to the configured TTL and staleness.\n * The interceptor also respects `Cache-Control` headers from the server.\n *\n * @param allowedMethods - An array of HTTP methods for which caching should be enabled.\n * Defaults to `['GET', 'HEAD', 'OPTIONS']`.\n *\n * @returns An `HttpInterceptorFn` that implements the caching logic.\n *\n * @example\n * // In your app.config.ts or module providers:\n *\n * import { provideHttpClient, withInterceptors } from '@angular/common/http';\n * import { createCacheInterceptor } from '@mmstack/resource';\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([createCacheInterceptor()])),\n * // ... other providers\n * ],\n * };\n */\nexport function createCacheInterceptor(\n allowedMethods = ['GET', 'HEAD', 'OPTIONS'],\n): HttpInterceptorFn {\n const CACHE_METHODS = new Set<string>(allowedMethods);\n\n return (\n req: HttpRequest<unknown>,\n next: HttpHandlerFn,\n ): Observable<HttpEvent<unknown>> => {\n const cache = injectQueryCache();\n\n if (!CACHE_METHODS.has(req.method)) return next(req);\n const opt = getCacheContext(req.context);\n\n if (!opt.cache) return next(req);\n\n const key = opt.key ?? req.urlWithParams;\n const entry = cache.getUntracked(key); // null if expired or not found\n\n // If the entry is not stale, return it\n if (entry && !entry.isStale) return of(entry.value);\n\n // resource itself handles case of showing stale data...the request must process as this will \"refresh said data\"\n\n const eTag = entry?.value.headers.get('ETag');\n const lastModified = entry?.value.headers.get('Last-Modified');\n\n if (eTag) {\n req = req.clone({ setHeaders: { 'If-None-Match': eTag } });\n }\n\n if (lastModified) {\n req = req.clone({ setHeaders: { 'If-Modified-Since': lastModified } });\n }\n\n if (opt.bustBrowserCache) {\n req = req.clone({\n setParams: { _cb: Date.now().toString() },\n });\n }\n\n return next(req).pipe(\n tap((event) => {\n if (!(event instanceof HttpResponse)) return;\n\n if (event.ok) {\n const cacheControl = parseCacheControlHeader(event);\n\n if (cacheControl.noStore && !opt.ignoreCacheControl) return;\n\n const { staleTime, ttl } = opt.ignoreCacheControl\n ? opt\n : resolveTimings(cacheControl, opt.staleTime, opt.ttl);\n\n if (opt.ttl === 0) return; // no point\n\n const parsedResponse = opt.parse\n ? new HttpResponse({\n body: opt.parse(event.body),\n headers: event.headers,\n status: event.status,\n statusText: event.statusText,\n url: event.url ?? undefined,\n })\n : event;\n\n cache.store(key, parsedResponse, staleTime, ttl, opt.persist);\n return;\n }\n\n // 304 → server confirmed our cached entry is still valid. Re-stamp the\n // existing entry so subsequent reads within the new freshness window\n // don't trigger another revalidation round-trip.\n if (event.status === 304 && entry) {\n const cacheControl = parseCacheControlHeader(event);\n const { staleTime, ttl } = opt.ignoreCacheControl\n ? opt\n : resolveTimings(cacheControl, opt.staleTime, opt.ttl);\n\n cache.store(key, entry.value, staleTime, ttl, opt.persist);\n }\n }),\n map((event) => {\n // handle 304 responses due to eTag/last-modified\n if (event instanceof HttpResponse && event.status === 304 && entry) {\n return entry.value;\n }\n\n return event;\n }),\n );\n };\n}\n","import { HttpResourceRef } from '@angular/common/http';\nimport { computed } from '@angular/core';\nimport { toWritable } from '@mmstack/primitives';\n\nexport function catchValueError<T>(\n resource: HttpResourceRef<T>,\n fallback: T,\n): HttpResourceRef<T> {\n return {\n ...resource,\n value: toWritable(\n computed(() => {\n try {\n return resource.value();\n } catch {\n return fallback;\n }\n }),\n (value) => resource.value.set(value),\n ),\n };\n}\n","import {\n computed,\n effect,\n inject,\n InjectionToken,\n Injector,\n Provider,\n Signal,\n signal,\n untracked,\n} from '@angular/core';\n\n/**\n * Represents the possible states of a circuit breaker.\n * - `CLOSED`: The circuit breaker is closed, and operations are allowed to proceed.\n * - `OPEN`: The circuit breaker is open, and operations are blocked.\n * - `HALF_OPEN`: The circuit breaker is in a half-open state, allowing a limited number of operations to test if the underlying issue is resolved.\n */\ntype CircuitBreakerState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';\n\n/**\n * Represents a circuit breaker, which monitors operations and prevents failures from cascading.\n */\nexport type CircuitBreaker = {\n /**\n * A signal indicating whether the circuit breaker is currently closed (allowing operations).\n */\n isClosed: Signal<boolean>;\n /**\n * A signal indicating whether the circuit breaker is either open or in a half-open state.\n * This is useful for checking if operations are blocked.\n * If the circuit breaker is open, operations should not proceed.\n */\n isOpen: Signal<boolean>;\n /**\n * A signal representing the current state of the circuit breaker.\n */\n status: Signal<CircuitBreakerState>;\n /**\n * Signals a failure to the circuit breaker. This may cause the circuit breaker to open.\n */\n fail: (err?: Error) => void;\n /**\n * Signals a success to the circuit breaker. This may cause the circuit breaker to close.\n */\n success: () => void;\n /**\n * Attempts to transition the circuit breaker to the half-open state. This is typically used\n * to test if the underlying issue has been resolved after the circuit breaker has been open.\n */\n halfOpen: () => void;\n /**\n * Fully resets the breaker state — clears the failure count, drops the half-open\n * flag, and lifts a permanent open caused by `shouldFailForever`. Use after the\n * underlying condition has been resolved (e.g. user re-authenticated after a\n * 401-triggered permanent open).\n */\n hardReset: () => void;\n /**\n * Destroys the circuit breaker & initiates related cleanup\n */\n destroy: () => void;\n};\n\n/**\n * Options for creating a circuit breaker.\n */\ntype CreateCircuitBreakerOptions = {\n /**\n * The number of failures that will cause the circuit breaker to open.\n * @default 5\n */\n threshold?: number;\n /**\n * @deprecated Misspelled — use `threshold` instead. Kept for backwards compatibility; will be removed in a future major.\n */\n treshold?: number;\n /**\n * The time in milliseconds after which the circuit breaker will reset and allow operations to proceed again.\n * @default 30000 (30 seconds)\n */\n timeout?: number;\n /**\n * A function that determines whether an error should cause the circuit breaker to increment the failure count.\n * @default Always returns true\n */\n shouldFail?: (err?: Error) => boolean;\n /**\n * A function that determines whether an error should cause the circuit breaker to be open forever.\n * `hardReset()` is required to lift this state.\n * @default Always returns false\n */\n shouldFailForever?: (err?: Error) => boolean;\n};\n\n/**\n * Options for creating a circuit breaker.\n * - `false`: Disables circuit breaker functionality (always open).\n * - true: Creates a new circuit breaker with default options.\n * - `CircuitBreaker`: Provides an existing `CircuitBreaker` instance to use.\n * - `{ threshold?: number; timeout?: number; }`: Creates a new circuit breaker with the specified options.\n */\nexport type CircuitBreakerOptions =\n | false\n | CircuitBreaker\n | CreateCircuitBreakerOptions;\n\n/** @internal */\nconst DEFAULT_OPTIONS: Required<\n Omit<CreateCircuitBreakerOptions, 'treshold'>\n> = {\n threshold: 5,\n timeout: 30000,\n shouldFail: () => true,\n shouldFailForever: () => false,\n};\n\n/** @internal */\nfunction internalCeateCircuitBreaker(\n threshold = 5,\n resetTimeout = 30000,\n shouldFail: (err?: Error) => boolean = () => true,\n shouldFailForever: (err?: Error) => boolean = () => false,\n): CircuitBreaker {\n const halfOpen = signal(false);\n const failureCount = signal(0);\n const failedForever = signal(false);\n\n const status = computed<CircuitBreakerState>(() => {\n if (failedForever() || failureCount() >= threshold) return 'OPEN';\n return halfOpen() ? 'HALF_OPEN' : 'CLOSED';\n });\n\n const isClosed = computed(() => status() !== 'OPEN');\n const isOpen = computed(() => status() !== 'CLOSED');\n\n const success = () => {\n failureCount.set(0);\n halfOpen.set(false);\n };\n\n const tryOnce = () => {\n if (!untracked(isOpen)) return;\n halfOpen.set(true);\n failureCount.set(threshold - 1);\n };\n\n // Auto-probe effect: schedules a half-open retry after `resetTimeout` whenever\n // the breaker is open, *unless* we've been failed forever (in which case only\n // hardReset() can recover).\n const effectRef = effect((cleanup) => {\n if (!isOpen() || failedForever()) return;\n\n const timeout = setTimeout(tryOnce, resetTimeout);\n return cleanup(() => {\n clearTimeout(timeout);\n });\n });\n\n const failInternal = () => {\n failureCount.set(failureCount() + 1);\n halfOpen.set(false);\n };\n\n const failForever = () => {\n failedForever.set(true);\n halfOpen.set(false);\n };\n\n const fail = (err?: Error) => {\n if (shouldFailForever(err)) return failForever();\n if (shouldFail(err)) return failInternal();\n // If the error does not trigger a failure, we do nothing.\n };\n\n const hardReset = () => {\n failedForever.set(false);\n failureCount.set(0);\n halfOpen.set(false);\n };\n\n return {\n status,\n isClosed,\n isOpen,\n fail,\n success,\n halfOpen: tryOnce,\n hardReset,\n destroy: () => effectRef.destroy(),\n };\n}\n\n/** @internal */\nfunction createNeverBrokenCircuitBreaker(): CircuitBreaker {\n return {\n isClosed: computed(() => true),\n isOpen: computed(() => false),\n status: signal('CLOSED'),\n fail: () => {\n // noop\n },\n success: () => {\n // noop\n },\n halfOpen: () => {\n // noop\n },\n hardReset: () => {\n // noop\n },\n destroy: () => {\n // noop\n },\n };\n}\n\nconst CB_DEFAULT_OPTIONS = new InjectionToken<\n Required<Omit<CreateCircuitBreakerOptions, 'treshold'>>\n>('MMSTACK_CIRCUIT_BREAKER_DEFAULT_OPTIONS');\n\n/**\n * Provides application-wide default options for {@link createCircuitBreaker}.\n * Any `createCircuitBreaker()` call without explicit options (or with only\n * partial options) merges these defaults in, so you can centralize threshold /\n * timeout / failure-classifier behavior in one place.\n *\n * Per-call options always win over the provided defaults.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideCircuitBreakerDefaultOptions({\n * threshold: 10,\n * timeout: 60_000,\n * shouldFailForever: (err) =>\n * err instanceof HttpErrorResponse && [401, 403].includes(err.status),\n * }),\n * ],\n * });\n * ```\n */\nexport function provideCircuitBreakerDefaultOptions(\n options: CircuitBreakerOptions,\n): Provider {\n return {\n provide: CB_DEFAULT_OPTIONS,\n useValue: {\n ...DEFAULT_OPTIONS,\n ...normalizeThreshold(options),\n },\n };\n}\n\nfunction injectCircuitBreakerOptions(\n injector = inject(Injector),\n): Required<Omit<CreateCircuitBreakerOptions, 'treshold'>> {\n return injector.get(CB_DEFAULT_OPTIONS, DEFAULT_OPTIONS, {\n optional: true,\n });\n}\n\n/** @internal — strips the deprecated `treshold` field and folds it into `threshold` */\nfunction normalizeThreshold(\n opt: CircuitBreakerOptions | undefined,\n): Partial<Omit<CreateCircuitBreakerOptions, 'treshold'>> {\n if (!opt || typeof opt !== 'object' || 'isClosed' in opt) return {};\n const { treshold, threshold, ...rest } = opt;\n return {\n ...rest,\n threshold: threshold ?? treshold,\n };\n}\n\n/**\n * Creates a circuit breaker instance.\n *\n * @param options - Configuration options for the circuit breaker. Can be:\n * - `undefined`: Uses defaults (threshold: 5, timeout: 30000ms) or provided defaults via {@link provideCircuitBreakerDefaultOptions}.\n * - `false`: Creates a \"no-op\" circuit breaker that is always closed (never trips).\n * - `true`: Creates a circuit breaker with default settings.\n * - `CircuitBreaker`: Reuses an existing `CircuitBreaker` instance.\n * - `{ threshold?: number; timeout?: number; }`: Creates a circuit breaker with the specified threshold and timeout.\n *\n * @returns A `CircuitBreaker` instance.\n *\n * @example\n * // Create a circuit breaker with default settings:\n * const breaker = createCircuitBreaker();\n *\n * // Create a circuit breaker with custom settings:\n * const customBreaker = createCircuitBreaker({ threshold: 10, timeout: 60000 });\n *\n * // Share a single circuit breaker instance across multiple resources:\n * const sharedBreaker = createCircuitBreaker();\n * const resource1 = queryResource(..., { circuitBreaker: sharedBreaker });\n * const resource2 = mutationResource(..., { circuitBreaker: sharedBreaker });\n */\nexport function createCircuitBreaker(\n opt?: CircuitBreakerOptions,\n injector?: Injector,\n): CircuitBreaker {\n if (opt === false) return createNeverBrokenCircuitBreaker();\n\n if (typeof opt === 'object' && 'isClosed' in opt) return opt;\n\n const { threshold, timeout, shouldFail, shouldFailForever } = {\n ...injectCircuitBreakerOptions(injector),\n ...normalizeThreshold(opt),\n };\n\n return internalCeateCircuitBreaker(\n threshold,\n timeout,\n shouldFail,\n shouldFailForever,\n );\n}\n","// Heavily inspired by: https://dev.to/kasual1/request-deduplication-in-angular-3pd8\n\nimport {\n HttpContext,\n HttpContextToken,\n HttpInterceptorFn,\n type HttpEvent,\n type HttpHandlerFn,\n type HttpRequest,\n} from '@angular/common/http';\nimport { finalize, shareReplay, type Observable } from 'rxjs';\n\nconst NO_DEDUPE = new HttpContextToken<boolean>(() => false);\n\n/**\n * Disables request deduplication for a specific HTTP request.\n *\n * @param ctx - The `HttpContext` to modify. If not provided, a new `HttpContext` is created.\n * @returns The modified `HttpContext` with the `NO_DEDUPE` token set to `true`.\n *\n * @example\n * // Disable deduplication for a specific POST request:\n * const context = noDedupe();\n * this.http.post('/api/data', payload, { context }).subscribe(...);\n *\n * // Disable deduplication, modifying an existing context:\n * let context = new HttpContext();\n * context = noDedupe(context);\n * this.http.post('/api/data', payload, { context }).subscribe(...);\n */\nexport function noDedupe(ctx: HttpContext = new HttpContext()) {\n return ctx.set(NO_DEDUPE, true);\n}\n\n/**\n * Creates an `HttpInterceptorFn` that deduplicates identical HTTP requests.\n * If multiple identical requests (same URL and parameters) are made concurrently,\n * only the first request will be sent to the server. Subsequent requests will\n * receive the response from the first request.\n *\n * @param allowed - An array of HTTP methods for which deduplication should be enabled.\n * Defaults to `['GET', 'DELETE', 'HEAD', 'OPTIONS']`.\n *\n * @returns An `HttpInterceptorFn` that implements the request deduplication logic.\n *\n * @example\n * // In your app.config.ts or module providers:\n * import { provideHttpClient, withInterceptors } from '@angular/common/http';\n * import { createDedupeRequestsInterceptor } from './your-dedupe-interceptor';\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([createDedupeRequestsInterceptor()])),\n * // ... other providers\n * ],\n * };\n *\n * // You can also specify which methods should be deduped\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([createDedupeRequestsInterceptor(['GET'])])), // only dedupe GET calls\n * // ... other providers\n * ],\n * };\n */\nexport function createDedupeRequestsInterceptor(\n allowed = ['GET', 'DELETE', 'HEAD', 'OPTIONS'],\n): HttpInterceptorFn {\n const inFlight = new Map<string, Observable<HttpEvent<unknown>>>();\n\n const DEDUPE_METHODS = new Set<string>(allowed);\n\n return (\n req: HttpRequest<unknown>,\n next: HttpHandlerFn,\n ): Observable<HttpEvent<unknown>> => {\n if (!DEDUPE_METHODS.has(req.method) || req.context.get(NO_DEDUPE))\n return next(req);\n\n const found = inFlight.get(req.urlWithParams);\n\n if (found) return found;\n\n const request = next(req).pipe(\n finalize(() => inFlight.delete(req.urlWithParams)),\n shareReplay(),\n );\n inFlight.set(req.urlWithParams, request);\n\n return request;\n };\n}\n","import {\n HttpContext,\n HttpHeaders,\n HttpParams,\n HttpResourceRequest,\n} from '@angular/common/http';\nimport { type ValueEqualityFn } from '@angular/core';\n\ntype UnknownObject = Record<PropertyKey, unknown>;\n\n/**\n * Checks if `value` is a plain JavaScript object (e.g., `{}` or `new Object()`).\n * Distinguishes from arrays, null, and class instances. Acts as a type predicate,\n * narrowing `value` to `UnknownObject` if `true`.\n *\n * @param value The value to check.\n * @returns {value is UnknownObject} `true` if `value` is a plain object, otherwise `false`.\n * @example\n * isPlainObject({}) // => true\n * isPlainObject([]) // => false\n * isPlainObject(null) // => false\n * isPlainObject(new Date()) // => false\n */\nfunction isPlainObject(value: unknown): value is UnknownObject {\n if (value === null || typeof value !== 'object') return false;\n const proto = Object.getPrototypeOf(value);\n if (proto === null) return false; // remove Object.create(null);\n return proto === Object.prototype;\n}\n\n/**\n * Internal helper to generate a stable JSON string from an array.\n * Sorts keys of plain objects within the array alphabetically before serialization\n * to ensure hash stability regardless of key order.\n *\n * @param queryKey The array of values to serialize.\n * @returns A stable JSON string representation.\n * @internal\n */\nfunction hashKey(queryKey: unknown[]): string {\n return JSON.stringify(queryKey, (_, val) =>\n isPlainObject(val)\n ? Object.keys(val)\n .toSorted()\n .reduce((result, key) => {\n result[key] = val[key];\n return result;\n }, {} as UnknownObject)\n : val,\n );\n}\n\n/**\n * Generates a stable, unique string hash from one or more arguments.\n * Useful for creating cache keys or identifiers where object key order shouldn't matter.\n *\n * How it works:\n * - Plain objects within the arguments have their keys sorted alphabetically before hashing.\n * This ensures that `{ a: 1, b: 2 }` and `{ b: 2, a: 1 }` produce the same hash.\n * - Uses `JSON.stringify` internally with custom sorting for plain objects via `hashKey`.\n * - Non-plain objects (arrays, Dates, etc.) and primitives are serialized naturally.\n *\n * @param {...unknown} args Values to include in the hash.\n * @returns A stable string hash representing the input arguments.\n * @example\n * const userQuery = (id: number) => ['user', { id, timestamp: Date.now() }];\n *\n * const obj1 = { a: 1, b: 2 };\n * const obj2 = { b: 2, a: 1 }; // Same keys/values, different order\n *\n * hash('posts', 10);\n * // => '[\"posts\",10]'\n *\n * hash('config', obj1);\n * // => '[\"config\",{\"a\":1,\"b\":2}]'\n *\n * hash('config', obj2);\n * // => '[\"config\",{\"a\":1,\"b\":2}]' (Same as above due to key sorting)\n *\n * hash(['todos', { status: 'done', owner: obj1 }]);\n * // => '[[\"todos\",{\"owner\":{\"a\":1,\"b\":2},\"status\":\"done\"}]]'\n *\n * // Be mindful of values JSON.stringify cannot handle (functions, undefined, Symbols)\n * // hash('a', undefined, function() {}) => '[\"a\",null,null]'\n */\nfunction hash(...args: unknown[]): string {\n return hashKey(args);\n}\n\nfunction equalTransferCache(\n a: HttpResourceRequest['transferCache'],\n b: HttpResourceRequest['transferCache'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n if (typeof a !== typeof b) return false;\n if (typeof a === 'boolean' || typeof b === 'boolean') return a === b;\n\n if (!a.includeHeaders && !b.includeHeaders) return true;\n if (!a.includeHeaders || !b.includeHeaders) return false;\n\n if (a.includeHeaders.length !== b.includeHeaders.length) return false;\n\n if (a.includeHeaders.length === 0) return true;\n\n const aSet = new Set(a.includeHeaders ?? []);\n\n return b.includeHeaders.every((header) => aSet.has(header));\n}\n\nfunction equalParamArray(\n a: Array<string | number | boolean>,\n b: Array<string | number | boolean>,\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n if (a.length !== b.length) return false;\n\n return a.every((value) => b.includes(value));\n}\n\nfunction headersToObject(headerClass: HttpHeaders) {\n const headers: Exclude<\n Required<HttpResourceRequest['headers']>,\n HttpHeaders | undefined\n > = {};\n\n headerClass.keys().forEach((key) => {\n const value = headerClass.getAll(key);\n if (value === null) return;\n if (value.length === 1) {\n headers[key] = value[0];\n } else {\n headers[key] = value;\n }\n });\n\n return headers;\n}\n\nfunction paramToObject(paramsClass: HttpParams) {\n const params: Exclude<\n Required<HttpResourceRequest['params']>,\n HttpParams | undefined\n > = {};\n\n paramsClass.keys().forEach((key) => {\n const value = paramsClass.getAll(key);\n if (value === null) return;\n if (value.length === 1) {\n params[key] = value[0];\n } else {\n params[key] = value;\n }\n });\n\n return params;\n}\n\nfunction equalParams(\n a: HttpResourceRequest['params'],\n b: HttpResourceRequest['params'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n const aObj = a instanceof HttpParams ? paramToObject(a) : a;\n const bObj = b instanceof HttpParams ? paramToObject(b) : b;\n\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n if (aKeys.length !== bKeys.length) return false;\n\n return aKeys.every((key) => {\n if (Array.isArray(aObj[key]) || Array.isArray(bObj[key])) {\n return equalParamArray(\n Array.isArray(aObj[key]) ? aObj[key] : [aObj[key]],\n Array.isArray(bObj[key]) ? bObj[key] : [bObj[key]],\n );\n }\n\n return aObj[key] === bObj[key];\n });\n}\n\nfunction equalBody(\n a: HttpResourceRequest['body'],\n b: HttpResourceRequest['body'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n return hash(a) === hash(b);\n}\n\nfunction equalHeaders(\n a: HttpResourceRequest['headers'],\n b: HttpResourceRequest['headers'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n const aObj = a instanceof HttpHeaders ? headersToObject(a) : a;\n const bObj = b instanceof HttpHeaders ? headersToObject(b) : b;\n\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n if (aKeys.length !== bKeys.length) return false;\n return aKeys.every((key) => {\n if (Array.isArray(aObj[key]) || Array.isArray(bObj[key])) {\n return equalParamArray(\n Array.isArray(aObj[key]) ? aObj[key] : [aObj[key]],\n Array.isArray(bObj[key]) ? bObj[key] : [bObj[key]],\n );\n }\n\n return aObj[key] === bObj[key];\n });\n}\n\nfunction toHttpContextEntries(ctx: HttpResourceRequest['context']) {\n if (!ctx) return [];\n\n if (ctx instanceof HttpContext) {\n const tokens = Array.from(ctx.keys());\n return tokens.map((key) => [key.toString(), ctx.get(key)] as const);\n }\n\n if (typeof ctx === 'object') {\n return Object.entries(ctx) as Array<[string, unknown]>;\n }\n\n return [];\n}\n\nfunction equalContext(\n a: HttpResourceRequest['context'],\n b: HttpResourceRequest['context'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n const aEntries = toHttpContextEntries(a);\n const bEntries = toHttpContextEntries(b);\n if (aEntries.length !== bEntries.length) return false;\n if (aEntries.length === 0) return true;\n const bMap = new Map(bEntries);\n return aEntries.every(([key, value]) => value === bMap.get(key));\n}\n\nexport function createEqualRequest<TResult>(\n equalResult?: ValueEqualityFn<TResult>,\n) {\n const eqb = equalResult ?? equalBody;\n\n return (\n a: Partial<HttpResourceRequest> | undefined,\n b: Partial<HttpResourceRequest> | undefined,\n ) => {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n if (a.url !== b.url) return false;\n if (a.method !== b.method) return false;\n if (!equalParams(a.params, b.params)) return false;\n if (!equalHeaders(a.headers, b.headers)) return false;\n if (!eqb(a.body as TResult, b.body as TResult)) return false;\n if (!equalContext(a.context, b.context)) return false;\n\n if (a.withCredentials !== b.withCredentials) return false;\n if (a.reportProgress !== b.reportProgress) return false;\n if (!equalTransferCache(a.transferCache, b.transferCache)) return false;\n\n return true;\n };\n}\n","export function hasSlowConnection() {\n if (\n window &&\n 'navigator' in window &&\n 'connection' in window.navigator &&\n typeof window.navigator.connection === 'object' &&\n !!window.navigator.connection &&\n 'effectiveType' in window.navigator.connection &&\n typeof window.navigator.connection.effectiveType === 'string'\n )\n return window.navigator.connection.effectiveType.endsWith('2g');\n\n return false;\n}\n","import { type HttpHeaders, type HttpResourceRef } from '@angular/common/http';\nimport {\n linkedSignal,\n type Signal,\n type ValueEqualityFn,\n type WritableSignal,\n} from '@angular/core';\n\nfunction persist<T>(\n value: WritableSignal<T>,\n equal?: ValueEqualityFn<T>,\n): WritableSignal<T>;\n\nfunction persist<T>(value: Signal<T>, equal?: ValueEqualityFn<T>): Signal<T>;\n\nfunction persist<T>(\n src: WritableSignal<T> | Signal<T>,\n equal?: ValueEqualityFn<T>,\n): WritableSignal<T> | Signal<T> {\n // linkedSignal allows us to access previous source value\n\n const persisted = linkedSignal<T, T>({\n source: () => src(),\n computation: (next, prev) => {\n if (next === undefined && prev !== undefined) return prev.value;\n return next;\n },\n equal,\n });\n\n // if original value was WritableSignal then override linkedSignal methods to original...angular uses linkedSignal under the hood in ResourceImpl, this applies to that.\n if ('set' in src) {\n persisted.set = src.set;\n persisted.update = src.update;\n persisted.asReadonly = src.asReadonly;\n }\n\n return persisted;\n}\n\nexport function persistResourceValues<T>(\n resource: HttpResourceRef<T>,\n shouldPersist = false,\n equal?: ValueEqualityFn<T>,\n): HttpResourceRef<T> {\n if (!shouldPersist) return resource;\n\n return {\n ...resource,\n statusCode: persist<number | undefined>(resource.statusCode),\n headers: persist<HttpHeaders | undefined>(resource.headers),\n value: persist<T>(resource.value, equal),\n };\n}\n","import { HttpResourceRef } from '@angular/common/http';\nimport { DestroyRef } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { interval } from 'rxjs';\n\n// refresh resource every n miliseconds or don't refresh if undefined provided. 0 also excluded, due to it not being a valid usecase\nexport function refresh<T>(\n resource: HttpResourceRef<T>,\n destroyRef: DestroyRef,\n refresh?: number,\n): HttpResourceRef<T> {\n if (!refresh) return resource; // no refresh requested\n\n // we can use RxJs here as reloading the resource will always be a side effect & as such does not impact the reactive graph in any way.\n let sub = interval(refresh)\n .pipe(takeUntilDestroyed(destroyRef))\n .subscribe(() => resource.reload());\n\n const reload = (): boolean => {\n sub.unsubscribe(); // do not conflict with manual reload\n\n const hasReloaded = resource.reload();\n\n // resubscribe after manual reload\n sub = interval(refresh)\n .pipe(takeUntilDestroyed(destroyRef))\n .subscribe(() => resource.reload());\n\n return hasReloaded;\n };\n\n return {\n ...resource,\n reload,\n destroy: () => {\n sub.unsubscribe();\n resource.destroy();\n },\n };\n}\n","import { type HttpResourceRef } from '@angular/common/http';\nimport { effect, untracked } from '@angular/core';\n\nexport type RetryOptions =\n | number\n | {\n max?: number;\n backoff?: number;\n };\n\n/**\n * Callback fired by the retry wrapper for every failed attempt.\n * `retryCount` is the number of retries that already happened before this\n * error (`0` on the original failure, `1` after the first retry, etc.).\n * `isFinal` is `true` when no further retry will be scheduled — either because\n * retries are exhausted or `retry` was unset/0.\n */\nexport type RetryErrorCallback<TError = unknown> = (\n err: TError,\n retryCount: number,\n isFinal: boolean,\n) => void;\n\n// Retry on error, if number is provided it will retry that many times with exponential backoff, otherwise it will use the options provided\nexport function retryOnError<T>(\n res: HttpResourceRef<T>,\n opt?: RetryOptions,\n onError?: RetryErrorCallback,\n): HttpResourceRef<T> {\n const max = opt ? (typeof opt === 'number' ? opt : (opt.max ?? 0)) : 0;\n const backoff = typeof opt === 'object' ? (opt.backoff ?? 1000) : 1000;\n\n let retries = 0;\n\n let timeout: ReturnType<typeof setTimeout> | undefined;\n\n const handleError = () => {\n const err = untracked(res.error);\n const isFinal = retries >= max;\n\n onError?.(err, retries, isFinal);\n\n if (isFinal) return;\n\n retries++;\n\n if (timeout) clearTimeout(timeout);\n\n setTimeout(\n () => res.reload(),\n retries <= 0 ? 0 : backoff * Math.pow(2, retries - 1),\n );\n };\n\n const onSuccess = () => {\n if (timeout) clearTimeout(timeout);\n retries = 0;\n };\n\n const ref = effect(() => {\n switch (res.status()) {\n case 'error':\n return handleError();\n case 'resolved':\n return onSuccess();\n }\n });\n\n return {\n ...res,\n destroy: () => {\n ref.destroy(); // cleanup on manual destroy\n res.destroy();\n },\n };\n}\n","import { inject, Injectable } from '@angular/core';\nimport { sensor } from '@mmstack/primitives';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ResourceSensors {\n readonly networkStatus = sensor('networkStatus');\n}\n\nexport function injectNetworkStatus() {\n return inject(ResourceSensors).networkStatus;\n}\n","import { HttpResourceRef } from '@angular/common/http';\n\nexport function toResourceObject<T>(\n res: HttpResourceRef<T>,\n): HttpResourceRef<T> {\n return {\n asReadonly: () => res.asReadonly(),\n destroy: () => res.destroy(),\n error: res.error,\n headers: res.headers,\n isLoading: res.isLoading,\n progress: res.progress,\n status: res.status,\n statusCode: res.statusCode,\n value: res.value,\n reload: () => res.reload(),\n hasValue: (() => res.hasValue()) as HttpResourceRef<T>['hasValue'],\n set: (v) => res.set(v),\n update: (v) => res.update(v),\n };\n}\n","import { HttpParams, type HttpResourceRequest } from '@angular/common/http';\n\nfunction normalizeParams(\n params: Required<HttpResourceRequest>['params'],\n): string {\n if (params instanceof HttpParams) return params.toString();\n\n const paramMap = new Map<string, string>();\n\n for (const [key, value] of Object.entries(params)) {\n if (Array.isArray(value)) {\n paramMap.set(key, value.map(encodeURIComponent).join(','));\n } else {\n paramMap.set(key, encodeURIComponent(value.toString()));\n }\n }\n\n return Array.from(paramMap.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, value]) => `${key}=${value}`)\n .join('&');\n}\n\nexport function urlWithParams(req: HttpResourceRequest): string {\n if (!req.params) return req.url;\n\n return `${req.url}?${normalizeParams(req.params)}`;\n}\n","import {\n HttpClient,\n HttpHeaders,\n httpResource,\n HttpResponse,\n type HttpResourceOptions,\n type HttpResourceRef,\n type HttpResourceRequest,\n} from '@angular/common/http';\nimport {\n computed,\n DestroyRef,\n effect,\n inject,\n isDevMode,\n linkedSignal,\n Signal,\n untracked,\n WritableSignal,\n} from '@angular/core';\nimport { toWritable } from '@mmstack/primitives';\nimport { firstValueFrom } from 'rxjs';\nimport {\n catchValueError,\n CircuitBreakerOptions,\n createCircuitBreaker,\n createEqualRequest,\n hasSlowConnection,\n injectNetworkStatus,\n injectQueryCache,\n persistResourceValues,\n refresh,\n retryOnError,\n setCacheContext,\n toResourceObject,\n urlWithParams,\n type RetryOptions,\n} from './util';\nimport { CacheEntry } from './util/cache/cache';\n\n/**\n * Options for configuring caching behavior of a `queryResource`.\n * - `true`: Enables caching with default settings.\n * - `{ ttl?: number; staleTime?: number; hash?: (req: HttpResourceRequest) => string; }`: Configures caching with custom settings.\n */\ntype ResourceCacheOptions =\n | true\n | {\n /**\n * The Time To Live (TTL) for the cached data, in milliseconds. After this time, the cached data is\n * considered expired and will be refetched.\n */\n ttl?: number;\n /**\n * The duration, in milliseconds, during which stale data can be served while a revalidation request\n * is made in the background.\n */\n staleTime?: number;\n /**\n * A custom function to generate the cache key. Defaults to using the request URL with parameters.\n * Provide a custom hash function if you need more control over how cache keys are generated,\n * for instance, to ignore certain query parameters or to use request body for the cache key.\n */\n hash?: (req: HttpResourceRequest) => string;\n /**\n * Whether to bust the browser cache by appending a unique query parameter to the request URL.\n * This is useful for ensuring that the latest data is fetched from the server, bypassing any\n * cached responses in the browser. The unique parameter is removed before calling the cache function, so it does not affect the cache key.\n * @default false - By default, the resource will not bust the browser cache.\n */\n bustBrowserCache?: boolean;\n /**\n * Whether to ignore the `Cache-Control` headers from the server when caching responses.\n * If set to `true`, the resource will not respect any cache directives from the server,\n * allowing you to control caching behavior entirely through the resource options.\n * @default false - By default the resource will respect `Cache-Control` headers.\n */\n ignoreCacheControl?: boolean;\n /**\n * Whether to persist the cache entry in the local DB instance.\n * @default false - By default, the cache entry is not persisted.\n */\n persist?: boolean;\n };\n\n/**\n * Options for configuring a `queryResource`.\n */\nexport type QueryResourceOptions<TResult, TRaw = TResult> = HttpResourceOptions<\n TResult,\n TRaw\n> & {\n /**\n * Whether to keep the previous value of the resource while a refresh is in progress.\n * Defaults to `false`. Also keeps status & headers while refreshing.\n */\n keepPrevious?: boolean;\n /**\n * The refresh interval, in milliseconds. If provided, the resource will automatically\n * refresh its data at the specified interval.\n */\n refresh?: number;\n /**\n * Options for retrying failed requests.\n */\n retry?: RetryOptions;\n /**\n * Called on every failed attempt, including each retry.\n *\n * @param err - The error from the underlying HTTP request.\n * @param retryCount - The number of retries that already happened before\n * this error (`0` on the original failure, `1` after the first retry, etc.).\n * @param isFinal - `true` when no further retry will be scheduled — either\n * because retries are exhausted or `retry` was unset/0. Branch on this for\n * \"user actually needs to know\" side effects (toasts, error reporting).\n */\n onError?: (err: unknown, retryCount: number, isFinal: boolean) => void;\n /**\n * Options for configuring a circuit breaker for the resource.\n */\n circuitBreaker?: CircuitBreakerOptions | true;\n /**\n * Options for enabling and configuring caching for the resource.\n */\n cache?: ResourceCacheOptions;\n /**\n * Trigger a request every time the request function is triggered, even if the request parameters are the same.\n * @default false\n */\n triggerOnSameRequest?: boolean;\n};\n\n/**\n * The reason a query resource is currently in the `disabled` state, or `null`\n * if it is enabled. Useful for branching UI on cause (e.g. \"offline\" vs\n * \"circuit tripped\" vs \"nothing to fetch yet\").\n */\nexport type DisabledReason = 'offline' | 'circuit-open' | 'no-request';\n\n/**\n * Represents a resource created by `queryResource`. Extends `HttpResourceRef` with additional properties.\n */\nexport type QueryResourceRef<TResult> = Omit<\n HttpResourceRef<TResult>,\n 'headers' | 'statusCode'\n> & {\n /**\n * Linkedsignal of the response headers, when available.\n */\n readonly headers: WritableSignal<HttpHeaders | undefined>;\n /**\n * Linkedsignal of the response status code, when available.\n */\n readonly statusCode: WritableSignal<number | undefined>;\n /**\n * A signal indicating whether the resource is currently disabled (due to circuit breaker, offline, or undefined request).\n */\n disabled: Signal<boolean>;\n /**\n * Why the resource is currently disabled, or `null` if it is enabled.\n * Maps to one of: `'offline'`, `'circuit-open'`, `'no-request'`.\n */\n disabledReason: Signal<DisabledReason | null>;\n /**\n * Prefetches data for the resource, populating the cache if caching is enabled. This can be\n * used to proactively load data before it's needed. If a slow connection is detected, prefetching is skipped.\n *\n * @param req - Optional partial request parameters to use for the prefetch. This allows you\n * to prefetch data with different parameters than the main resource request.\n */\n prefetch: (req?: Partial<HttpResourceRequest> | string) => Promise<void>;\n};\n\n/**\n * Creates an HTTP resource with features like caching, retries, refresh intervals, circuit breaker, and optimistic updates. Without additional options it is equivalent to simply calling `httpResource`.\n * This overload is for when a `defaultValue` is provided, ensuring that the resource's value is always defined.\n * @param request A function that returns the `HttpResourceRequest` or a URL string to be made. This function\n * is called reactively, so the request can change over time. If the function\n * returns `undefined`, the resource is considered \"disabled\" and no request will be made.\n * @param options Configuration options for the resource. These options extend the basic\n * `HttpResourceOptions` and add features like `keepPrevious`, `refresh`, `retry`,\n * `onError`, `circuitBreaker`, and `cache`. Additionally, when a `defaultValue` is provided, the resource's value will always be defined, even if the underlying HTTP request fails or is disabled.\n * @returns An `QueryResourceRef` instance, which extends the basic `HttpResourceRef` with additional features.\n */\nexport function queryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | string | undefined | void,\n options: QueryResourceOptions<TResult, TRaw> & {\n defaultValue: NoInfer<TResult>;\n },\n): QueryResourceRef<TResult>;\n\n/**\n * Creates an extended HTTP resource with features like caching, retries, refresh intervals,\n * circuit breaker, and optimistic updates. Without additional options it is equivalent to simply calling `httpResource`.\n *\n * @param request A function that returns the `HttpResourceRequest` or a URL string to be made. This function\n * is called reactively, so the request can change over time. If the function\n * returns `undefined`, the resource is considered \"disabled\" and no request will be made.\n * @param options Configuration options for the resource. These options extend the basic\n * `HttpResourceOptions` and add features like `keepPrevious`, `refresh`, `retry`,\n * `onError`, `circuitBreaker`, and `cache`.\n * @returns An `QueryResourceRef` instance, which extends the basic `HttpResourceRef` with additional features.\n */\nexport function queryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | string | undefined | void,\n options?: QueryResourceOptions<TResult, TRaw>,\n): QueryResourceRef<TResult | undefined>;\n\nexport function queryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | string | undefined | void,\n options?: QueryResourceOptions<TResult, TRaw>,\n): QueryResourceRef<TResult | undefined> {\n const cache = injectQueryCache<TResult>(options?.injector);\n\n const destroyRef = options?.injector\n ? options.injector.get(DestroyRef)\n : inject(DestroyRef);\n\n const cb = createCircuitBreaker(\n options?.circuitBreaker === true\n ? undefined\n : (options?.circuitBreaker ?? false),\n options?.injector,\n );\n\n const networkAvailable = injectNetworkStatus();\n\n const eq = options?.triggerOnSameRequest\n ? undefined\n : createEqualRequest(options?.equal);\n\n const rawRequest = computed(() => request() ?? undefined);\n\n const disabledReason = computed<DisabledReason | null>(() => {\n if (!networkAvailable()) return 'offline';\n if (cb.isOpen()) return 'circuit-open';\n if (!rawRequest()) return 'no-request';\n return null;\n });\n\n const stableRequest = computed(\n (): HttpResourceRequest | undefined => {\n if (disabledReason() !== null) return undefined;\n const req = rawRequest();\n if (!req) return undefined;\n if (typeof req === 'string') return { method: 'GET', url: req };\n return req;\n },\n {\n equal: (a, b) => {\n if (eq) return eq(a, b);\n return a === b;\n },\n },\n );\n\n const hashFn =\n typeof options?.cache === 'object'\n ? (options.cache.hash ?? urlWithParams)\n : urlWithParams;\n\n const staleTime =\n typeof options?.cache === 'object' ? options.cache.staleTime : 0;\n const ttl =\n typeof options?.cache === 'object' ? options.cache.ttl : undefined;\n\n const cacheKey = computed(() => {\n const r = stableRequest();\n if (!r) return null;\n return hashFn(r);\n });\n\n const bustBrowserCache =\n typeof options?.cache === 'object' &&\n options.cache.bustBrowserCache === true;\n\n const ignoreCacheControl =\n typeof options?.cache === 'object' &&\n options.cache.ignoreCacheControl === true;\n\n const persist =\n typeof options?.cache === 'object' && options.cache.persist === true;\n\n const cachedRequest = options?.cache\n ? computed(() => {\n const r = stableRequest();\n if (!r) return r;\n\n return {\n ...r,\n context: setCacheContext(r.context, {\n staleTime,\n ttl,\n key: cacheKey() ?? hashFn(r),\n bustBrowserCache,\n ignoreCacheControl,\n persist,\n }),\n };\n })\n : stableRequest;\n\n let resource = toResourceObject(\n httpResource<TResult>(cachedRequest, {\n ...options,\n parse: options?.parse as any, // Not my favorite thing to do, but here it is completely safe.\n }) as HttpResourceRef<TResult>,\n );\n\n resource = catchValueError(resource, options?.defaultValue as TResult);\n\n // get full HttpResonse from Cache\n const cachedEvent = cache.getEntryOrKey(cacheKey);\n\n const cacheEntry = linkedSignal<\n CacheEntry<HttpResponse<TResult>> | string | null,\n { key: string; value: TResult | null } | null\n >({\n source: () => cachedEvent(),\n computation: (entry, prev) => {\n if (!entry) return null;\n\n if (\n typeof entry === 'string' &&\n prev &&\n prev.value !== null &&\n prev.value.key === entry\n ) {\n return prev.value;\n }\n\n if (typeof entry === 'string') return { key: entry, value: null };\n\n if (!(entry.value instanceof HttpResponse))\n return { key: entry.key, value: null };\n\n return {\n value: entry.value.body,\n key: entry.key,\n };\n },\n });\n\n resource = refresh(resource, destroyRef, options?.refresh);\n resource = retryOnError(resource, options?.retry, options?.onError);\n\n resource = persistResourceValues<TResult>(\n resource,\n options?.keepPrevious,\n options?.equal,\n );\n\n const value = options?.cache\n ? toWritable(\n computed((): TResult => {\n resource.value();\n return cacheEntry()?.value ?? resource.value();\n }),\n resource.value.set,\n resource.value.update,\n )\n : resource.value;\n\n // iterate circuit breaker state, is effect as a computed would cause a circular dependency (resource -> cb -> resource)\n const cbEffectRef = effect(() => {\n const status = resource.status();\n if (status === 'error')\n cb.fail(untracked(resource.error) as Error | undefined);\n else if (status === 'resolved') cb.success();\n });\n\n const set = (value: TResult) => {\n resource.value.set(value);\n const k = untracked(cacheKey);\n if (options?.cache && k)\n cache.store(\n k,\n new HttpResponse({\n body: value,\n status: 200,\n statusText: 'OK',\n }),\n staleTime,\n ttl,\n persist,\n );\n };\n\n const update = (updater: (value: TResult) => TResult) => {\n set(updater(untracked(resource.value)));\n };\n\n const client = options?.injector\n ? options.injector.get(HttpClient)\n : inject(HttpClient);\n\n return {\n ...resource,\n value,\n set,\n update,\n statusCode: linkedSignal(resource.statusCode),\n headers: linkedSignal(resource.headers),\n disabled: computed(() => disabledReason() !== null),\n disabledReason,\n reload: () => {\n cb.halfOpen(); // open the circuit for manual reload\n return resource.reload();\n },\n destroy: () => {\n cbEffectRef.destroy();\n cb.destroy();\n resource.destroy();\n },\n prefetch: async (partial) => {\n if (!options?.cache || hasSlowConnection()) return Promise.resolve();\n\n const request = untracked(stableRequest);\n\n const partialReq =\n typeof partial === 'string' ? { method: 'GET', url: partial } : partial;\n\n const prefetchRequest = {\n ...request,\n ...partialReq,\n };\n if (!prefetchRequest.url) return Promise.resolve();\n\n const key = hashFn({\n ...prefetchRequest,\n url: prefetchRequest.url ?? '',\n });\n\n const found = cache.getUntracked(key);\n if (found && !found.isStale) return Promise.resolve();\n\n try {\n await firstValueFrom(\n client.request(prefetchRequest.method ?? 'GET', prefetchRequest.url, {\n ...prefetchRequest,\n credentials: prefetchRequest.credentials as\n | RequestCredentials\n | undefined,\n priority: prefetchRequest.priority as RequestPriority | undefined,\n cache: prefetchRequest.cache as RequestCache | undefined,\n mode: prefetchRequest.mode as RequestMode | undefined,\n redirect: prefetchRequest.redirect as RequestRedirect | undefined,\n context: setCacheContext(prefetchRequest.context, {\n staleTime,\n ttl,\n key: hashFn({\n ...prefetchRequest,\n url: prefetchRequest.url ?? '',\n }),\n bustBrowserCache,\n ignoreCacheControl,\n persist,\n }),\n headers: prefetchRequest.headers as HttpHeaders,\n observe: 'response',\n }),\n );\n\n return;\n } catch (err) {\n if (isDevMode()) console.error('Prefetch failed: ', err);\n return;\n }\n },\n };\n}\n","import { HttpResourceRequest } from '@angular/common/http';\nimport { computed, inject, Injector, signal, untracked } from '@angular/core';\nimport { nestedEffect } from '@mmstack/primitives';\nimport {\n queryResource,\n QueryResourceOptions,\n QueryResourceRef,\n} from './query-resource';\n\n/**\n * A reference to a manually triggered query resource. This type extends the standard `QueryResourceRef`\n * with an additional `trigger` method that allows you to manually trigger the resource request.\n * @see QueryResourceRef\n */\nexport type ManualQueryResourceRef<TResult> = QueryResourceRef<TResult> & {\n trigger: (\n req?: HttpResourceRequest | string,\n injector?: Injector,\n ) => Promise<TResult>;\n};\n\n/**\n * Creates a manually triggered HTTP resource with features like caching, retries, refresh intervals, circuit breaker, and optimistic updates. Without additional options it is equivalent to simply calling `httpResource`.\n * This overload is for when a `defaultValue` is provided, ensuring that the resource's value is always defined.\n * @param request A function that returns the `HttpResourceRequest` or a URL string to be made. This function\n * is called reactively, so the request can change over time. If the function\n * returns `undefined`, the resource is considered \"disabled\" and no request will be made.\n * @param options Configuration options for the resource. These options extend the basic\n * `HttpResourceOptions` and add features like `keepPrevious`, `refresh`, `retry`,\n * `onError`, `circuitBreaker`, and `cache`. Additionally, when a `defaultValue` is provided, the resource's value will always be defined, even if the underlying HTTP request fails or is disabled.\n * @returns An `ManualQueryResourceRef` instance, which extends the basic `QueryResourceRef` with additional features.\n */\nexport function manualQueryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | string | undefined | void,\n options: QueryResourceOptions<TResult, TRaw> & {\n defaultValue: NoInfer<TResult>;\n },\n): ManualQueryResourceRef<TResult>;\n\n/**\n * Creates a manually triggered extended HTTP resource with features like caching, retries, refresh intervals,\n * circuit breaker, and optimistic updates. Without additional options it is equivalent to simply calling `httpResource`.\n *\n * @param request A function that returns the `HttpResourceRequest` or a URL string to be made. This function\n * is called reactively, so the request can change over time. If the function\n * returns `undefined`, the resource is considered \"disabled\" and no request will be made.\n * @param options Configuration options for the resource. These options extend the basic\n * `HttpResourceOptions` and add features like `keepPrevious`, `refresh`, `retry`,\n * `onError`, `circuitBreaker`, and `cache`.\n * @returns An `ManualQueryResourceRef` instance, which extends the basic `QueryResourceRef` with additional features.\n */\nexport function manualQueryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | string | undefined | void,\n options?: QueryResourceOptions<TResult, TRaw>,\n): ManualQueryResourceRef<TResult | undefined>;\n\nexport function manualQueryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | string | undefined | void,\n options?: QueryResourceOptions<TResult, TRaw>,\n): ManualQueryResourceRef<TResult | undefined> {\n const trigger = signal<{\n epoch: number;\n override?: HttpResourceRequest | string;\n }>(\n { epoch: 0 },\n {\n equal: (a, b) => a.epoch === b.epoch,\n },\n );\n\n const injector = options?.injector ?? inject(Injector);\n\n const req = computed(\n () => {\n const state = trigger();\n if (state.epoch === 0) return;\n if (state.override) return state.override;\n\n return untracked(request);\n },\n {\n equal: () => false,\n },\n );\n\n const resource = queryResource(req, options);\n\n return {\n ...resource,\n trigger: (override, injectorOverride) => {\n trigger.update((s) => ({\n epoch: s.epoch + 1,\n override,\n }));\n\n return new Promise<TResult>((res, rej) => {\n const watcher = nestedEffect(\n () => {\n const status = resource.status();\n\n if (status === 'resolved') {\n watcher.destroy();\n res(untracked(resource.value) as TResult);\n } else if (status === 'error') {\n watcher.destroy();\n rej(untracked(resource.error));\n }\n },\n { injector: injectorOverride ?? injector },\n );\n });\n },\n };\n}\n","import { type HttpResourceRequest } from '@angular/common/http';\nimport {\n computed,\n DestroyRef,\n effect,\n inject,\n linkedSignal,\n Signal,\n signal,\n ValueEqualityFn,\n} from '@angular/core';\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\nimport { catchError, combineLatestWith, filter, map, of } from 'rxjs';\nimport {\n queryResource,\n type QueryResourceOptions,\n type QueryResourceRef,\n} from './query-resource';\nimport { createCircuitBreaker, createEqualRequest } from './util';\n\n/**\n * @internal\n * Helper type for inferring the request body type based on the HTTP method.\n */\ntype NextRequest<\n TMethod extends HttpResourceRequest['method'],\n TMutation,\n> = TMethod extends 'DELETE' | 'delete'\n ? Omit<HttpResourceRequest, 'body' | 'method'> & { method: TMethod }\n : Omit<HttpResourceRequest, 'body' | 'method'> & {\n body: TMutation;\n method: TMethod;\n };\n\n/**\n * @internal\n * Helper type for tracking mutation status.\n */\ntype StatusResult<TResult> =\n | {\n status: 'error';\n error: unknown;\n }\n | {\n status: 'resolved';\n value: TResult;\n };\n\n/**\n * Options for configuring a `mutationResource`.\n *\n * @typeParam TResult - The type of the expected result from the mutation.\n * @typeParam TRaw - The raw response type from the HTTP request (defaults to TResult).\n * @typeParam TCTX - The type of the context value returned by `onMutate`.\n */\nexport type MutationResourceOptions<\n TResult,\n TRaw = TResult,\n TMutation = TResult,\n TCTX = void,\n TICTX = TCTX,\n TError = unknown,\n> = Omit<\n QueryResourceOptions<TResult, TRaw>,\n 'equal' | 'onError' | 'keepPrevious' | 'refresh' | 'cache' // we can't keep previous values, refresh or cache mutations as they are meant to be one-off operations\n> & {\n /**\n * A callback function that is called before the mutation request is made.\n * @param value The value being mutated (the `body` of the request).\n * @returns An optional context value that will be passed to the `onError`, `onSuccess`, and `onSettled` callbacks. This is useful for storing\n * information needed during the mutation lifecycle, such as previous values for optimistic updates or rollback.\n */\n onMutate?: (value: TMutation, initialCTX?: TICTX) => TCTX;\n /**\n * A callback function that is called if the mutation request fails.\n * @param error The error that occurred.\n * @param ctx The context value returned by the `onMutate` callback (or `undefined` if `onMutate` was not provided or returned `undefined`).\n */\n onError?: (error: TError, ctx: NoInfer<TCTX>) => void;\n /**\n * A callback function that is called if the mutation request succeeds.\n * @param value The result of the mutation (the parsed response body).\n * @param ctx The context value returned by the `onMutate` callback (or `undefined` if `onMutate` was not provided or returned `undefined`).\n */\n onSuccess?: (value: TResult, ctx: NoInfer<TCTX>) => void;\n /**\n * A callback function that is called when the mutation request settles (either succeeds or fails).\n * @param ctx The context value returned by the `onMutate` callback (or `undefined` if `onMutate` was not provided or returned `undefined`).\n */\n onSettled?: (ctx: NoInfer<TCTX>) => void;\n /**\n * Whether to queue the mutation requests and execute them in series. For example if network is unavailable or circuit breaker is open.\n * @default false\n */\n queue?: boolean;\n equal?: ValueEqualityFn<TMutation>;\n};\n\n/**\n * Represents a mutation resource created by `mutationResource`. Extends `QueryResourceRef`\n * but removes methods that don't make sense for mutations (like `prefetch`, `value`, etc.).\n *\n * @typeParam TResult - The type of the expected result from the mutation.\n */\nexport type MutationResourceRef<\n TResult,\n TMutation = TResult,\n TICTX = void,\n> = Omit<\n QueryResourceRef<TResult>,\n 'prefetch' | 'value' | 'hasValue' | 'set' | 'update' // we don't allow manually viewing the returned data or updating it manually, prefetching a mutation also doesn't make any sense\n> & {\n /**\n * Executes the mutation.\n *\n * @param value The mutation value (usually the request body).\n * @param ctx An optional initial context value that will be passed to the `onMutate` callback.\n */\n mutate: (value: TMutation, ctx?: TICTX) => void;\n /**\n * A signal that holds the current mutation request, or `null` if no mutation is in progress.\n * This can be useful for tracking the state of the mutation or for displaying loading indicators.\n */\n current: Signal<TMutation | null>;\n};\n\n/**\n * Creates a resource for performing mutations (e.g., POST, PUT, PATCH, DELETE requests).\n * Unlike `queryResource`, `mutationResource` is designed for one-off operations that change data.\n * It does *not* cache responses and does not provide a `value` signal. Instead, it focuses on\n * managing the mutation lifecycle (pending, error, success) and provides callbacks for handling\n * these states.\n *\n * @param request A function that returns the base `HttpResourceRequest` to be made. This function is called reactively. The parameter is the mutation value provided by the `mutate` method.\n * @param options Configuration options for the mutation resource. This includes callbacks\n * for `onMutate`, `onError`, `onSuccess`, and `onSettled`.\n * @typeParam TResult - The type of the expected result from the mutation.\n * @typeParam TRaw - The raw response type from the HTTP request (defaults to TResult).\n * @typeParam TMutation - The type of the mutation value (the request body).\n * @typeParam TICTX - The type of the initial context value passed to `onMutate`.\n * @typeParam TCTX - The type of the context value returned by `onMutate`.\n * @typeParam TMethod - The HTTP method to be used for the mutation (defaults to `HttpResourceRequest['method']`).\n * @returns A `MutationResourceRef` instance, which provides methods for triggering the mutation\n * and observing its status.\n */\nexport function mutationResource<\n TResult,\n TRaw = TResult,\n TMutation = TResult,\n TCTX = void,\n TICTX = TCTX,\n TMethod extends HttpResourceRequest['method'] = HttpResourceRequest['method'],\n>(\n request: (\n params: TMutation,\n ) => Omit<NextRequest<TMethod, TMutation>, 'body'> | undefined | void,\n options: MutationResourceOptions<TResult, TRaw, TMutation, TCTX, TICTX> = {},\n): MutationResourceRef<TResult, TMutation, TICTX> {\n const { onMutate, onError, onSuccess, onSettled, equal, ...rest } = options;\n\n const requestEqual = createEqualRequest(equal);\n\n const eq = equal ?? Object.is;\n const next = signal<TMutation | null>(null, {\n equal: (a, b) => {\n if (!a && !b) return true;\n if (!a || !b) return false;\n return eq(a, b);\n },\n });\n\n const queue = signal<[TMutation, TICTX | undefined][]>([]);\n\n let ctx: TCTX = undefined as TCTX;\n\n const queueRef = effect(() => {\n const nextInQueue = queue().at(0);\n if (!nextInQueue || next() !== null) return;\n queue.update((q) => q.slice(1));\n const [value, ictx] = nextInQueue;\n ctx = onMutate?.(value, ictx) as TCTX;\n next.set(value);\n });\n\n const req = computed(\n (): HttpResourceRequest | undefined => {\n const nr = next();\n if (!nr) return;\n\n return request(nr) ?? undefined;\n },\n {\n equal: requestEqual,\n },\n );\n\n const lastValue = linkedSignal<TMutation | null, TMutation | null>({\n source: next,\n computation: (next, prev) => {\n if (next === null && !!prev) return prev.value;\n return next;\n },\n });\n\n const lastValueRequest = computed(\n (): HttpResourceRequest | undefined => {\n const nr = lastValue();\n if (!nr) return;\n\n return request(nr) ?? undefined;\n },\n {\n equal: requestEqual,\n },\n );\n\n const cb = createCircuitBreaker(\n options?.circuitBreaker === true\n ? undefined\n : (options?.circuitBreaker ?? false),\n options?.injector,\n );\n\n const resource = queryResource<TResult, TRaw>(req, {\n ...rest,\n circuitBreaker: cb,\n defaultValue: null as unknown as TResult, // doesnt matter since .value is not accessible\n });\n\n const destroyRef = options.injector\n ? options.injector.get(DestroyRef)\n : inject(DestroyRef);\n\n const error$ = toObservable(resource.error);\n const value$ = toObservable(resource.value).pipe(catchError(() => of(null)));\n\n const statusSub = toObservable(resource.status)\n .pipe(\n combineLatestWith(error$, value$),\n map(([status, error, value]): StatusResult<TResult> | null => {\n if (status === 'error' && error) {\n return {\n status: 'error',\n error,\n };\n }\n\n if (status === 'resolved' && value !== null) {\n return {\n status: 'resolved',\n value,\n };\n }\n\n return null;\n }),\n filter((v) => v !== null),\n takeUntilDestroyed(destroyRef),\n )\n .subscribe((result) => {\n if (result.status === 'error') onError?.(result.error, ctx);\n else onSuccess?.(result.value, ctx);\n\n onSettled?.(ctx);\n ctx = undefined as TCTX;\n next.set(null);\n });\n\n const shouldQueue = options.queue ?? false;\n\n return {\n ...resource,\n destroy: () => {\n statusSub.unsubscribe();\n resource.destroy();\n queueRef.destroy();\n },\n mutate: (value, ictx) => {\n if (shouldQueue) {\n return queue.update((q) => [...q, [value, ictx]]);\n } else {\n ctx = onMutate?.(value, ictx) as TCTX;\n next.set(value);\n }\n },\n current: next,\n // redeclare disabled with last value so that it is not affected by the resource's internal disablement logic\n disabled: computed(() => cb.isOpen() || lastValueRequest() === undefined),\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mmstack-resource.mjs","sources":["../../../../packages/resource/src/lib/util/cache/persistence.ts","../../../../packages/resource/src/lib/util/cache/cache.ts","../../../../packages/resource/src/lib/util/hash-unknown.ts","../../../../packages/resource/src/lib/util/hash-request.ts","../../../../packages/resource/src/lib/util/cache/cache-interceptor.ts","../../../../packages/resource/src/lib/util/catch-value-error.ts","../../../../packages/resource/src/lib/util/circuit-breaker.ts","../../../../packages/resource/src/lib/util/dedupe-interceptor.ts","../../../../packages/resource/src/lib/util/equality.ts","../../../../packages/resource/src/lib/util/has-slow-connection.ts","../../../../packages/resource/src/lib/util/persist.ts","../../../../packages/resource/src/lib/util/refresh.ts","../../../../packages/resource/src/lib/util/retry-on-error.ts","../../../../packages/resource/src/lib/util/sensors.ts","../../../../packages/resource/src/lib/util/to-resource-object.ts","../../../../packages/resource/src/lib/query-resource.ts","../../../../packages/resource/src/lib/manual-query.ts","../../../../packages/resource/src/lib/mutation-resource.ts","../../../../packages/resource/src/mmstack-resource.ts"],"sourcesContent":["import { isDevMode } from '@angular/core';\nimport { CacheEntry } from './cache';\n\ntype StoredEntry<T> = Omit<CacheEntry<T>, 'timeout'>;\n\nexport type CacheDB<T> = {\n getAll: () => Promise<StoredEntry<T>[]>;\n store: (value: StoredEntry<T>) => Promise<void>;\n remove: (key: string) => Promise<void>;\n};\n\nexport function createNoopDB<T>(): CacheDB<T> {\n return {\n getAll: async () => [],\n store: async () => {\n // noop\n },\n remove: async () => {\n // noop\n },\n };\n}\n\nfunction toCacheDB<T>(db: IDBDatabase, storeName: string): CacheDB<T> {\n const getAll = async () => {\n const now = Date.now();\n return new Promise<StoredEntry<T>[]>((res, rej) => {\n const transaction = db.transaction(storeName, 'readonly');\n const store = transaction.objectStore(storeName);\n const request = store.getAll();\n\n request.onsuccess = () => res(request.result);\n request.onerror = () => rej(request.error);\n })\n .then((entries) => entries.filter((e) => e.expiresAt > now))\n .catch((err) => {\n if (isDevMode())\n console.error('Error getting all items from cache DB:', err);\n return [];\n });\n };\n\n const store = (value: StoredEntry<T>) => {\n return new Promise<void>((res, rej) => {\n const transaction = db.transaction(storeName, 'readwrite');\n const store = transaction.objectStore(storeName);\n\n store.put(value);\n\n transaction.oncomplete = () => res();\n transaction.onerror = () => rej(transaction.error);\n }).catch((err) => {\n if (isDevMode()) console.error('Error storing item in cache DB:', err);\n });\n };\n\n const remove = (key: string) => {\n return new Promise<void>((res, rej) => {\n const transaction = db.transaction(storeName, 'readwrite');\n const store = transaction.objectStore(storeName);\n\n store.delete(key);\n\n transaction.oncomplete = () => res();\n transaction.onerror = () => rej(transaction.error);\n }).catch((err) => {\n if (isDevMode()) console.error('Error removing item from cache DB:', err);\n });\n };\n\n return {\n getAll,\n store,\n remove,\n };\n}\n\nexport function createSingleStoreDB<T>(\n name: string,\n getStoreName: (version: number) => string,\n version = 1,\n): Promise<CacheDB<T>> {\n const storeName = getStoreName(version);\n\n if (!globalThis.indexedDB) return Promise.resolve(createNoopDB());\n\n return new Promise<IDBDatabase>((res, rej) => {\n if (version < 1) rej(new Error('Version must be 1 or greater'));\n\n const req = indexedDB.open(name, version);\n\n req.onupgradeneeded = (event) => {\n const db = req.result;\n const oldVersion = event.oldVersion;\n\n db.createObjectStore(storeName, { keyPath: 'key' });\n\n if (oldVersion > 0) {\n db.deleteObjectStore(getStoreName(oldVersion));\n }\n };\n\n req.onerror = () => {\n rej(req.error);\n };\n\n req.onsuccess = () => res(req.result);\n })\n .then((db) => toCacheDB<T>(db, storeName))\n .catch((err) => {\n if (isDevMode()) console.error('Error creating query DB:', err);\n return createNoopDB();\n });\n}\n","import { HttpHeaders, HttpResponse } from '@angular/common/http';\nimport {\n computed,\n inject,\n InjectionToken,\n Injector,\n isDevMode,\n type Provider,\n type Signal,\n untracked,\n} from '@angular/core';\nimport { mutable } from '@mmstack/primitives';\nimport { CacheDB, createNoopDB, createSingleStoreDB } from './persistence';\n\nfunction generateID() {\n if (globalThis.crypto?.randomUUID) {\n return globalThis.crypto.randomUUID();\n }\n return Math.random().toString(36).substring(2);\n}\n\ntype BaseSyncMessage<TEntry, TAction extends string> = {\n entry: TEntry;\n action: TAction;\n};\n\ntype InvalidateMessage<T> = BaseSyncMessage<\n Pick<CacheEntry<T>, 'key'>,\n 'invalidate'\n>;\n\ntype StoreMessage<T> = BaseSyncMessage<Omit<CacheEntry<T>, 'timeout'>, 'store'>;\n\ntype InternalSyncMessage<T> = InvalidateMessage<T> | StoreMessage<T>;\n\n/**\n * A message type used for synchronizing cache updates across tabs.\n * @internal\n * @template T - The type of data being cached.\n */\ntype SyncMessage<T> = InternalSyncMessage<T> & {\n cacheId: string;\n type: 'cache-sync-message';\n};\n\nfunction isSyncMessage<T>(msg: unknown): msg is SyncMessage<T> {\n return (\n typeof msg === 'object' &&\n msg !== null &&\n 'type' in msg &&\n (msg as SyncMessage<T>).type === 'cache-sync-message'\n );\n}\n\n/**\n * Options for configuring the Least Recently Used (LRU) cache cleanup strategy.\n * @internal\n */\ntype LRUCleanupType = {\n type: 'lru';\n /**\n * How often to check for expired or excess entries, in milliseconds.\n */\n checkInterval: number;\n /**\n * The maximum number of entries to keep in the cache. When the cache exceeds this size,\n * the least recently used entries will be removed.\n */\n maxSize: number;\n};\n\n/**\n * Options for configuring the \"oldest first\" cache cleanup strategy.\n * @internal\n */\ntype OldsetCleanupType = {\n type: 'oldest';\n /**\n * How often to check for expired or excess entries, in milliseconds.\n */\n checkInterval: number;\n /**\n * The maximum number of entries to keep in the cache. When the cache exceeds this size,\n * the oldest entries will be removed.\n */\n maxSize: number;\n};\n\n/**\n * Represents an entry in the cache.\n * @internal\n */\nexport type CacheEntry<T> = {\n value: T;\n created: number;\n updated: number;\n stale: number;\n useCount: number;\n expiresAt: number;\n timeout: ReturnType<typeof setTimeout>;\n key: string;\n};\n\n/**\n * Defines the types of cleanup strategies available for the cache.\n * - `lru`: Least Recently Used. Removes the least recently accessed entries when the cache is full.\n * - `oldest`: Removes the oldest entries when the cache is full.\n */\nexport type CleanupType = LRUCleanupType | OldsetCleanupType;\n\nconst ONE_DAY = 1000 * 60 * 60 * 24;\nconst ONE_HOUR = 1000 * 60 * 60;\n\nconst DEFAULT_CLEANUP_OPT = {\n type: 'lru',\n maxSize: 200,\n checkInterval: ONE_HOUR,\n} satisfies LRUCleanupType;\n\n/**\n * A generic cache implementation that stores data with time-to-live (TTL) and stale-while-revalidate capabilities.\n *\n * @typeParam T - The type of data to be stored in the cache.\n */\nexport class Cache<T> {\n private readonly internal = mutable(new Map<string, CacheEntry<T>>());\n private readonly cleanupOpt: CleanupType;\n private readonly id = generateID();\n\n /**\n * Destroys the cache instance, cleaning up any resources used by the cache.\n * This method is called automatically when the cache instance is garbage collected.\n */\n readonly destroy: () => void;\n\n private readonly broadcast: (msg: InternalSyncMessage<T>) => void = () => {\n // noop\n };\n\n /**\n * Creates a new `Cache` instance.\n *\n * @param ttl - The default Time To Live (TTL) for cache entries, in milliseconds. Defaults to one day.\n * @param staleTime - The default duration, in milliseconds, during which a cache entry is considered\n * stale but can still be used while revalidation occurs in the background. Defaults to 1 hour.\n * @param cleanupOpt - Options for configuring the cache cleanup strategy. Defaults to LRU with a\n * `maxSize` of 200 and a `checkInterval` of one hour.\n * @param syncTabs - If provided, the cache will use the options a BroadcastChannel to send updates between tabs.\n * Defaults to `undefined`, meaning no synchronization across tabs.\n */\n constructor(\n protected readonly ttl: number = ONE_DAY,\n protected readonly staleTime: number = ONE_HOUR,\n cleanupOpt: Partial<CleanupType> = {\n type: 'lru',\n maxSize: 1000,\n checkInterval: ONE_HOUR,\n },\n syncTabs?: {\n id: string;\n serialize: (value: T) => string;\n deserialize: (value: string) => T | null;\n },\n\n private readonly db: Promise<CacheDB<T>> = Promise.resolve(\n createNoopDB<T>(),\n ),\n ) {\n this.cleanupOpt = {\n ...DEFAULT_CLEANUP_OPT,\n ...cleanupOpt,\n };\n\n if (this.cleanupOpt.maxSize <= 0)\n throw new Error('maxSize must be greater than 0');\n\n // cleanup cache based on provided options regularly\n const cleanupInterval = setInterval(() => {\n this.cleanup();\n }, cleanupOpt.checkInterval);\n\n let destroySyncTabs = () => {\n // noop\n };\n\n if (syncTabs) {\n const channel = new BroadcastChannel(syncTabs.id);\n this.broadcast = (msg: InternalSyncMessage<T>) => {\n if (msg.action === 'invalidate')\n return channel.postMessage({\n action: 'invalidate',\n entry: { key: msg.entry.key },\n cacheId: this.id,\n type: 'cache-sync-message',\n } satisfies SyncMessage<string>);\n\n return channel.postMessage({\n ...msg,\n entry: {\n ...msg.entry,\n value: syncTabs.serialize(msg.entry.value),\n },\n cacheId: this.id,\n type: 'cache-sync-message',\n } satisfies SyncMessage<string>);\n };\n\n channel.onmessage = (event) => {\n const msg = event.data;\n if (!isSyncMessage<string>(msg)) return;\n if (msg.cacheId === this.id) return; // ignore messages from this cache\n\n if (msg.action === 'store') {\n const value = syncTabs.deserialize(msg.entry.value);\n if (value === null) return;\n\n // Last-write-wins by `updated` timestamp. If our local entry was\n // written more recently than the broadcast we just received, the\n // broadcast is stale (in-flight when we wrote locally) — drop it.\n const existing = untracked(this.internal).get(msg.entry.key);\n if (existing && existing.updated >= msg.entry.updated) return;\n\n this.storeInternal(\n msg.entry.key,\n value,\n msg.entry.stale - msg.entry.updated,\n msg.entry.expiresAt - msg.entry.updated,\n true,\n false,\n );\n } else if (msg.action === 'invalidate') {\n this.invalidateInternal(msg.entry.key, true);\n }\n };\n\n destroySyncTabs = () => {\n channel.close();\n };\n }\n\n let destroyed = false;\n const destroy = () => {\n if (destroyed) return;\n destroyed = true;\n clearInterval(cleanupInterval);\n destroySyncTabs();\n };\n\n this.db\n .then(async (db) => {\n if (destroyed) return [];\n return db.getAll();\n })\n .then((entries) => {\n if (destroyed) return;\n // load entries into the cache\n\n const current = untracked(this.internal);\n entries.forEach((entry) => {\n if (current.has(entry.key)) return;\n this.storeInternal(\n entry.key,\n entry.value,\n entry.stale - entry.updated,\n entry.expiresAt - entry.updated,\n true, // like from sync because we dont want to trigger sync or db writes\n );\n });\n });\n\n this.destroy = destroy;\n\n // cleanup if object is garbage collected, this is because the cache can be quite large from a memory standpoint & we dont want all that floating garbage\n const registry = new FinalizationRegistry((id: string) => {\n if (id === this.id) {\n destroy();\n }\n });\n\n registry.register(this, this.id);\n }\n\n /** @internal */\n private getInternal(\n key: () => string | null,\n ): Signal<(CacheEntry<T> & { isStale: boolean }) | null> {\n const keySignal = computed(() => key());\n\n return computed(() => {\n const key = keySignal();\n if (!key) return null;\n const found = this.internal().get(key);\n\n const now = Date.now();\n\n if (!found || found.expiresAt <= now) return null;\n found.useCount++;\n return {\n ...found,\n isStale: found.stale <= now,\n };\n });\n }\n\n /**\n * Retrieves a cache entry without affecting its usage count (for LRU). This is primarily\n * for internal use or debugging.\n * @internal\n * @param key - The key of the entry to retrieve.\n * @returns The cache entry, or `null` if not found or expired.\n */\n getUntracked(key: string): (CacheEntry<T> & { isStale: boolean }) | null {\n return untracked(this.getInternal(() => key));\n }\n\n /**\n * Retrieves a cache entry as a signal.\n *\n * @param key - A function that returns the cache key. The key is a signal, allowing for dynamic keys. If the function returns null the value is also null.\n * @returns A signal that holds the cache entry, or `null` if not found or expired. The signal\n * updates whenever the cache entry changes (e.g., due to revalidation or expiration).\n */\n get(\n key: () => string | null,\n ): Signal<(CacheEntry<T> & { isStale: boolean }) | null> {\n return this.getInternal(key);\n }\n\n /**\n * Retrieves a cache entry or an object with the key if not found.\n *\n * @param key - A function that returns the cache key. The key is a signal, allowing for dynamic keys. If the function returns null the value is also null.\n * @returns A signal that holds the cache entry or an object with the key if not found. The signal\n * updates whenever the cache entry changes (e.g., due to revalidation or expiration).\n */\n getEntryOrKey(\n key: () => string | null,\n ): Signal<(CacheEntry<T> & { isStale: boolean }) | string | null> {\n const valueSig = this.getInternal(key);\n return computed(() => valueSig() ?? key());\n }\n\n /**\n * Stores a value in the cache.\n *\n * @param key - The key under which to store the value.\n * @param value - The value to store.\n * @param staleTime - (Optional) The stale time for this entry, in milliseconds. Overrides the default `staleTime`.\n * @param ttl - (Optional) The TTL for this entry, in milliseconds. Overrides the default `ttl`.\n */\n store(\n key: string,\n value: T,\n staleTime = this.staleTime,\n ttl = this.ttl,\n persist = false,\n ) {\n this.storeInternal(key, value, staleTime, ttl, false, persist);\n }\n\n private storeInternal(\n key: string,\n value: T,\n staleTime = this.staleTime,\n ttl = this.ttl,\n fromSync = false,\n persist = false,\n ) {\n const entry = this.getUntracked(key);\n if (entry) {\n clearTimeout(entry.timeout); // stop invalidation\n }\n\n const prevCount = entry?.useCount ?? 0;\n\n // ttl cannot be less than staleTime\n if (ttl < staleTime) staleTime = ttl;\n\n const now = Date.now();\n\n const next: Omit<CacheEntry<T>, 'timeout'> = {\n value,\n created: entry?.created ?? now,\n updated: now,\n useCount: prevCount + 1,\n stale: now + staleTime,\n expiresAt: now + ttl,\n key,\n };\n\n this.internal.mutate((map) => {\n map.set(key, {\n ...next,\n timeout: setTimeout(() => this.invalidate(key), ttl),\n });\n return map;\n });\n\n if (!fromSync) {\n if (persist) this.db.then((db) => db.store(next));\n\n this.broadcast({\n action: 'store',\n entry: next,\n });\n }\n }\n\n /**\n * Invalidates (removes) a cache entry.\n *\n * @param key - The key of the entry to invalidate.\n */\n invalidate(key: string) {\n this.invalidateInternal(key);\n }\n\n /**\n * Invalidates every cache entry whose key starts with `prefix`. Common after a\n * list-mutating operation (e.g. invalidate every paginated `GET /api/posts*`\n * after a POST). Returns the number of entries removed.\n *\n * @example\n * cache.invalidatePrefix('GET https://api.example.com/posts');\n */\n invalidatePrefix(prefix: string): number {\n return this.invalidateWhere((key) => key.startsWith(prefix));\n }\n\n /**\n * Invalidates every cache entry whose key matches the predicate. Use for\n * arbitrary bulk invalidation that doesn't fit prefix matching (e.g.\n * \"everything containing `userId=42`\"). Returns the number of entries removed.\n *\n * @example\n * cache.invalidateWhere((key) => key.includes('/me/'));\n */\n invalidateWhere(predicate: (key: string) => boolean): number {\n const keys = Array.from(untracked(this.internal).keys()).filter(predicate);\n for (const key of keys) this.invalidateInternal(key);\n return keys.length;\n }\n\n private invalidateInternal(key: string, fromSync = false) {\n const entry = this.getUntracked(key);\n if (!entry) return;\n clearTimeout(entry.timeout);\n this.internal.mutate((map) => {\n map.delete(key);\n return map;\n });\n if (!fromSync) {\n this.db.then((db) => db.remove(key));\n this.broadcast({ action: 'invalidate', entry: { key } });\n }\n }\n\n /** @internal */\n private cleanup() {\n if (untracked(this.internal).size <= this.cleanupOpt.maxSize) return;\n\n const sorted = Array.from(untracked(this.internal).entries()).toSorted(\n (a, b) => {\n if (this.cleanupOpt.type === 'lru') {\n return a[1].useCount - b[1].useCount; // least used first\n } else {\n return a[1].created - b[1].created; // oldest first\n }\n },\n );\n\n const keepCount = Math.floor(this.cleanupOpt.maxSize / 2);\n\n const removed = sorted.slice(0, sorted.length - keepCount);\n const keep = sorted.slice(removed.length, sorted.length);\n\n removed.forEach(([, e]) => {\n clearTimeout(e.timeout);\n });\n\n this.internal.set(new Map(keep));\n }\n}\n\n/**\n * Options for configuring the cache.\n */\ntype CacheOptions = {\n /**\n * The default Time To Live (TTL) for cache entries, in milliseconds.\n */\n ttl?: number;\n /**\n * The default duration, in milliseconds, during which a cache entry is considered\n * stale but can still be used while revalidation occurs in the background.\n */\n staleTime?: number;\n /**\n * Options for configuring the cache cleanup strategy.\n */\n cleanup?: Partial<CleanupType>;\n /**\n * Whether to synchronize cache across tabs. If true, the cache will use a BroadcastChannel to send updates between tabs.\n */\n syncTabs?: boolean;\n /**\n * Globally disable persistence of cache entries.\n * If set to `false`, cache entries will not be persisted to the database.\n * `true` means, cache entries can be persisted, they must still be opted into on the resource level & allowed by server headers.\n * @default true\n */\n persist?: boolean;\n /**\n * Version of the caches database, increment this if the interfaces change, this will cause the old data to be deleted.\n * Minimum value is 1, so first increment should be 2.\n * @default 1\n */\n version?: number;\n};\n\nconst CLIENT_CACHE_TOKEN = new InjectionToken<Cache<HttpResponse<unknown>>>(\n 'INTERNAL_CLIENT_CACHE',\n);\n\n/**\n * Provides the instance of the QueryCache for queryResource. This should probably be called\n * in your application's root configuration, but can also be overriden with component/module providers.\n *\n * @param options - Optional configuration options for the cache.\n * @returns An Angular `Provider` for the cache.\n *\n * @example\n * // In your app.config.ts or AppModule providers:\n *\n * import { provideQueryCache } from './your-cache';\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideQueryCache({\n * ttl: 60000, // Default TTL of 60 seconds\n * staleTime: 30000, // Default staleTime of 30 seconds\n * }),\n * // ... other providers\n * ]\n * };\n */\nexport function provideQueryCache(opt?: CacheOptions): Provider {\n const serialize = (value: HttpResponse<unknown>) => {\n const headersRecord: Record<string, string[]> = {};\n\n const headerKeys = value.headers.keys();\n headerKeys.forEach((key) => {\n const values = value.headers.getAll(key);\n if (!values) return;\n headersRecord[key] = values;\n });\n\n return JSON.stringify({\n body: value.body,\n status: value.status,\n statusText: value.statusText,\n headers: headerKeys.length > 0 ? headersRecord : undefined,\n url: value.url,\n });\n };\n\n const deserialize = (value: string) => {\n try {\n const parsed = JSON.parse(value);\n\n if (!parsed || typeof parsed !== 'object' || !('body' in parsed))\n throw new Error('Invalid cache entry format');\n\n const headers = parsed.headers\n ? new HttpHeaders(parsed.headers)\n : undefined;\n\n return new HttpResponse({\n body: parsed.body,\n status: parsed.status,\n statusText: parsed.statusText,\n headers: headers,\n url: parsed.url,\n });\n } catch (err) {\n if (isDevMode()) console.error('Failed to deserialize cache entry:', err);\n return null;\n }\n };\n\n const syncTabsOpt = opt?.syncTabs\n ? {\n id: 'mmstack-query-cache-sync',\n serialize,\n deserialize,\n }\n : undefined;\n\n const db =\n opt?.persist === false\n ? undefined\n : createSingleStoreDB<string>(\n 'mmstack-query-cache-db',\n (version) => `query-store_v${version}`,\n opt?.version,\n ).then((db): CacheDB<HttpResponse<unknown>> => {\n return {\n getAll: () => {\n return db.getAll().then((entries) => {\n return entries\n .map((entry) => {\n const value = deserialize(entry.value);\n if (value === null) return null;\n return {\n ...entry,\n value,\n };\n })\n .filter((e) => e !== null);\n });\n },\n store: (entry) => {\n return db.store({ ...entry, value: serialize(entry.value) });\n },\n remove: db.remove,\n };\n });\n\n return {\n provide: CLIENT_CACHE_TOKEN,\n useValue: new Cache(\n opt?.ttl,\n opt?.staleTime,\n opt?.cleanup,\n syncTabsOpt,\n db,\n ),\n };\n}\n\nclass NoopCache<T> extends Cache<T> {\n override store(_: string, __: T, ___ = super.staleTime, ____ = super.ttl) {\n // noop\n }\n}\n\n/**\n * Injects the `QueryCache` instance that is used within queryResource.\n * Allows for direct modification of cached data, but is mostly meant for internal use.\n *\n * @param injector - (Optional) The injector to use. If not provided, the current\n * injection context is used.\n * @returns The `QueryCache` instance.\n *\n * @example\n * // In your component or service:\n *\n * import { injectQueryCache } from './your-cache';\n *\n * constructor() {\n * const cache = injectQueryCache();\n *\n * const myData = cache.get(() => 'my-data-key');\n * if (myData() !== null) {\n * // ... use cached data ...\n * }\n * }\n */\nexport function injectQueryCache<TRaw = unknown>(\n injector?: Injector,\n): Cache<HttpResponse<TRaw>> {\n const cache = injector\n ? injector.get(CLIENT_CACHE_TOKEN, null, {\n optional: true,\n })\n : inject(CLIENT_CACHE_TOKEN, {\n optional: true,\n });\n\n if (!cache) {\n if (isDevMode())\n throw new Error(\n 'Cache not provided, please add provideQueryCache() to providers array',\n );\n else return new NoopCache();\n }\n\n return cache as Cache<HttpResponse<TRaw>>;\n}\n","type UnknownObject = Record<PropertyKey, unknown>;\n\n/**\n * Returns `true` for any object-like value whose own enumerable keys should\n * be sorted for stable hashing. Excludes arrays (positional), `Date`\n * (handled by `toJSON`), `Map`/`Set` (handled explicitly), and binary types\n * (`Blob`/`FormData`/`URLSearchParams`/`ArrayBuffer`/typed arrays — these\n * should be branched on before reaching `hash()`, typically by `hashRequest`).\n *\n * Plain objects, class instances, and `Object.create(null)` all qualify.\n */\nfunction isHashableObject(value: unknown): value is UnknownObject {\n if (value === null || typeof value !== 'object') return false;\n if (Array.isArray(value)) return false;\n if (value instanceof Date) return false;\n if (value instanceof Map) return false;\n if (value instanceof Set) return false;\n if (typeof Blob !== 'undefined' && value instanceof Blob) return false;\n if (typeof FormData !== 'undefined' && value instanceof FormData) return false;\n if (\n typeof URLSearchParams !== 'undefined' &&\n value instanceof URLSearchParams\n )\n return false;\n if (value instanceof ArrayBuffer) return false;\n if (ArrayBuffer.isView(value)) return false;\n return true;\n}\n\nfunction sortKeys(val: UnknownObject): UnknownObject {\n return Object.keys(val)\n .toSorted()\n .reduce((result, key) => {\n result[key] = val[key];\n return result;\n }, {} as UnknownObject);\n}\n\n/**\n * Internal helper to generate a stable JSON string from an array.\n * - Object-like values (plain, class instances, null-proto) get their own\n * enumerable keys sorted alphabetically.\n * - `Map` → marker object with sorted entries (sorted by `JSON.stringify(key)`).\n * - `Set` → marker object with sorted values (sorted by `JSON.stringify(value)`).\n * - Arrays preserve order. `Date` serializes via `toJSON`.\n *\n * @internal\n */\nfunction hashKey(queryKey: unknown[]): string {\n return JSON.stringify(queryKey, (_, val) => {\n if (val instanceof Map) {\n // Schwartzian: compute each entry's sort key (recursive hash of the\n // Map key) once, then sort by the cheap string compare.\n const entries = [...val.entries()]\n .map((e) => [hash(e[0]), e] as const)\n .sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))\n .map(([, e]) => e);\n return { __map__: entries };\n }\n if (val instanceof Set) {\n const values = [...val]\n .map((v) => [hash(v), v] as const)\n .sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))\n .map(([, v]) => v);\n return { __set__: values };\n }\n if (isHashableObject(val)) return sortKeys(val);\n return val;\n });\n}\n\n/**\n * Generates a stable, unique string hash from one or more arguments.\n * Useful for creating cache keys or identifiers where object key order shouldn't matter.\n *\n * How it works:\n * - Object-like values (plain objects, class instances, `Object.create(null)`) have\n * their own enumerable keys sorted alphabetically before hashing. This ensures\n * `{ a: 1, b: 2 }` and `{ b: 2, a: 1 }` produce the same hash.\n * - `Map` and `Set` are serialized via stable, sorted markers (`__map__` / `__set__`).\n * - Arrays preserve positional order; `Date` uses its ISO string via `toJSON`.\n *\n * @param {...unknown} args Values to include in the hash.\n * @returns A stable string hash representing the input arguments.\n * @example\n * hash('posts', 10);\n * // => '[\"posts\",10]'\n *\n * hash({ a: 1, b: 2 }) === hash({ b: 2, a: 1 }); // true\n *\n * hash(new Map([['a', 1]])) === hash(new Map([['a', 1]])); // true\n *\n * // Be mindful of values JSON.stringify cannot handle (functions, undefined, Symbols)\n * // hash('a', undefined, function() {}) => '[\"a\",null,null]'\n */\nexport function hash(...args: unknown[]): string {\n return hashKey(args);\n}\n","import {\n HttpParams,\n type HttpRequest,\n type HttpResourceRequest,\n} from '@angular/common/http';\nimport { hash } from './hash-unknown';\n\ntype HashableRequest = {\n method?: string;\n url: string;\n responseType?: string;\n params?: HttpResourceRequest['params'] | HttpRequest<unknown>['params'];\n body?: unknown;\n};\n\nfunction normalizeParams(\n params: NonNullable<HashableRequest['params']>,\n): string {\n const p =\n params instanceof HttpParams\n ? params\n : new HttpParams({ fromObject: params });\n\n return p\n .keys()\n .toSorted()\n .map((key) => {\n const encodedKey = encodeURIComponent(key);\n return (p.getAll(key) ?? [])\n .map((v) => `${encodedKey}=${encodeURIComponent(v)}`)\n .join('&');\n })\n .join('&');\n}\n\nfunction hashBody(body: unknown): string {\n // File extends Blob — must check File first\n if (typeof File !== 'undefined' && body instanceof File) {\n return `File:${body.name}:${body.type}:${body.size}:${body.lastModified}`;\n }\n\n if (typeof Blob !== 'undefined' && body instanceof Blob) {\n return `Blob:${body.type}:${body.size}`;\n }\n\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n const entries: Array<[string, string]> = [];\n body.forEach((value, key) => {\n entries.push([key, hashBody(value)]);\n });\n entries.sort(\n ([ak, av], [bk, bv]) => ak.localeCompare(bk) || av.localeCompare(bv),\n );\n return `FormData:${entries.map(([k, v]) => `${k}=${v}`).join('&')}`;\n }\n\n if (\n typeof URLSearchParams !== 'undefined' &&\n body instanceof URLSearchParams\n ) {\n const sp = new URLSearchParams(body);\n sp.sort();\n return `URLSearchParams:${sp.toString()}`;\n }\n\n if (body instanceof ArrayBuffer) {\n return `ArrayBuffer:${body.byteLength}`;\n }\n\n if (ArrayBuffer.isView(body)) {\n return `${body.constructor.name}:${body.byteLength}`;\n }\n\n return hash(body);\n}\n\n/**\n * Builds a stable cache/dedupe key from an HTTP request shape (accepts both\n * `HttpRequest` and `HttpResourceRequest`).\n *\n * Key composition: `${method}:${url}:${responseType}[:${params}][:${body}]`\n * - `method` defaults to `'GET'`, `responseType` to `'json'` (Angular defaults).\n * - Query params are sorted alphabetically and URL-encoded for stability.\n * - Body hashing handles `File`/`Blob`/`FormData`/`URLSearchParams`/`ArrayBuffer`\n * and typed arrays explicitly; everything else flows through key-sorted\n * `JSON.stringify` via `hash()`.\n */\nexport function hashRequest(req: HashableRequest): string {\n const method = req.method ?? 'GET';\n const responseType = req.responseType ?? 'json';\n const base = `${method}:${req.url}:${responseType}`;\n\n const params = req.params ? `:${normalizeParams(req.params)}` : '';\n const body = req.body != null ? `:${hashBody(req.body)}` : '';\n\n return base + params + body;\n}\n","import {\n HttpContext,\n HttpContextToken,\n type HttpEvent,\n type HttpHandlerFn,\n type HttpInterceptorFn,\n type HttpRequest,\n HttpResponse,\n} from '@angular/common/http';\nimport { map, type Observable, of, tap } from 'rxjs';\nimport { hashRequest } from '../hash-request';\nimport { injectQueryCache } from './cache';\n\ntype CacheEntryOptions = {\n key?: string;\n ttl?: number;\n staleTime?: number;\n cache: boolean;\n bustBrowserCache?: boolean;\n ignoreCacheControl?: boolean;\n parse?: (val: unknown) => unknown;\n persist?: boolean;\n};\n\nconst CACHE_CONTEXT = new HttpContextToken<CacheEntryOptions>(() => ({\n cache: false,\n}));\n\nexport function setCacheContext(\n ctx = new HttpContext(),\n opt: Omit<CacheEntryOptions, 'cache' | 'key'> & {\n key: Required<CacheEntryOptions>['key'];\n },\n) {\n return ctx.set(CACHE_CONTEXT, { ...opt, cache: true });\n}\n\nfunction getCacheContext(ctx: HttpContext): CacheEntryOptions {\n return ctx.get(CACHE_CONTEXT);\n}\n\ntype ResolvedCacheControl = {\n noStore: boolean;\n noCache: boolean;\n mustRevalidate: boolean;\n immutable: boolean;\n maxAge: number | null;\n staleWhileRevalidate: number | null;\n};\n\nfunction parseCacheControlHeader(\n req: HttpResponse<unknown>,\n): ResolvedCacheControl {\n const header = req.headers.get('Cache-Control');\n\n let sMaxAge: number | null = null;\n const directives: ResolvedCacheControl = {\n noStore: false,\n noCache: false,\n mustRevalidate: false,\n immutable: false,\n maxAge: null,\n staleWhileRevalidate: null,\n };\n\n if (!header) return directives;\n\n const parts = header.split(',');\n\n for (const part of parts) {\n const [unparsedKey, value] = part.trim().split('=');\n const key = unparsedKey.trim().toLowerCase();\n\n switch (key) {\n case 'no-store':\n directives.noStore = true;\n break;\n case 'no-cache':\n directives.noCache = true;\n break;\n case 'must-revalidate':\n case 'proxy-revalidate':\n directives.mustRevalidate = true;\n break;\n case 'immutable':\n directives.immutable = true;\n break;\n case 'max-age': {\n if (!value) break;\n const parsedValue = parseInt(value, 10);\n if (!isNaN(parsedValue)) directives.maxAge = parsedValue;\n break;\n }\n case 's-max-age': {\n if (!value) break;\n const parsedValue = parseInt(value, 10);\n if (!isNaN(parsedValue)) sMaxAge = parsedValue;\n break;\n }\n case 'stale-while-revalidate': {\n if (!value) break;\n const parsedValue = parseInt(value, 10);\n if (!isNaN(parsedValue)) directives.staleWhileRevalidate = parsedValue;\n break;\n }\n }\n }\n\n // s-max-age takes precedence over max-age\n if (sMaxAge !== null) directives.maxAge = sMaxAge;\n\n // if no store nothing else is relevant\n if (directives.noStore)\n return {\n noStore: true,\n noCache: false,\n mustRevalidate: false,\n immutable: false,\n maxAge: null,\n staleWhileRevalidate: null,\n };\n\n // max age does not apply to immutable resources\n if (directives.immutable)\n return {\n ...directives,\n maxAge: null,\n };\n\n return directives;\n}\n\nfunction resolveTimings(\n cacheControl: ResolvedCacheControl,\n optStaleTime?: number,\n optTTL?: number,\n): { staleTime?: number; ttl?: number } {\n let staleTime = optStaleTime;\n let ttl = optTTL;\n\n if (cacheControl.immutable)\n return {\n staleTime: Infinity,\n ttl: Infinity,\n };\n\n if (cacheControl.maxAge !== null) ttl = cacheControl.maxAge * 1000;\n\n if (cacheControl.staleWhileRevalidate !== null)\n staleTime = cacheControl.staleWhileRevalidate * 1000;\n\n // if no-cache is set, we must always revalidate\n if (cacheControl.noCache || cacheControl.mustRevalidate) staleTime = 0;\n\n if (ttl !== undefined && staleTime !== undefined && ttl < staleTime) {\n staleTime = ttl;\n }\n\n return { staleTime, ttl };\n}\n\n/**\n * Creates an `HttpInterceptorFn` that implements caching for HTTP requests. This interceptor\n * checks for a caching configuration in the request's `HttpContext` (internally set by the queryResource).\n * If caching is enabled, it attempts to retrieve responses from the cache. If a cached response\n * is found and is not stale, it's returned directly. If the cached response is stale, it's returned,\n * and a background revalidation request is made. If no cached response is found, the request\n * is made to the server, and the response is cached according to the configured TTL and staleness.\n * The interceptor also respects `Cache-Control` headers from the server.\n *\n * @param allowedMethods - An array of HTTP methods for which caching should be enabled.\n * Defaults to `['GET', 'HEAD', 'OPTIONS']`.\n *\n * @returns An `HttpInterceptorFn` that implements the caching logic.\n *\n * @example\n * // In your app.config.ts or module providers:\n *\n * import { provideHttpClient, withInterceptors } from '@angular/common/http';\n * import { createCacheInterceptor } from '@mmstack/resource';\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([createCacheInterceptor()])),\n * // ... other providers\n * ],\n * };\n */\nexport function createCacheInterceptor(\n allowedMethods = ['GET', 'HEAD', 'OPTIONS'],\n): HttpInterceptorFn {\n const CACHE_METHODS = new Set<string>(allowedMethods);\n\n return (\n req: HttpRequest<unknown>,\n next: HttpHandlerFn,\n ): Observable<HttpEvent<unknown>> => {\n const cache = injectQueryCache();\n\n if (!CACHE_METHODS.has(req.method)) return next(req);\n const opt = getCacheContext(req.context);\n\n if (!opt.cache) return next(req);\n\n const key = opt.key ?? hashRequest(req);\n const entry = cache.getUntracked(key); // null if expired or not found\n\n // If the entry is not stale, return it\n if (entry && !entry.isStale) return of(entry.value);\n\n // resource itself handles case of showing stale data...the request must process as this will \"refresh said data\"\n\n const eTag = entry?.value.headers.get('ETag');\n const lastModified = entry?.value.headers.get('Last-Modified');\n\n if (eTag) {\n req = req.clone({ setHeaders: { 'If-None-Match': eTag } });\n }\n\n if (lastModified) {\n req = req.clone({ setHeaders: { 'If-Modified-Since': lastModified } });\n }\n\n if (opt.bustBrowserCache) {\n req = req.clone({\n setParams: { _cb: Date.now().toString() },\n });\n }\n\n return next(req).pipe(\n tap((event) => {\n if (!(event instanceof HttpResponse)) return;\n\n if (event.ok) {\n const cacheControl = parseCacheControlHeader(event);\n\n if (cacheControl.noStore && !opt.ignoreCacheControl) return;\n\n const { staleTime, ttl } = opt.ignoreCacheControl\n ? opt\n : resolveTimings(cacheControl, opt.staleTime, opt.ttl);\n\n if (opt.ttl === 0) return; // no point\n\n const parsedResponse = opt.parse\n ? new HttpResponse({\n body: opt.parse(event.body),\n headers: event.headers,\n status: event.status,\n statusText: event.statusText,\n url: event.url ?? undefined,\n })\n : event;\n\n cache.store(key, parsedResponse, staleTime, ttl, opt.persist);\n return;\n }\n\n // 304 → server confirmed our cached entry is still valid. Re-stamp the\n // existing entry so subsequent reads within the new freshness window\n // don't trigger another revalidation round-trip.\n if (event.status === 304 && entry) {\n const cacheControl = parseCacheControlHeader(event);\n const { staleTime, ttl } = opt.ignoreCacheControl\n ? opt\n : resolveTimings(cacheControl, opt.staleTime, opt.ttl);\n\n cache.store(key, entry.value, staleTime, ttl, opt.persist);\n }\n }),\n map((event) => {\n // handle 304 responses due to eTag/last-modified\n if (event instanceof HttpResponse && event.status === 304 && entry) {\n return entry.value;\n }\n\n return event;\n }),\n );\n };\n}\n","import { HttpResourceRef } from '@angular/common/http';\nimport { computed } from '@angular/core';\nimport { toWritable } from '@mmstack/primitives';\n\nexport function catchValueError<T>(\n resource: HttpResourceRef<T>,\n fallback: T,\n): HttpResourceRef<T> {\n return {\n ...resource,\n value: toWritable(\n computed(() => {\n try {\n return resource.value();\n } catch {\n return fallback;\n }\n }),\n (value) => resource.value.set(value),\n ),\n };\n}\n","import {\n computed,\n effect,\n inject,\n InjectionToken,\n Injector,\n Provider,\n Signal,\n signal,\n untracked,\n} from '@angular/core';\n\n/**\n * Represents the possible states of a circuit breaker.\n * - `CLOSED`: The circuit breaker is closed, and operations are allowed to proceed.\n * - `OPEN`: The circuit breaker is open, and operations are blocked.\n * - `HALF_OPEN`: The circuit breaker is in a half-open state, allowing a limited number of operations to test if the underlying issue is resolved.\n */\ntype CircuitBreakerState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';\n\n/**\n * Represents a circuit breaker, which monitors operations and prevents failures from cascading.\n */\nexport type CircuitBreaker = {\n /**\n * A signal indicating whether the circuit breaker is currently closed (allowing operations).\n */\n isClosed: Signal<boolean>;\n /**\n * A signal indicating whether the circuit breaker is either open or in a half-open state.\n * This is useful for checking if operations are blocked.\n * If the circuit breaker is open, operations should not proceed.\n */\n isOpen: Signal<boolean>;\n /**\n * A signal representing the current state of the circuit breaker.\n */\n status: Signal<CircuitBreakerState>;\n /**\n * Signals a failure to the circuit breaker. This may cause the circuit breaker to open.\n */\n fail: (err?: Error) => void;\n /**\n * Signals a success to the circuit breaker. This may cause the circuit breaker to close.\n */\n success: () => void;\n /**\n * Attempts to transition the circuit breaker to the half-open state. This is typically used\n * to test if the underlying issue has been resolved after the circuit breaker has been open.\n */\n halfOpen: () => void;\n /**\n * Fully resets the breaker state — clears the failure count, drops the half-open\n * flag, and lifts a permanent open caused by `shouldFailForever`. Use after the\n * underlying condition has been resolved (e.g. user re-authenticated after a\n * 401-triggered permanent open).\n */\n hardReset: () => void;\n /**\n * Destroys the circuit breaker & initiates related cleanup\n */\n destroy: () => void;\n};\n\n/**\n * Options for creating a circuit breaker.\n */\ntype CreateCircuitBreakerOptions = {\n /**\n * The number of failures that will cause the circuit breaker to open.\n * @default 5\n */\n threshold?: number;\n /**\n * @deprecated Misspelled — use `threshold` instead. Kept for backwards compatibility; will be removed in a future major.\n */\n treshold?: number;\n /**\n * The time in milliseconds after which the circuit breaker will reset and allow operations to proceed again.\n * @default 30000 (30 seconds)\n */\n timeout?: number;\n /**\n * A function that determines whether an error should cause the circuit breaker to increment the failure count.\n * @default Always returns true\n */\n shouldFail?: (err?: Error) => boolean;\n /**\n * A function that determines whether an error should cause the circuit breaker to be open forever.\n * `hardReset()` is required to lift this state.\n * @default Always returns false\n */\n shouldFailForever?: (err?: Error) => boolean;\n};\n\n/**\n * Options for creating a circuit breaker.\n * - `false`: Disables circuit breaker functionality (always open).\n * - true: Creates a new circuit breaker with default options.\n * - `CircuitBreaker`: Provides an existing `CircuitBreaker` instance to use.\n * - `{ threshold?: number; timeout?: number; }`: Creates a new circuit breaker with the specified options.\n */\nexport type CircuitBreakerOptions =\n | false\n | CircuitBreaker\n | CreateCircuitBreakerOptions;\n\n/** @internal */\nconst DEFAULT_OPTIONS: Required<\n Omit<CreateCircuitBreakerOptions, 'treshold'>\n> = {\n threshold: 5,\n timeout: 30000,\n shouldFail: () => true,\n shouldFailForever: () => false,\n};\n\n/** @internal */\nfunction internalCeateCircuitBreaker(\n threshold = 5,\n resetTimeout = 30000,\n shouldFail: (err?: Error) => boolean = () => true,\n shouldFailForever: (err?: Error) => boolean = () => false,\n): CircuitBreaker {\n const halfOpen = signal(false);\n const failureCount = signal(0);\n const failedForever = signal(false);\n\n const status = computed<CircuitBreakerState>(() => {\n if (failedForever() || failureCount() >= threshold) return 'OPEN';\n return halfOpen() ? 'HALF_OPEN' : 'CLOSED';\n });\n\n const isClosed = computed(() => status() !== 'OPEN');\n const isOpen = computed(() => status() !== 'CLOSED');\n\n const success = () => {\n failureCount.set(0);\n halfOpen.set(false);\n };\n\n const tryOnce = () => {\n if (!untracked(isOpen)) return;\n halfOpen.set(true);\n failureCount.set(threshold - 1);\n };\n\n // Auto-probe effect: schedules a half-open retry after `resetTimeout` whenever\n // the breaker is open, *unless* we've been failed forever (in which case only\n // hardReset() can recover).\n const effectRef = effect((cleanup) => {\n if (!isOpen() || failedForever()) return;\n\n const timeout = setTimeout(tryOnce, resetTimeout);\n return cleanup(() => {\n clearTimeout(timeout);\n });\n });\n\n const failInternal = () => {\n failureCount.set(failureCount() + 1);\n halfOpen.set(false);\n };\n\n const failForever = () => {\n failedForever.set(true);\n halfOpen.set(false);\n };\n\n const fail = (err?: Error) => {\n if (shouldFailForever(err)) return failForever();\n if (shouldFail(err)) return failInternal();\n // If the error does not trigger a failure, we do nothing.\n };\n\n const hardReset = () => {\n failedForever.set(false);\n failureCount.set(0);\n halfOpen.set(false);\n };\n\n return {\n status,\n isClosed,\n isOpen,\n fail,\n success,\n halfOpen: tryOnce,\n hardReset,\n destroy: () => effectRef.destroy(),\n };\n}\n\n/** @internal */\nfunction createNeverBrokenCircuitBreaker(): CircuitBreaker {\n return {\n isClosed: computed(() => true),\n isOpen: computed(() => false),\n status: signal('CLOSED'),\n fail: () => {\n // noop\n },\n success: () => {\n // noop\n },\n halfOpen: () => {\n // noop\n },\n hardReset: () => {\n // noop\n },\n destroy: () => {\n // noop\n },\n };\n}\n\nconst CB_DEFAULT_OPTIONS = new InjectionToken<\n Required<Omit<CreateCircuitBreakerOptions, 'treshold'>>\n>('MMSTACK_CIRCUIT_BREAKER_DEFAULT_OPTIONS');\n\n/**\n * Provides application-wide default options for {@link createCircuitBreaker}.\n * Any `createCircuitBreaker()` call without explicit options (or with only\n * partial options) merges these defaults in, so you can centralize threshold /\n * timeout / failure-classifier behavior in one place.\n *\n * Per-call options always win over the provided defaults.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideCircuitBreakerDefaultOptions({\n * threshold: 10,\n * timeout: 60_000,\n * shouldFailForever: (err) =>\n * err instanceof HttpErrorResponse && [401, 403].includes(err.status),\n * }),\n * ],\n * });\n * ```\n */\nexport function provideCircuitBreakerDefaultOptions(\n options: CircuitBreakerOptions,\n): Provider {\n return {\n provide: CB_DEFAULT_OPTIONS,\n useValue: {\n ...DEFAULT_OPTIONS,\n ...normalizeThreshold(options),\n },\n };\n}\n\nfunction injectCircuitBreakerOptions(\n injector = inject(Injector),\n): Required<Omit<CreateCircuitBreakerOptions, 'treshold'>> {\n return injector.get(CB_DEFAULT_OPTIONS, DEFAULT_OPTIONS, {\n optional: true,\n });\n}\n\n/** @internal — strips the deprecated `treshold` field and folds it into `threshold` */\nfunction normalizeThreshold(\n opt: CircuitBreakerOptions | undefined,\n): Partial<Omit<CreateCircuitBreakerOptions, 'treshold'>> {\n if (!opt || typeof opt !== 'object' || 'isClosed' in opt) return {};\n const { treshold, threshold, ...rest } = opt;\n return {\n ...rest,\n threshold: threshold ?? treshold,\n };\n}\n\n/**\n * Creates a circuit breaker instance.\n *\n * @param options - Configuration options for the circuit breaker. Can be:\n * - `undefined`: Uses defaults (threshold: 5, timeout: 30000ms) or provided defaults via {@link provideCircuitBreakerDefaultOptions}.\n * - `false`: Creates a \"no-op\" circuit breaker that is always closed (never trips).\n * - `true`: Creates a circuit breaker with default settings.\n * - `CircuitBreaker`: Reuses an existing `CircuitBreaker` instance.\n * - `{ threshold?: number; timeout?: number; }`: Creates a circuit breaker with the specified threshold and timeout.\n *\n * @returns A `CircuitBreaker` instance.\n *\n * @example\n * // Create a circuit breaker with default settings:\n * const breaker = createCircuitBreaker();\n *\n * // Create a circuit breaker with custom settings:\n * const customBreaker = createCircuitBreaker({ threshold: 10, timeout: 60000 });\n *\n * // Share a single circuit breaker instance across multiple resources:\n * const sharedBreaker = createCircuitBreaker();\n * const resource1 = queryResource(..., { circuitBreaker: sharedBreaker });\n * const resource2 = mutationResource(..., { circuitBreaker: sharedBreaker });\n */\nexport function createCircuitBreaker(\n opt?: CircuitBreakerOptions,\n injector?: Injector,\n): CircuitBreaker {\n if (opt === false) return createNeverBrokenCircuitBreaker();\n\n if (typeof opt === 'object' && 'isClosed' in opt) return opt;\n\n const { threshold, timeout, shouldFail, shouldFailForever } = {\n ...injectCircuitBreakerOptions(injector),\n ...normalizeThreshold(opt),\n };\n\n return internalCeateCircuitBreaker(\n threshold,\n timeout,\n shouldFail,\n shouldFailForever,\n );\n}\n","// Heavily inspired by: https://dev.to/kasual1/request-deduplication-in-angular-3pd8\n\nimport {\n HttpContext,\n HttpContextToken,\n type HttpEvent,\n type HttpHandlerFn,\n type HttpInterceptorFn,\n type HttpRequest,\n} from '@angular/common/http';\nimport { finalize, shareReplay, type Observable } from 'rxjs';\nimport { hashRequest } from './hash-request';\n\nconst NO_DEDUPE = new HttpContextToken<boolean>(() => false);\n\n/**\n * Disables request deduplication for a specific HTTP request.\n *\n * @param ctx - The `HttpContext` to modify. If not provided, a new `HttpContext` is created.\n * @returns The modified `HttpContext` with the `NO_DEDUPE` token set to `true`.\n *\n * @example\n * // Disable deduplication for a specific POST request:\n * const context = noDedupe();\n * this.http.post('/api/data', payload, { context }).subscribe(...);\n *\n * // Disable deduplication, modifying an existing context:\n * let context = new HttpContext();\n * context = noDedupe(context);\n * this.http.post('/api/data', payload, { context }).subscribe(...);\n */\nexport function noDedupe(ctx: HttpContext = new HttpContext()) {\n return ctx.set(NO_DEDUPE, true);\n}\n\n/**\n * Creates an `HttpInterceptorFn` that deduplicates identical HTTP requests.\n * If multiple identical requests (same URL and parameters) are made concurrently,\n * only the first request will be sent to the server. Subsequent requests will\n * receive the response from the first request.\n *\n * @param allowed - An array of HTTP methods for which deduplication should be enabled.\n * Defaults to `['GET', 'DELETE', 'HEAD', 'OPTIONS']`.\n * @param keyFn - Optional function to compute the dedupe key from a request.\n * Defaults to `hashRequest`, which includes method, URL,\n * response type, params, and body.\n *\n * @returns An `HttpInterceptorFn` that implements the request deduplication logic.\n *\n * @example\n * // In your app.config.ts or module providers:\n * import { provideHttpClient, withInterceptors } from '@angular/common/http';\n * import { createDedupeRequestsInterceptor } from './your-dedupe-interceptor';\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([createDedupeRequestsInterceptor()])),\n * // ... other providers\n * ],\n * };\n *\n * // You can also specify which methods should be deduped\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([createDedupeRequestsInterceptor(['GET'])])), // only dedupe GET calls\n * // ... other providers\n * ],\n * };\n */\nexport function createDedupeRequestsInterceptor(\n allowed = ['GET', 'DELETE', 'HEAD', 'OPTIONS'],\n keyFn: (req: HttpRequest<unknown>) => string = hashRequest,\n): HttpInterceptorFn {\n const inFlight = new Map<string, Observable<HttpEvent<unknown>>>();\n\n const DEDUPE_METHODS = new Set<string>(allowed);\n\n return (\n req: HttpRequest<unknown>,\n next: HttpHandlerFn,\n ): Observable<HttpEvent<unknown>> => {\n if (!DEDUPE_METHODS.has(req.method) || req.context.get(NO_DEDUPE))\n return next(req);\n\n const key = keyFn(req);\n const found = inFlight.get(key);\n\n if (found) return found;\n\n const request = next(req).pipe(\n finalize(() => inFlight.delete(key)),\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n inFlight.set(key, request);\n\n return request;\n };\n}\n","import {\n HttpContext,\n HttpHeaders,\n HttpParams,\n HttpResourceRequest,\n} from '@angular/common/http';\nimport { type ValueEqualityFn } from '@angular/core';\nimport { hash } from './hash-unknown';\n\nfunction equalTransferCache(\n a: HttpResourceRequest['transferCache'],\n b: HttpResourceRequest['transferCache'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n if (typeof a !== typeof b) return false;\n if (typeof a === 'boolean' || typeof b === 'boolean') return a === b;\n\n if (!a.includeHeaders && !b.includeHeaders) return true;\n if (!a.includeHeaders || !b.includeHeaders) return false;\n\n if (a.includeHeaders.length !== b.includeHeaders.length) return false;\n\n if (a.includeHeaders.length === 0) return true;\n\n const aSet = new Set(a.includeHeaders ?? []);\n\n return b.includeHeaders.every((header) => aSet.has(header));\n}\n\nfunction equalParamArray(\n a: Array<string | number | boolean>,\n b: Array<string | number | boolean>,\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n if (a.length !== b.length) return false;\n\n return a.every((value) => b.includes(value));\n}\n\nfunction headersToObject(headerClass: HttpHeaders) {\n const headers: Exclude<\n Required<HttpResourceRequest['headers']>,\n HttpHeaders | undefined\n > = {};\n\n headerClass.keys().forEach((key) => {\n const value = headerClass.getAll(key);\n if (value === null) return;\n if (value.length === 1) {\n headers[key] = value[0];\n } else {\n headers[key] = value;\n }\n });\n\n return headers;\n}\n\nfunction paramToObject(paramsClass: HttpParams) {\n const params: Exclude<\n Required<HttpResourceRequest['params']>,\n HttpParams | undefined\n > = {};\n\n paramsClass.keys().forEach((key) => {\n const value = paramsClass.getAll(key);\n if (value === null) return;\n if (value.length === 1) {\n params[key] = value[0];\n } else {\n params[key] = value;\n }\n });\n\n return params;\n}\n\nfunction equalParams(\n a: HttpResourceRequest['params'],\n b: HttpResourceRequest['params'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n const aObj = a instanceof HttpParams ? paramToObject(a) : a;\n const bObj = b instanceof HttpParams ? paramToObject(b) : b;\n\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n if (aKeys.length !== bKeys.length) return false;\n\n return aKeys.every((key) => {\n if (Array.isArray(aObj[key]) || Array.isArray(bObj[key])) {\n return equalParamArray(\n Array.isArray(aObj[key]) ? aObj[key] : [aObj[key]],\n Array.isArray(bObj[key]) ? bObj[key] : [bObj[key]],\n );\n }\n\n return aObj[key] === bObj[key];\n });\n}\n\nfunction equalBody(\n a: HttpResourceRequest['body'],\n b: HttpResourceRequest['body'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n return hash(a) === hash(b);\n}\n\nfunction equalHeaders(\n a: HttpResourceRequest['headers'],\n b: HttpResourceRequest['headers'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n const aObj = a instanceof HttpHeaders ? headersToObject(a) : a;\n const bObj = b instanceof HttpHeaders ? headersToObject(b) : b;\n\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n if (aKeys.length !== bKeys.length) return false;\n return aKeys.every((key) => {\n if (Array.isArray(aObj[key]) || Array.isArray(bObj[key])) {\n return equalParamArray(\n Array.isArray(aObj[key]) ? aObj[key] : [aObj[key]],\n Array.isArray(bObj[key]) ? bObj[key] : [bObj[key]],\n );\n }\n\n return aObj[key] === bObj[key];\n });\n}\n\nfunction toHttpContextEntries(ctx: HttpResourceRequest['context']) {\n if (!ctx) return [];\n\n if (ctx instanceof HttpContext) {\n const tokens = Array.from(ctx.keys());\n return tokens.map((key) => [key.toString(), ctx.get(key)] as const);\n }\n\n if (typeof ctx === 'object') {\n return Object.entries(ctx) as Array<[string, unknown]>;\n }\n\n return [];\n}\n\nfunction equalContext(\n a: HttpResourceRequest['context'],\n b: HttpResourceRequest['context'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n const aEntries = toHttpContextEntries(a);\n const bEntries = toHttpContextEntries(b);\n if (aEntries.length !== bEntries.length) return false;\n if (aEntries.length === 0) return true;\n const bMap = new Map(bEntries);\n return aEntries.every(([key, value]) => value === bMap.get(key));\n}\n\nexport function createEqualRequest<TResult>(\n equalResult?: ValueEqualityFn<TResult>,\n) {\n const eqb = equalResult ?? equalBody;\n\n return (\n a: Partial<HttpResourceRequest> | undefined,\n b: Partial<HttpResourceRequest> | undefined,\n ) => {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n if (a.url !== b.url) return false;\n if (a.method !== b.method) return false;\n if (!equalParams(a.params, b.params)) return false;\n if (!equalHeaders(a.headers, b.headers)) return false;\n if (!eqb(a.body as TResult, b.body as TResult)) return false;\n if (!equalContext(a.context, b.context)) return false;\n\n if (a.withCredentials !== b.withCredentials) return false;\n if (a.reportProgress !== b.reportProgress) return false;\n if (!equalTransferCache(a.transferCache, b.transferCache)) return false;\n\n return true;\n };\n}\n","export function hasSlowConnection() {\n if (\n window &&\n 'navigator' in window &&\n 'connection' in window.navigator &&\n typeof window.navigator.connection === 'object' &&\n !!window.navigator.connection &&\n 'effectiveType' in window.navigator.connection &&\n typeof window.navigator.connection.effectiveType === 'string'\n )\n return window.navigator.connection.effectiveType.endsWith('2g');\n\n return false;\n}\n","import { type HttpHeaders, type HttpResourceRef } from '@angular/common/http';\nimport {\n linkedSignal,\n type Signal,\n type ValueEqualityFn,\n type WritableSignal,\n} from '@angular/core';\n\nfunction persist<T>(\n value: WritableSignal<T>,\n equal?: ValueEqualityFn<T>,\n): WritableSignal<T>;\n\nfunction persist<T>(value: Signal<T>, equal?: ValueEqualityFn<T>): Signal<T>;\n\nfunction persist<T>(\n src: WritableSignal<T> | Signal<T>,\n equal?: ValueEqualityFn<T>,\n): WritableSignal<T> | Signal<T> {\n // linkedSignal allows us to access previous source value\n\n const persisted = linkedSignal<T, T>({\n source: () => src(),\n computation: (next, prev) => {\n if (next === undefined && prev !== undefined) return prev.value;\n return next;\n },\n equal,\n });\n\n // if original value was WritableSignal then override linkedSignal methods to original...angular uses linkedSignal under the hood in ResourceImpl, this applies to that.\n if ('set' in src) {\n persisted.set = src.set;\n persisted.update = src.update;\n persisted.asReadonly = src.asReadonly;\n }\n\n return persisted;\n}\n\nexport function persistResourceValues<T>(\n resource: HttpResourceRef<T>,\n shouldPersist = false,\n equal?: ValueEqualityFn<T>,\n): HttpResourceRef<T> {\n if (!shouldPersist) return resource;\n\n return {\n ...resource,\n statusCode: persist<number | undefined>(resource.statusCode),\n headers: persist<HttpHeaders | undefined>(resource.headers),\n value: persist<T>(resource.value, equal),\n };\n}\n","import { HttpResourceRef } from '@angular/common/http';\nimport { DestroyRef } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { interval } from 'rxjs';\n\n// refresh resource every n miliseconds or don't refresh if undefined provided. 0 also excluded, due to it not being a valid usecase\nexport function refresh<T>(\n resource: HttpResourceRef<T>,\n destroyRef: DestroyRef,\n refresh?: number,\n): HttpResourceRef<T> {\n if (!refresh) return resource; // no refresh requested\n\n // we can use RxJs here as reloading the resource will always be a side effect & as such does not impact the reactive graph in any way.\n let sub = interval(refresh)\n .pipe(takeUntilDestroyed(destroyRef))\n .subscribe(() => resource.reload());\n\n const reload = (): boolean => {\n sub.unsubscribe(); // do not conflict with manual reload\n\n const hasReloaded = resource.reload();\n\n // resubscribe after manual reload\n sub = interval(refresh)\n .pipe(takeUntilDestroyed(destroyRef))\n .subscribe(() => resource.reload());\n\n return hasReloaded;\n };\n\n return {\n ...resource,\n reload,\n destroy: () => {\n sub.unsubscribe();\n resource.destroy();\n },\n };\n}\n","import { type HttpResourceRef } from '@angular/common/http';\nimport { effect, untracked } from '@angular/core';\n\nexport type RetryOptions =\n | number\n | {\n max?: number;\n backoff?: number;\n };\n\n/**\n * Callback fired by the retry wrapper for every failed attempt.\n * `retryCount` is the number of retries that already happened before this\n * error (`0` on the original failure, `1` after the first retry, etc.).\n * `isFinal` is `true` when no further retry will be scheduled — either because\n * retries are exhausted or `retry` was unset/0.\n */\nexport type RetryErrorCallback<TError = unknown> = (\n err: TError,\n retryCount: number,\n isFinal: boolean,\n) => void;\n\n// Retry on error, if number is provided it will retry that many times with exponential backoff, otherwise it will use the options provided\nexport function retryOnError<T>(\n res: HttpResourceRef<T>,\n opt?: RetryOptions,\n onError?: RetryErrorCallback,\n): HttpResourceRef<T> {\n const max = opt ? (typeof opt === 'number' ? opt : (opt.max ?? 0)) : 0;\n const backoff = typeof opt === 'object' ? (opt.backoff ?? 1000) : 1000;\n\n let retries = 0;\n\n let timeout: ReturnType<typeof setTimeout> | undefined;\n\n const handleError = () => {\n const err = untracked(res.error);\n const isFinal = retries >= max;\n\n onError?.(err, retries, isFinal);\n\n if (isFinal) return;\n\n retries++;\n\n if (timeout) clearTimeout(timeout);\n\n setTimeout(\n () => res.reload(),\n retries <= 0 ? 0 : backoff * Math.pow(2, retries - 1),\n );\n };\n\n const onSuccess = () => {\n if (timeout) clearTimeout(timeout);\n retries = 0;\n };\n\n const ref = effect(() => {\n switch (res.status()) {\n case 'error':\n return handleError();\n case 'resolved':\n return onSuccess();\n }\n });\n\n return {\n ...res,\n destroy: () => {\n ref.destroy(); // cleanup on manual destroy\n res.destroy();\n },\n };\n}\n","import { inject, Injectable } from '@angular/core';\nimport { sensor } from '@mmstack/primitives';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ResourceSensors {\n readonly networkStatus = sensor('networkStatus');\n}\n\nexport function injectNetworkStatus() {\n return inject(ResourceSensors).networkStatus;\n}\n","import { HttpResourceRef } from '@angular/common/http';\n\nexport function toResourceObject<T>(\n res: HttpResourceRef<T>,\n): HttpResourceRef<T> {\n return {\n asReadonly: () => res.asReadonly(),\n destroy: () => res.destroy(),\n error: res.error,\n headers: res.headers,\n isLoading: res.isLoading,\n progress: res.progress,\n status: res.status,\n statusCode: res.statusCode,\n value: res.value,\n reload: () => res.reload(),\n hasValue: (() => res.hasValue()) as HttpResourceRef<T>['hasValue'],\n set: (v) => res.set(v),\n update: (v) => res.update(v),\n };\n}\n","import {\n HttpClient,\n HttpHeaders,\n httpResource,\n HttpResponse,\n type HttpResourceOptions,\n type HttpResourceRef,\n type HttpResourceRequest,\n} from '@angular/common/http';\nimport {\n computed,\n DestroyRef,\n effect,\n inject,\n isDevMode,\n linkedSignal,\n Signal,\n untracked,\n WritableSignal,\n} from '@angular/core';\nimport { toWritable } from '@mmstack/primitives';\nimport { firstValueFrom } from 'rxjs';\nimport {\n catchValueError,\n CircuitBreakerOptions,\n createCircuitBreaker,\n createEqualRequest,\n hashRequest,\n hasSlowConnection,\n injectNetworkStatus,\n injectQueryCache,\n persistResourceValues,\n refresh,\n retryOnError,\n setCacheContext,\n toResourceObject,\n type RetryOptions,\n} from './util';\nimport { CacheEntry } from './util/cache/cache';\n\n/**\n * Options for configuring caching behavior of a `queryResource`.\n * - `true`: Enables caching with default settings.\n * - `{ ttl?: number; staleTime?: number; hash?: (req: HttpResourceRequest) => string; }`: Configures caching with custom settings.\n */\ntype ResourceCacheOptions =\n | true\n | {\n /**\n * The Time To Live (TTL) for the cached data, in milliseconds. After this time, the cached data is\n * considered expired and will be refetched.\n */\n ttl?: number;\n /**\n * The duration, in milliseconds, during which stale data can be served while a revalidation request\n * is made in the background.\n */\n staleTime?: number;\n /**\n * A custom function to generate the cache key. Defaults to using the request URL with parameters.\n * Provide a custom hash function if you need more control over how cache keys are generated,\n * for instance, to ignore certain query parameters or to use request body for the cache key.\n */\n hash?: (req: HttpResourceRequest) => string;\n /**\n * Whether to bust the browser cache by appending a unique query parameter to the request URL.\n * This is useful for ensuring that the latest data is fetched from the server, bypassing any\n * cached responses in the browser. The unique parameter is removed before calling the cache function, so it does not affect the cache key.\n * @default false - By default, the resource will not bust the browser cache.\n */\n bustBrowserCache?: boolean;\n /**\n * Whether to ignore the `Cache-Control` headers from the server when caching responses.\n * If set to `true`, the resource will not respect any cache directives from the server,\n * allowing you to control caching behavior entirely through the resource options.\n * @default false - By default the resource will respect `Cache-Control` headers.\n */\n ignoreCacheControl?: boolean;\n /**\n * Whether to persist the cache entry in the local DB instance.\n * @default false - By default, the cache entry is not persisted.\n */\n persist?: boolean;\n };\n\n/**\n * Options for configuring a `queryResource`.\n */\nexport type QueryResourceOptions<TResult, TRaw = TResult> = HttpResourceOptions<\n TResult,\n TRaw\n> & {\n /**\n * Whether to keep the previous value of the resource while a refresh is in progress.\n * Defaults to `false`. Also keeps status & headers while refreshing.\n */\n keepPrevious?: boolean;\n /**\n * The refresh interval, in milliseconds. If provided, the resource will automatically\n * refresh its data at the specified interval.\n */\n refresh?: number;\n /**\n * Options for retrying failed requests.\n */\n retry?: RetryOptions;\n /**\n * Called on every failed attempt, including each retry.\n *\n * @param err - The error from the underlying HTTP request.\n * @param retryCount - The number of retries that already happened before\n * this error (`0` on the original failure, `1` after the first retry, etc.).\n * @param isFinal - `true` when no further retry will be scheduled — either\n * because retries are exhausted or `retry` was unset/0. Branch on this for\n * \"user actually needs to know\" side effects (toasts, error reporting).\n */\n onError?: (err: unknown, retryCount: number, isFinal: boolean) => void;\n /**\n * Options for configuring a circuit breaker for the resource.\n */\n circuitBreaker?: CircuitBreakerOptions | true;\n /**\n * Options for enabling and configuring caching for the resource.\n */\n cache?: ResourceCacheOptions;\n /**\n * Trigger a request every time the request function is triggered, even if the request parameters are the same.\n * @default false\n */\n triggerOnSameRequest?: boolean;\n};\n\n/**\n * The reason a query resource is currently in the `disabled` state, or `null`\n * if it is enabled. Useful for branching UI on cause (e.g. \"offline\" vs\n * \"circuit tripped\" vs \"nothing to fetch yet\").\n */\nexport type DisabledReason = 'offline' | 'circuit-open' | 'no-request';\n\n/**\n * Represents a resource created by `queryResource`. Extends `HttpResourceRef` with additional properties.\n */\nexport type QueryResourceRef<TResult> = Omit<\n HttpResourceRef<TResult>,\n 'headers' | 'statusCode'\n> & {\n /**\n * Linkedsignal of the response headers, when available.\n */\n readonly headers: WritableSignal<HttpHeaders | undefined>;\n /**\n * Linkedsignal of the response status code, when available.\n */\n readonly statusCode: WritableSignal<number | undefined>;\n /**\n * A signal indicating whether the resource is currently disabled (due to circuit breaker, offline, or undefined request).\n */\n disabled: Signal<boolean>;\n /**\n * Why the resource is currently disabled, or `null` if it is enabled.\n * Maps to one of: `'offline'`, `'circuit-open'`, `'no-request'`.\n */\n disabledReason: Signal<DisabledReason | null>;\n /**\n * Prefetches data for the resource, populating the cache if caching is enabled. This can be\n * used to proactively load data before it's needed. If a slow connection is detected, prefetching is skipped.\n *\n * @param req - Optional partial request parameters to use for the prefetch. This allows you\n * to prefetch data with different parameters than the main resource request.\n */\n prefetch: (req?: Partial<HttpResourceRequest> | string) => Promise<void>;\n};\n\n/**\n * Creates an HTTP resource with features like caching, retries, refresh intervals, circuit breaker, and optimistic updates. Without additional options it is equivalent to simply calling `httpResource`.\n * This overload is for when a `defaultValue` is provided, ensuring that the resource's value is always defined.\n * @param request A function that returns the `HttpResourceRequest` or a URL string to be made. This function\n * is called reactively, so the request can change over time. If the function\n * returns `undefined`, the resource is considered \"disabled\" and no request will be made.\n * @param options Configuration options for the resource. These options extend the basic\n * `HttpResourceOptions` and add features like `keepPrevious`, `refresh`, `retry`,\n * `onError`, `circuitBreaker`, and `cache`. Additionally, when a `defaultValue` is provided, the resource's value will always be defined, even if the underlying HTTP request fails or is disabled.\n * @returns An `QueryResourceRef` instance, which extends the basic `HttpResourceRef` with additional features.\n */\nexport function queryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | string | undefined | void,\n options: QueryResourceOptions<TResult, TRaw> & {\n defaultValue: NoInfer<TResult>;\n },\n): QueryResourceRef<TResult>;\n\n/**\n * Creates an extended HTTP resource with features like caching, retries, refresh intervals,\n * circuit breaker, and optimistic updates. Without additional options it is equivalent to simply calling `httpResource`.\n *\n * @param request A function that returns the `HttpResourceRequest` or a URL string to be made. This function\n * is called reactively, so the request can change over time. If the function\n * returns `undefined`, the resource is considered \"disabled\" and no request will be made.\n * @param options Configuration options for the resource. These options extend the basic\n * `HttpResourceOptions` and add features like `keepPrevious`, `refresh`, `retry`,\n * `onError`, `circuitBreaker`, and `cache`.\n * @returns An `QueryResourceRef` instance, which extends the basic `HttpResourceRef` with additional features.\n */\nexport function queryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | string | undefined | void,\n options?: QueryResourceOptions<TResult, TRaw>,\n): QueryResourceRef<TResult | undefined>;\n\nexport function queryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | string | undefined | void,\n options?: QueryResourceOptions<TResult, TRaw>,\n): QueryResourceRef<TResult | undefined> {\n const cache = injectQueryCache<TResult>(options?.injector);\n\n const destroyRef = options?.injector\n ? options.injector.get(DestroyRef)\n : inject(DestroyRef);\n\n const cb = createCircuitBreaker(\n options?.circuitBreaker === true\n ? undefined\n : (options?.circuitBreaker ?? false),\n options?.injector,\n );\n\n const networkAvailable = injectNetworkStatus();\n\n const eq = options?.triggerOnSameRequest\n ? undefined\n : createEqualRequest(options?.equal);\n\n const rawRequest = computed(() => request() ?? undefined);\n\n const disabledReason = computed<DisabledReason | null>(() => {\n if (!networkAvailable()) return 'offline';\n if (cb.isOpen()) return 'circuit-open';\n if (!rawRequest()) return 'no-request';\n return null;\n });\n\n const stableRequest = computed(\n (): HttpResourceRequest | undefined => {\n if (disabledReason() !== null) return undefined;\n const req = rawRequest();\n if (!req) return undefined;\n if (typeof req === 'string') return { method: 'GET', url: req };\n return req;\n },\n {\n equal: (a, b) => {\n if (eq) return eq(a, b);\n return a === b;\n },\n },\n );\n\n const hashFn =\n typeof options?.cache === 'object'\n ? (options.cache.hash ?? hashRequest)\n : hashRequest;\n\n const staleTime =\n typeof options?.cache === 'object' ? options.cache.staleTime : 0;\n const ttl =\n typeof options?.cache === 'object' ? options.cache.ttl : undefined;\n\n const cacheKey = computed(() => {\n const r = stableRequest();\n if (!r) return null;\n return hashFn(r);\n });\n\n const bustBrowserCache =\n typeof options?.cache === 'object' &&\n options.cache.bustBrowserCache === true;\n\n const ignoreCacheControl =\n typeof options?.cache === 'object' &&\n options.cache.ignoreCacheControl === true;\n\n const persist =\n typeof options?.cache === 'object' && options.cache.persist === true;\n\n const cachedRequest = options?.cache\n ? computed(() => {\n const r = stableRequest();\n if (!r) return r;\n\n return {\n ...r,\n context: setCacheContext(r.context, {\n staleTime,\n ttl,\n key: cacheKey() ?? hashFn(r),\n bustBrowserCache,\n ignoreCacheControl,\n persist,\n }),\n };\n })\n : stableRequest;\n\n let resource = toResourceObject(\n httpResource<TResult>(cachedRequest, {\n ...options,\n parse: options?.parse as any, // Not my favorite thing to do, but here it is completely safe.\n }) as HttpResourceRef<TResult>,\n );\n\n resource = catchValueError(resource, options?.defaultValue as TResult);\n\n // get full HttpResonse from Cache\n const cachedEvent = cache.getEntryOrKey(cacheKey);\n\n const cacheEntry = linkedSignal<\n CacheEntry<HttpResponse<TResult>> | string | null,\n { key: string; value: TResult | null } | null\n >({\n source: () => cachedEvent(),\n computation: (entry, prev) => {\n if (!entry) return null;\n\n if (\n typeof entry === 'string' &&\n prev &&\n prev.value !== null &&\n prev.value.key === entry\n ) {\n return prev.value;\n }\n\n if (typeof entry === 'string') return { key: entry, value: null };\n\n if (!(entry.value instanceof HttpResponse))\n return { key: entry.key, value: null };\n\n return {\n value: entry.value.body,\n key: entry.key,\n };\n },\n });\n\n resource = refresh(resource, destroyRef, options?.refresh);\n resource = retryOnError(resource, options?.retry, options?.onError);\n\n resource = persistResourceValues<TResult>(\n resource,\n options?.keepPrevious,\n options?.equal,\n );\n\n const value = options?.cache\n ? toWritable(\n computed((): TResult => {\n resource.value();\n return cacheEntry()?.value ?? resource.value();\n }),\n resource.value.set,\n resource.value.update,\n )\n : resource.value;\n\n // iterate circuit breaker state, is effect as a computed would cause a circular dependency (resource -> cb -> resource)\n const cbEffectRef = effect(() => {\n const status = resource.status();\n if (status === 'error')\n cb.fail(untracked(resource.error) as Error | undefined);\n else if (status === 'resolved') cb.success();\n });\n\n const set = (value: TResult) => {\n resource.value.set(value);\n const k = untracked(cacheKey);\n if (options?.cache && k)\n cache.store(\n k,\n new HttpResponse({\n body: value,\n status: 200,\n statusText: 'OK',\n }),\n staleTime,\n ttl,\n persist,\n );\n };\n\n const update = (updater: (value: TResult) => TResult) => {\n set(updater(untracked(resource.value)));\n };\n\n const client = options?.injector\n ? options.injector.get(HttpClient)\n : inject(HttpClient);\n\n return {\n ...resource,\n value,\n set,\n update,\n statusCode: linkedSignal(resource.statusCode),\n headers: linkedSignal(resource.headers),\n disabled: computed(() => disabledReason() !== null),\n disabledReason,\n reload: () => {\n cb.halfOpen(); // open the circuit for manual reload\n return resource.reload();\n },\n destroy: () => {\n cbEffectRef.destroy();\n cb.destroy();\n resource.destroy();\n },\n prefetch: async (partial) => {\n if (!options?.cache || hasSlowConnection()) return Promise.resolve();\n\n const request = untracked(stableRequest);\n\n const partialReq =\n typeof partial === 'string' ? { method: 'GET', url: partial } : partial;\n\n const prefetchRequest = {\n ...request,\n ...partialReq,\n };\n if (!prefetchRequest.url) return Promise.resolve();\n\n const key = hashFn({\n ...prefetchRequest,\n url: prefetchRequest.url ?? '',\n });\n\n const found = cache.getUntracked(key);\n if (found && !found.isStale) return Promise.resolve();\n\n try {\n await firstValueFrom(\n client.request(prefetchRequest.method ?? 'GET', prefetchRequest.url, {\n ...prefetchRequest,\n credentials: prefetchRequest.credentials as\n | RequestCredentials\n | undefined,\n priority: prefetchRequest.priority as RequestPriority | undefined,\n cache: prefetchRequest.cache as RequestCache | undefined,\n mode: prefetchRequest.mode as RequestMode | undefined,\n redirect: prefetchRequest.redirect as RequestRedirect | undefined,\n context: setCacheContext(prefetchRequest.context, {\n staleTime,\n ttl,\n key: hashFn({\n ...prefetchRequest,\n url: prefetchRequest.url ?? '',\n }),\n bustBrowserCache,\n ignoreCacheControl,\n persist,\n }),\n headers: prefetchRequest.headers as HttpHeaders,\n observe: 'response',\n }),\n );\n\n return;\n } catch (err) {\n if (isDevMode()) console.error('Prefetch failed: ', err);\n return;\n }\n },\n };\n}\n","import { HttpResourceRequest } from '@angular/common/http';\nimport { computed, inject, Injector, signal, untracked } from '@angular/core';\nimport { nestedEffect } from '@mmstack/primitives';\nimport {\n queryResource,\n QueryResourceOptions,\n QueryResourceRef,\n} from './query-resource';\n\n/**\n * A reference to a manually triggered query resource. This type extends the standard `QueryResourceRef`\n * with an additional `trigger` method that allows you to manually trigger the resource request.\n * @see QueryResourceRef\n */\nexport type ManualQueryResourceRef<TResult> = QueryResourceRef<TResult> & {\n trigger: (\n req?: HttpResourceRequest | string,\n injector?: Injector,\n ) => Promise<TResult>;\n};\n\n/**\n * Creates a manually triggered HTTP resource with features like caching, retries, refresh intervals, circuit breaker, and optimistic updates. Without additional options it is equivalent to simply calling `httpResource`.\n * This overload is for when a `defaultValue` is provided, ensuring that the resource's value is always defined.\n * @param request A function that returns the `HttpResourceRequest` or a URL string to be made. This function\n * is called reactively, so the request can change over time. If the function\n * returns `undefined`, the resource is considered \"disabled\" and no request will be made.\n * @param options Configuration options for the resource. These options extend the basic\n * `HttpResourceOptions` and add features like `keepPrevious`, `refresh`, `retry`,\n * `onError`, `circuitBreaker`, and `cache`. Additionally, when a `defaultValue` is provided, the resource's value will always be defined, even if the underlying HTTP request fails or is disabled.\n * @returns An `ManualQueryResourceRef` instance, which extends the basic `QueryResourceRef` with additional features.\n */\nexport function manualQueryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | string | undefined | void,\n options: QueryResourceOptions<TResult, TRaw> & {\n defaultValue: NoInfer<TResult>;\n },\n): ManualQueryResourceRef<TResult>;\n\n/**\n * Creates a manually triggered extended HTTP resource with features like caching, retries, refresh intervals,\n * circuit breaker, and optimistic updates. Without additional options it is equivalent to simply calling `httpResource`.\n *\n * @param request A function that returns the `HttpResourceRequest` or a URL string to be made. This function\n * is called reactively, so the request can change over time. If the function\n * returns `undefined`, the resource is considered \"disabled\" and no request will be made.\n * @param options Configuration options for the resource. These options extend the basic\n * `HttpResourceOptions` and add features like `keepPrevious`, `refresh`, `retry`,\n * `onError`, `circuitBreaker`, and `cache`.\n * @returns An `ManualQueryResourceRef` instance, which extends the basic `QueryResourceRef` with additional features.\n */\nexport function manualQueryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | string | undefined | void,\n options?: QueryResourceOptions<TResult, TRaw>,\n): ManualQueryResourceRef<TResult | undefined>;\n\nexport function manualQueryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | string | undefined | void,\n options?: QueryResourceOptions<TResult, TRaw>,\n): ManualQueryResourceRef<TResult | undefined> {\n const trigger = signal<{\n epoch: number;\n override?: HttpResourceRequest | string;\n }>(\n { epoch: 0 },\n {\n equal: (a, b) => a.epoch === b.epoch,\n },\n );\n\n const injector = options?.injector ?? inject(Injector);\n\n const req = computed(\n () => {\n const state = trigger();\n if (state.epoch === 0) return;\n if (state.override) return state.override;\n\n return untracked(request);\n },\n {\n equal: () => false,\n },\n );\n\n const resource = queryResource(req, options);\n\n return {\n ...resource,\n trigger: (override, injectorOverride) => {\n trigger.update((s) => ({\n epoch: s.epoch + 1,\n override,\n }));\n\n return new Promise<TResult>((res, rej) => {\n const watcher = nestedEffect(\n () => {\n const status = resource.status();\n\n if (status === 'resolved') {\n watcher.destroy();\n res(untracked(resource.value) as TResult);\n } else if (status === 'error') {\n watcher.destroy();\n rej(untracked(resource.error));\n }\n },\n { injector: injectorOverride ?? injector },\n );\n });\n },\n };\n}\n","import { type HttpResourceRequest } from '@angular/common/http';\nimport {\n computed,\n DestroyRef,\n effect,\n inject,\n linkedSignal,\n Signal,\n signal,\n ValueEqualityFn,\n} from '@angular/core';\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\nimport { catchError, combineLatestWith, filter, map, of } from 'rxjs';\nimport {\n queryResource,\n type QueryResourceOptions,\n type QueryResourceRef,\n} from './query-resource';\nimport { createCircuitBreaker, createEqualRequest } from './util';\n\n/**\n * @internal\n * Helper type for inferring the request body type based on the HTTP method.\n */\ntype NextRequest<\n TMethod extends HttpResourceRequest['method'],\n TMutation,\n> = TMethod extends 'DELETE' | 'delete'\n ? Omit<HttpResourceRequest, 'body' | 'method'> & { method: TMethod }\n : Omit<HttpResourceRequest, 'body' | 'method'> & {\n body: TMutation;\n method: TMethod;\n };\n\n/**\n * @internal\n * Helper type for tracking mutation status.\n */\ntype StatusResult<TResult> =\n | {\n status: 'error';\n error: unknown;\n }\n | {\n status: 'resolved';\n value: TResult;\n };\n\n/**\n * Options for configuring a `mutationResource`.\n *\n * @typeParam TResult - The type of the expected result from the mutation.\n * @typeParam TRaw - The raw response type from the HTTP request (defaults to TResult).\n * @typeParam TCTX - The type of the context value returned by `onMutate`.\n */\nexport type MutationResourceOptions<\n TResult,\n TRaw = TResult,\n TMutation = TResult,\n TCTX = void,\n TICTX = TCTX,\n TError = unknown,\n> = Omit<\n QueryResourceOptions<TResult, TRaw>,\n 'equal' | 'onError' | 'keepPrevious' | 'refresh' | 'cache' // we can't keep previous values, refresh or cache mutations as they are meant to be one-off operations\n> & {\n /**\n * A callback function that is called before the mutation request is made.\n * @param value The value being mutated (the `body` of the request).\n * @returns An optional context value that will be passed to the `onError`, `onSuccess`, and `onSettled` callbacks. This is useful for storing\n * information needed during the mutation lifecycle, such as previous values for optimistic updates or rollback.\n */\n onMutate?: (value: TMutation, initialCTX?: TICTX) => TCTX;\n /**\n * A callback function that is called if the mutation request fails.\n * @param error The error that occurred.\n * @param ctx The context value returned by the `onMutate` callback (or `undefined` if `onMutate` was not provided or returned `undefined`).\n */\n onError?: (error: TError, ctx: NoInfer<TCTX>) => void;\n /**\n * A callback function that is called if the mutation request succeeds.\n * @param value The result of the mutation (the parsed response body).\n * @param ctx The context value returned by the `onMutate` callback (or `undefined` if `onMutate` was not provided or returned `undefined`).\n */\n onSuccess?: (value: TResult, ctx: NoInfer<TCTX>) => void;\n /**\n * A callback function that is called when the mutation request settles (either succeeds or fails).\n * @param ctx The context value returned by the `onMutate` callback (or `undefined` if `onMutate` was not provided or returned `undefined`).\n */\n onSettled?: (ctx: NoInfer<TCTX>) => void;\n /**\n * Whether to queue the mutation requests and execute them in series. For example if network is unavailable or circuit breaker is open.\n * @default false\n */\n queue?: boolean;\n equal?: ValueEqualityFn<TMutation>;\n};\n\n/**\n * Represents a mutation resource created by `mutationResource`. Extends `QueryResourceRef`\n * but removes methods that don't make sense for mutations (like `prefetch`, `value`, etc.).\n *\n * @typeParam TResult - The type of the expected result from the mutation.\n */\nexport type MutationResourceRef<\n TResult,\n TMutation = TResult,\n TICTX = void,\n> = Omit<\n QueryResourceRef<TResult>,\n 'prefetch' | 'value' | 'hasValue' | 'set' | 'update' // we don't allow manually viewing the returned data or updating it manually, prefetching a mutation also doesn't make any sense\n> & {\n /**\n * Executes the mutation.\n *\n * @param value The mutation value (usually the request body).\n * @param ctx An optional initial context value that will be passed to the `onMutate` callback.\n */\n mutate: (value: TMutation, ctx?: TICTX) => void;\n /**\n * A signal that holds the current mutation request, or `null` if no mutation is in progress.\n * This can be useful for tracking the state of the mutation or for displaying loading indicators.\n */\n current: Signal<TMutation | null>;\n};\n\n/**\n * Creates a resource for performing mutations (e.g., POST, PUT, PATCH, DELETE requests).\n * Unlike `queryResource`, `mutationResource` is designed for one-off operations that change data.\n * It does *not* cache responses and does not provide a `value` signal. Instead, it focuses on\n * managing the mutation lifecycle (pending, error, success) and provides callbacks for handling\n * these states.\n *\n * @param request A function that returns the base `HttpResourceRequest` to be made. This function is called reactively. The parameter is the mutation value provided by the `mutate` method.\n * @param options Configuration options for the mutation resource. This includes callbacks\n * for `onMutate`, `onError`, `onSuccess`, and `onSettled`.\n * @typeParam TResult - The type of the expected result from the mutation.\n * @typeParam TRaw - The raw response type from the HTTP request (defaults to TResult).\n * @typeParam TMutation - The type of the mutation value (the request body).\n * @typeParam TICTX - The type of the initial context value passed to `onMutate`.\n * @typeParam TCTX - The type of the context value returned by `onMutate`.\n * @typeParam TMethod - The HTTP method to be used for the mutation (defaults to `HttpResourceRequest['method']`).\n * @returns A `MutationResourceRef` instance, which provides methods for triggering the mutation\n * and observing its status.\n */\nexport function mutationResource<\n TResult,\n TRaw = TResult,\n TMutation = TResult,\n TCTX = void,\n TICTX = TCTX,\n TMethod extends HttpResourceRequest['method'] = HttpResourceRequest['method'],\n>(\n request: (\n params: TMutation,\n ) => Omit<NextRequest<TMethod, TMutation>, 'body'> | undefined | void,\n options: MutationResourceOptions<TResult, TRaw, TMutation, TCTX, TICTX> = {},\n): MutationResourceRef<TResult, TMutation, TICTX> {\n const { onMutate, onError, onSuccess, onSettled, equal, ...rest } = options;\n\n const requestEqual = createEqualRequest(equal);\n\n const eq = equal ?? Object.is;\n const next = signal<TMutation | null>(null, {\n equal: (a, b) => {\n if (!a && !b) return true;\n if (!a || !b) return false;\n return eq(a, b);\n },\n });\n\n const queue = signal<[TMutation, TICTX | undefined][]>([]);\n\n let ctx: TCTX = undefined as TCTX;\n\n const queueRef = effect(() => {\n const nextInQueue = queue().at(0);\n if (!nextInQueue || next() !== null) return;\n queue.update((q) => q.slice(1));\n const [value, ictx] = nextInQueue;\n ctx = onMutate?.(value, ictx) as TCTX;\n next.set(value);\n });\n\n const req = computed(\n (): HttpResourceRequest | undefined => {\n const nr = next();\n if (!nr) return;\n\n return request(nr) ?? undefined;\n },\n {\n equal: requestEqual,\n },\n );\n\n const lastValue = linkedSignal<TMutation | null, TMutation | null>({\n source: next,\n computation: (next, prev) => {\n if (next === null && !!prev) return prev.value;\n return next;\n },\n });\n\n const lastValueRequest = computed(\n (): HttpResourceRequest | undefined => {\n const nr = lastValue();\n if (!nr) return;\n\n return request(nr) ?? undefined;\n },\n {\n equal: requestEqual,\n },\n );\n\n const cb = createCircuitBreaker(\n options?.circuitBreaker === true\n ? undefined\n : (options?.circuitBreaker ?? false),\n options?.injector,\n );\n\n const resource = queryResource<TResult, TRaw>(req, {\n ...rest,\n circuitBreaker: cb,\n defaultValue: null as unknown as TResult, // doesnt matter since .value is not accessible\n });\n\n const destroyRef = options.injector\n ? options.injector.get(DestroyRef)\n : inject(DestroyRef);\n\n const error$ = toObservable(resource.error);\n const value$ = toObservable(resource.value).pipe(catchError(() => of(null)));\n\n const statusSub = toObservable(resource.status)\n .pipe(\n combineLatestWith(error$, value$),\n map(([status, error, value]): StatusResult<TResult> | null => {\n if (status === 'error' && error) {\n return {\n status: 'error',\n error,\n };\n }\n\n if (status === 'resolved' && value !== null) {\n return {\n status: 'resolved',\n value,\n };\n }\n\n return null;\n }),\n filter((v) => v !== null),\n takeUntilDestroyed(destroyRef),\n )\n .subscribe((result) => {\n if (result.status === 'error') onError?.(result.error, ctx);\n else onSuccess?.(result.value, ctx);\n\n onSettled?.(ctx);\n ctx = undefined as TCTX;\n next.set(null);\n });\n\n const shouldQueue = options.queue ?? false;\n\n return {\n ...resource,\n destroy: () => {\n statusSub.unsubscribe();\n resource.destroy();\n queueRef.destroy();\n },\n mutate: (value, ictx) => {\n if (shouldQueue) {\n return queue.update((q) => [...q, [value, ictx]]);\n } else {\n ctx = onMutate?.(value, ictx) as TCTX;\n next.set(value);\n }\n },\n current: next,\n // redeclare disabled with last value so that it is not affected by the resource's internal disablement logic\n disabled: computed(() => cb.isOpen() || lastValueRequest() === undefined),\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { HttpResponse, HttpInterceptorFn, HttpContext, HttpResourceRef, HttpHeaders, HttpResourceRequest, HttpResourceOptions } from '@angular/common/http';
1
+ import { HttpResponse, HttpInterceptorFn, HttpRequest, HttpContext, HttpResourceRef, HttpHeaders, HttpResourceRequest, HttpResourceOptions } from '@angular/common/http';
2
2
  import { Signal, Injector, Provider, WritableSignal, ValueEqualityFn } from '@angular/core';
3
3
 
4
4
  type StoredEntry<T> = Omit<CacheEntry<T>, 'timeout'>;
@@ -437,6 +437,9 @@ declare function noDedupe(ctx?: HttpContext): HttpContext;
437
437
  *
438
438
  * @param allowed - An array of HTTP methods for which deduplication should be enabled.
439
439
  * Defaults to `['GET', 'DELETE', 'HEAD', 'OPTIONS']`.
440
+ * @param keyFn - Optional function to compute the dedupe key from a request.
441
+ * Defaults to `hashRequest`, which includes method, URL,
442
+ * response type, params, and body.
440
443
  *
441
444
  * @returns An `HttpInterceptorFn` that implements the request deduplication logic.
442
445
  *
@@ -460,7 +463,7 @@ declare function noDedupe(ctx?: HttpContext): HttpContext;
460
463
  * ],
461
464
  * };
462
465
  */
463
- declare function createDedupeRequestsInterceptor(allowed?: string[]): HttpInterceptorFn;
466
+ declare function createDedupeRequestsInterceptor(allowed?: string[], keyFn?: (req: HttpRequest<unknown>) => string): HttpInterceptorFn;
464
467
 
465
468
  type RetryOptions = number | {
466
469
  max?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmstack/resource",
3
- "version": "20.5.2",
3
+ "version": "20.6.0",
4
4
  "keywords": [
5
5
  "angular",
6
6
  "signals",