@mmstack/resource 21.4.0 → 22.1.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.
@@ -245,7 +245,8 @@ class Cache {
245
245
  }
246
246
  /** @internal */
247
247
  getInternal(key) {
248
- const keySignal = computed(() => key(), ...(ngDevMode ? [{ debugName: "keySignal" }] : /* istanbul ignore next */ []));
248
+ const keySignal = computed(() => key(), /* @ts-ignore */
249
+ ...(ngDevMode ? [{ debugName: "keySignal" }] : /* istanbul ignore next */ []));
249
250
  return computed(() => {
250
251
  const key = keySignal();
251
252
  if (!key)
@@ -942,16 +943,22 @@ const DEFAULT_OPTIONS = {
942
943
  };
943
944
  /** @internal */
944
945
  function internalCeateCircuitBreaker(threshold = 5, resetTimeout = 30000, shouldFail = () => true, shouldFailForever = () => false) {
945
- const halfOpen = signal(false, ...(ngDevMode ? [{ debugName: "halfOpen" }] : /* istanbul ignore next */ []));
946
- const failureCount = signal(0, ...(ngDevMode ? [{ debugName: "failureCount" }] : /* istanbul ignore next */ []));
947
- const failedForever = signal(false, ...(ngDevMode ? [{ debugName: "failedForever" }] : /* istanbul ignore next */ []));
946
+ const halfOpen = signal(false, /* @ts-ignore */
947
+ ...(ngDevMode ? [{ debugName: "halfOpen" }] : /* istanbul ignore next */ []));
948
+ const failureCount = signal(0, /* @ts-ignore */
949
+ ...(ngDevMode ? [{ debugName: "failureCount" }] : /* istanbul ignore next */ []));
950
+ const failedForever = signal(false, /* @ts-ignore */
951
+ ...(ngDevMode ? [{ debugName: "failedForever" }] : /* istanbul ignore next */ []));
948
952
  const status = computed(() => {
949
953
  if (failedForever() || failureCount() >= threshold)
950
954
  return 'OPEN';
951
955
  return halfOpen() ? 'HALF_OPEN' : 'CLOSED';
952
- }, ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
953
- const isClosed = computed(() => status() !== 'OPEN', ...(ngDevMode ? [{ debugName: "isClosed" }] : /* istanbul ignore next */ []));
954
- const isOpen = computed(() => status() !== 'CLOSED', ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
956
+ }, /* @ts-ignore */
957
+ ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
958
+ const isClosed = computed(() => status() !== 'OPEN', /* @ts-ignore */
959
+ ...(ngDevMode ? [{ debugName: "isClosed" }] : /* istanbul ignore next */ []));
960
+ const isOpen = computed(() => status() !== 'CLOSED', /* @ts-ignore */
961
+ ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
955
962
  const success = () => {
956
963
  failureCount.set(0);
957
964
  halfOpen.set(false);
@@ -972,7 +979,8 @@ function internalCeateCircuitBreaker(threshold = 5, resetTimeout = 30000, should
972
979
  return cleanup(() => {
973
980
  clearTimeout(timeout);
974
981
  });
975
- }, ...(ngDevMode ? [{ debugName: "effectRef" }] : /* istanbul ignore next */ []));
982
+ }, /* @ts-ignore */
983
+ ...(ngDevMode ? [{ debugName: "effectRef" }] : /* istanbul ignore next */ []));
976
984
  const failInternal = () => {
977
985
  failureCount.set(failureCount() + 1);
978
986
  halfOpen.set(false);
@@ -1422,7 +1430,8 @@ function retryOnError(res, opt, onError) {
1422
1430
  case 'resolved':
1423
1431
  return onSuccess();
1424
1432
  }
1425
- }, ...(ngDevMode ? [{ debugName: "ref" }] : /* istanbul ignore next */ []));
1433
+ }, /* @ts-ignore */
1434
+ ...(ngDevMode ? [{ debugName: "ref" }] : /* istanbul ignore next */ []));
1426
1435
  return {
1427
1436
  ...res,
1428
1437
  destroy: () => {
@@ -1434,10 +1443,10 @@ function retryOnError(res, opt, onError) {
1434
1443
 
1435
1444
  class ResourceSensors {
1436
1445
  networkStatus = sensor('networkStatus');
1437
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ResourceSensors, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1438
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ResourceSensors, providedIn: 'root' });
1446
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ResourceSensors, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1447
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ResourceSensors, providedIn: 'root' });
1439
1448
  }
1440
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ResourceSensors, decorators: [{
1449
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ResourceSensors, decorators: [{
1441
1450
  type: Injectable,
1442
1451
  args: [{
1443
1452
  providedIn: 'root',
@@ -1544,12 +1553,15 @@ function queryResource(request, options0) {
1544
1553
  ? undefined
1545
1554
  : (options?.equalRequest ?? createEqualRequest());
1546
1555
  const requestCtx = { paused: PAUSED };
1547
- const rawResult = computed(() => request(requestCtx), ...(ngDevMode ? [{ debugName: "rawResult" }] : /* istanbul ignore next */ []));
1548
- const paused = computed(() => rawResult() === PAUSED, ...(ngDevMode ? [{ debugName: "paused" }] : /* istanbul ignore next */ []));
1556
+ const rawResult = computed(() => request(requestCtx), /* @ts-ignore */
1557
+ ...(ngDevMode ? [{ debugName: "rawResult" }] : /* istanbul ignore next */ []));
1558
+ const paused = computed(() => rawResult() === PAUSED, /* @ts-ignore */
1559
+ ...(ngDevMode ? [{ debugName: "paused" }] : /* istanbul ignore next */ []));
1549
1560
  const rawRequest = computed(() => {
1550
1561
  const r = rawResult();
1551
1562
  return r === PAUSED ? undefined : (r ?? undefined);
1552
- }, ...(ngDevMode ? [{ debugName: "rawRequest" }] : /* istanbul ignore next */ []));
1563
+ }, /* @ts-ignore */
1564
+ ...(ngDevMode ? [{ debugName: "rawRequest" }] : /* istanbul ignore next */ []));
1553
1565
  const disabledReason = computed(() => {
1554
1566
  if (!networkAvailable())
1555
1567
  return 'offline';
@@ -1560,7 +1572,8 @@ function queryResource(request, options0) {
1560
1572
  if (!rawRequest())
1561
1573
  return 'no-request';
1562
1574
  return null;
1563
- }, ...(ngDevMode ? [{ debugName: "disabledReason" }] : /* istanbul ignore next */ []));
1575
+ }, /* @ts-ignore */
1576
+ ...(ngDevMode ? [{ debugName: "disabledReason" }] : /* istanbul ignore next */ []));
1564
1577
  // While PAUSED, hold the previous request so httpResource sees no change — it keeps its value and
1565
1578
  // does NOT refetch. On resume the request is re-evaluated, so it refetches only if it changed.
1566
1579
  const heldRequest = linkedSignal({ ...(ngDevMode ? { debugName: "heldRequest" } : /* istanbul ignore next */ {}), source: () => {
@@ -1597,7 +1610,8 @@ function queryResource(request, options0) {
1597
1610
  if (!r)
1598
1611
  return null;
1599
1612
  return hashFn(r);
1600
- }, ...(ngDevMode ? [{ debugName: "cacheKey" }] : /* istanbul ignore next */ []));
1613
+ }, /* @ts-ignore */
1614
+ ...(ngDevMode ? [{ debugName: "cacheKey" }] : /* istanbul ignore next */ []));
1601
1615
  const bustBrowserCache = typeof options?.cache === 'object' &&
1602
1616
  options.cache.bustBrowserCache === true;
1603
1617
  const ignoreCacheControl = typeof options?.cache === 'object' &&
@@ -1674,7 +1688,8 @@ function queryResource(request, options0) {
1674
1688
  cb.fail(untracked(resource.error));
1675
1689
  else if (status === 'resolved')
1676
1690
  cb.success();
1677
- }, ...(ngDevMode ? [{ debugName: "cbEffectRef" }] : /* istanbul ignore next */ []));
1691
+ }, /* @ts-ignore */
1692
+ ...(ngDevMode ? [{ debugName: "cbEffectRef" }] : /* istanbul ignore next */ []));
1678
1693
  const client = options?.injector
1679
1694
  ? options.injector.get(HttpClient)
1680
1695
  : inject(HttpClient);
@@ -1877,7 +1892,8 @@ function mutationResource(request, options0 = {}) {
1877
1892
  return false;
1878
1893
  return eq(a, b);
1879
1894
  } });
1880
- const queue = signal([], ...(ngDevMode ? [{ debugName: "queue" }] : /* istanbul ignore next */ []));
1895
+ const queue = signal([], /* @ts-ignore */
1896
+ ...(ngDevMode ? [{ debugName: "queue" }] : /* istanbul ignore next */ []));
1881
1897
  let ctx = undefined;
1882
1898
  const queueRef = effect(() => {
1883
1899
  const nextInQueue = queue().at(0);
@@ -1895,7 +1911,8 @@ function mutationResource(request, options0 = {}) {
1895
1911
  if (isDevMode())
1896
1912
  console.error('[@mmstack/resource]: error thrown in onMutate hook, mutation was not applied', mutationErr);
1897
1913
  }
1898
- }, ...(ngDevMode ? [{ debugName: "queueRef" }] : /* istanbul ignore next */ []));
1914
+ }, /* @ts-ignore */
1915
+ ...(ngDevMode ? [{ debugName: "queueRef" }] : /* istanbul ignore next */ []));
1899
1916
  const req = computed(() => {
1900
1917
  const nr = next();
1901
1918
  if (nr === NULL_VALUE)
@@ -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/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/options.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 { type 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 type Injector,\n isDevMode,\n type Provider,\n type Signal,\n untracked,\n} from '@angular/core';\nimport { mutable } from '@mmstack/primitives';\nimport { type 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 // eslint-disable-next-line @typescript-eslint/no-unused-vars\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 { HttpParams, type HttpRequest, type HttpResourceRequest } 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(params: NonNullable<HashableRequest['params']>): string {\n const p = params instanceof HttpParams ? params : 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) ?? []).map((v) => `${encodedKey}=${encodeURIComponent(v)}`).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: [string, string][] = [];\n body.forEach((value, key) => {\n entries.push([key, hashBody(value)]);\n });\n entries.sort(([ak, av], [bk, bv]) => ak.localeCompare(bk) || av.localeCompare(bv));\n return `FormData:${entries.map(([k, v]) => `${k}=${v}`).join('&')}`;\n }\n\n if (typeof URLSearchParams !== 'undefined' && body instanceof URLSearchParams) {\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 { type 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 type Provider,\n type 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 type 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: (string | number | boolean)[],\n b: (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<Required<HttpResourceRequest['headers']>, HttpHeaders | undefined> = {};\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<Required<HttpResourceRequest['params']>, HttpParams | undefined> = {};\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(a: HttpResourceRequest['params'], b: HttpResourceRequest['params']): 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(a: HttpResourceRequest['body'], b: HttpResourceRequest['body']): 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 [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>(equalResult?: ValueEqualityFn<TResult>) {\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 { type ValueEqualityFn } from '@angular/core';\nimport { keepPrevious } from '@mmstack/primitives';\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: keepPrevious<number | undefined>(resource.statusCode),\n headers: keepPrevious<HttpHeaders | undefined>(resource.headers),\n value: keepPrevious<T>(resource.value, { equal }),\n };\n}\n","import { type HttpResourceRef } from '@angular/common/http';\nimport { type 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 inactive?: () => boolean,\n): HttpResourceRef<T> {\n if (!refresh) return resource; // no refresh requested\n\n const tick = () => {\n if (inactive?.()) return; // disabled / paused → skip the poll\n resource.reload();\n };\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(tick);\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(tick);\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 timeout = 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 { type HttpResourceRef } from '@angular/common/http';\n\nexport function toResourceObject<T>(\n res: HttpResourceRef<T>,\n): HttpResourceRef<T> {\n return {\n snapshot: res.snapshot,\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 DestroyRef,\n inject,\n InjectionToken,\n type Injector,\n type Provider,\n type ResourceRef,\n runInInjectionContext,\n} from '@angular/core';\nimport {\n injectTransitionScope,\n type RegisterOptions,\n} from '@mmstack/primitives';\nimport { type CircuitBreakerOptions, type RetryOptions } from './util';\n\n/**\n * Auto-registration into the nearest transition scope, as a resource OPTION:\n * - `true` — register for the pending indicator + hold-stale (does NOT block first paint);\n * - `{ suspends: true }` — register as *suspending* (the boundary holds its placeholder until\n * this resource has a value), i.e. full Suspense;\n * - `{ suspends: false }` — same as `true`;\n * - `false` / omitted — don't register.\n *\n * Defaultable via `provideResourceOptions` / `provideQueryResourceOptions` and overridable\n * (including opting out with `false`) per call — so a dev can make \"all queries participate in\n * transitions\" the default and turn it off for the odd one.\n */\nexport type TransitionRegistration = boolean | RegisterOptions;\n\n/** Options common to every resource kind (the base layer for the options-injection system). */\nexport type CommonResourceOptions = {\n /** Auto-registration into the nearest transition scope. */\n readonly register?: TransitionRegistration;\n /** Retry failed requests. */\n readonly retry?: RetryOptions;\n /** Configure a circuit breaker for the resource. */\n readonly circuitBreaker?: CircuitBreakerOptions | true;\n /** Trigger a request even when the request parameters are unchanged. @default false */\n readonly triggerOnSameRequest?: boolean;\n};\n\nconst RESOURCE_OPTIONS = new InjectionToken<CommonResourceOptions>(\n '@mmstack/resource:resource-options',\n { factory: () => ({}) },\n);\n\nfunction asProvider<T>(\n token: InjectionToken<T>,\n valueOrFn: T | (() => T),\n): Provider {\n return typeof valueOrFn === 'function'\n ? { provide: token, useFactory: valueOrFn as () => T }\n : { provide: token, useValue: valueOrFn };\n}\n\n/** Layer 1: defaults that apply to ALL resource kinds. Type-specific providers inherit + override these. */\nexport function provideResourceOptions(\n valueOrFn: CommonResourceOptions | (() => CommonResourceOptions),\n): Provider {\n return asProvider(RESOURCE_OPTIONS, valueOrFn);\n}\n\nexport function injectResourceOptions(\n injector?: Injector,\n): CommonResourceOptions {\n return injector ? injector.get(RESOURCE_OPTIONS) : inject(RESOURCE_OPTIONS);\n}\n\n/** Shared helper for the type-specific providers (query/mutation), so precedence is identical. */\nexport function provideTypedResourceOptions<T>(\n token: InjectionToken<T>,\n valueOrFn: T | (() => T),\n): Provider {\n return asProvider(token, valueOrFn);\n}\n\n/**\n * Applies a resolved `register` option to a freshly-created resource — adds it to the nearest\n * transition scope and removes it on destroy. Runs in the resource's injection context (or the\n * provided `injector`), since registration needs `TRANSITION_SCOPE` + `DestroyRef`.\n */\nexport function applyResourceRegistration(\n ref: ResourceRef<unknown>,\n register: TransitionRegistration | undefined,\n injector?: Injector,\n): void {\n if (!register) return;\n const opt: RegisterOptions =\n register === true ? { suspends: false } : register;\n const run = injector\n ? (fn: () => void) => runInInjectionContext(injector, fn)\n : (fn: () => void) => fn();\n run(() => {\n const scope = injectTransitionScope();\n const destroyRef = inject(DestroyRef);\n scope.add(ref, opt);\n destroyRef.onDestroy(() => scope.remove(ref));\n });\n}\n","import {\n HttpClient,\n type HttpHeaders,\n httpResource,\n type HttpResourceOptions,\n type HttpResourceRef,\n type HttpResourceRequest,\n HttpResponse,\n} from '@angular/common/http';\nimport {\n computed,\n DestroyRef,\n effect,\n inject,\n InjectionToken,\n type Injector,\n isDevMode,\n linkedSignal,\n type Provider,\n type ResourceRef,\n type Signal,\n untracked,\n type WritableSignal,\n} from '@angular/core';\nimport { toWritable } from '@mmstack/primitives';\nimport { firstValueFrom } from 'rxjs';\nimport {\n applyResourceRegistration,\n type CommonResourceOptions,\n injectResourceOptions,\n provideTypedResourceOptions,\n} from './options';\nimport {\n catchValueError,\n createCircuitBreaker,\n createEqualRequest,\n hashRequest,\n hasSlowConnection,\n injectNetworkStatus,\n injectQueryCache,\n persistResourceValues,\n refresh,\n retryOnError,\n setCacheContext,\n toResourceObject,\n} from './util';\nimport { type 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`. Extends Angular's\n * `HttpResourceOptions` with caching, retries, refresh intervals, circuit\n * breakers, and lifecycle callbacks. See the linked properties below for the\n * full list.\n *\n * @example\n * ```ts\n * const options: QueryResourceOptions<User> = {\n * defaultValue: { id: 0, name: 'Anonymous' },\n * cache: { ttl: 60_000, staleTime: 10_000 },\n * refresh: 30_000,\n * retry: { max: 3 },\n * circuitBreaker: true,\n * onError: (err, retry, isFinal) => isFinal && toast.error(err),\n * };\n * ```\n */\nexport type QueryResourceOptions<TResult, TRaw = TResult> = HttpResourceOptions<\n TResult,\n TRaw\n> &\n CommonResourceOptions & {\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 * 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 enabling and configuring caching for the resource.\n */\n cache?: ResourceCacheOptions;\n /**\n * Comparison of request object\n */\n equalRequest?: (a: HttpResourceRequest, b: HttpResourceRequest) => boolean;\n };\n\nconst QUERY_RESOURCE_OPTIONS = new InjectionToken<\n Partial<QueryResourceOptions<any, any>>\n>('@mmstack/resource:query-resource-options', { factory: () => ({}) });\n\n/**\n * Layer 2 (query): default options for every `queryResource`, inheriting + overriding the\n * common defaults from `provideResourceOptions`. Per-call options override these in turn.\n */\nexport function provideQueryResourceOptions(\n valueOrFn:\n | Partial<QueryResourceOptions<any, any>>\n | (() => Partial<QueryResourceOptions<any, any>>),\n): Provider {\n return provideTypedResourceOptions(QUERY_RESOURCE_OPTIONS, valueOrFn);\n}\n\nfunction injectQueryResourceOptions(\n injector?: Injector,\n): Partial<QueryResourceOptions<any, any>> {\n return injector\n ? injector.get(QUERY_RESOURCE_OPTIONS)\n : inject(QUERY_RESOURCE_OPTIONS);\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 *\n * @example\n * ```ts\n * effect(() => {\n * switch (user.disabledReason()) {\n * case 'offline': return toast.warn('You are offline');\n * case 'circuit-open': return toast.warn('Service temporarily unavailable');\n * case 'no-request': return; // expected — request signal returned undefined\n * case null: return; // resource is enabled\n * }\n * });\n * ```\n */\nexport type DisabledReason = 'offline' | 'circuit-open' | 'no-request';\n\n/**\n * Returned from a resource's request fn to PAUSE it: the resource holds its current value and last\n * request (so it does not refetch on resume), and stops background work (no polling, no refetch\n * while paused). Distinct from returning `undefined` (DISABLE), which drops the request — a\n * disabled resource may refetch when re-enabled, a paused one resumes exactly where it left off.\n *\n * The request fn receives a {@link RequestContext} and can just return `ctx.paused`.\n */\nexport const PAUSED: unique symbol = Symbol('@mmstack/resource:paused');\n\n/**\n * Context passed to a resource's request fn. An object (not positional args) so it can grow\n * without changing the call signature. Today it carries {@link PAUSED} so the fn can return it.\n */\nexport type RequestContext = { readonly paused: typeof PAUSED };\n\n/** The request fn shape: build a request, or return `undefined` (disable) / `ctx.paused` (pause). */\nexport type ResourceRequestFn = (\n ctx: RequestContext,\n) => HttpResourceRequest | string | undefined | void | typeof PAUSED;\n\n/**\n * Represents a resource created by `queryResource`. Extends `HttpResourceRef`\n * with `disabled` / `disabledReason` signals, writable `headers` / `statusCode`\n * (so optimistic updates can patch them), and `prefetch()` for proactive cache\n * warm-up.\n *\n * @example\n * ```ts\n * const user = queryResource<User>(() => `/api/users/${userId()}`);\n *\n * effect(() => {\n * if (user.status() === 'resolved') console.log(user.value());\n * });\n *\n * // Warm the cache before navigating\n * onMouseEnter(() => user.prefetch());\n * ```\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 *\n * @example\n * ```ts\n * const userId = signal(1);\n *\n * const user = queryResource<User>(\n * () => `/api/users/${userId()}`,\n * { defaultValue: { id: 0, name: 'Anonymous' } },\n * );\n *\n * user.value(); // always User — never undefined, even before the first fetch resolves\n * ```\n */\nexport function queryResource<TResult, TRaw = TResult>(\n request: ResourceRequestFn,\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 *\n * @example\n * ```ts\n * const userId = signal<number | undefined>(undefined);\n *\n * const user = queryResource<User>(\n * () => userId() ? `/api/users/${userId()}` : undefined,\n * {\n * cache: { ttl: 60_000, staleTime: 10_000 },\n * refresh: 30_000,\n * retry: { max: 3 },\n * },\n * );\n *\n * user.value(); // User | undefined\n * user.status(); // 'idle' | 'loading' | 'resolved' | 'error'\n * user.disabledReason(); // null while enabled; 'offline' / 'circuit-open' / 'no-request' otherwise\n * ```\n */\nexport function queryResource<TResult, TRaw = TResult>(\n request: ResourceRequestFn,\n options?: QueryResourceOptions<TResult, TRaw>,\n): QueryResourceRef<TResult | undefined>;\n\nexport function queryResource<TResult, TRaw = TResult>(\n request: ResourceRequestFn,\n options0?: QueryResourceOptions<TResult, TRaw>,\n): QueryResourceRef<TResult | undefined> {\n // Two-layer option injection: per-call > provideQueryResourceOptions > provideResourceOptions.\n const options = {\n ...injectResourceOptions(options0?.injector),\n ...injectQueryResourceOptions(options0?.injector),\n ...options0,\n } as QueryResourceOptions<TResult, TRaw>;\n\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 : (options?.equalRequest ?? createEqualRequest());\n\n const requestCtx: RequestContext = { paused: PAUSED };\n const rawResult = computed(() => request(requestCtx));\n const paused = computed(() => rawResult() === PAUSED);\n const rawRequest = computed(() => {\n const r = rawResult();\n return r === PAUSED ? undefined : (r ?? undefined);\n });\n\n const disabledReason = computed<DisabledReason | null>(() => {\n if (!networkAvailable()) return 'offline';\n if (cb.isOpen()) return 'circuit-open';\n // PAUSED makes rawRequest undefined, so it reports 'no-request' here (and skips polling),\n // while stableRequest below HOLDS the last request so the value is kept (no refetch on resume).\n if (!rawRequest()) return 'no-request';\n return null;\n });\n\n // While PAUSED, hold the previous request so httpResource sees no change — it keeps its value and\n // does NOT refetch. On resume the request is re-evaluated, so it refetches only if it changed.\n const heldRequest = linkedSignal<\n { req: HttpResourceRequest | undefined; held: boolean },\n HttpResourceRequest | undefined\n >({\n source: () => {\n if (paused()) return { req: undefined, held: true };\n if (disabledReason() !== null) return { req: undefined, held: false };\n const req = rawRequest();\n if (!req) return { req: undefined, held: false };\n if (typeof req === 'string')\n return { req: { method: 'GET', url: req }, held: false };\n return { req, held: false };\n },\n computation: (curr, prev) =>\n curr.held && prev !== undefined ? prev.value : curr.req,\n });\n\n // Dedup via the request-equality (the linkedSignal re-runs on every source tick; this computed\n // is what actually gates httpResource — so an equal/held request never triggers a refetch).\n const stableRequest = computed(\n (): HttpResourceRequest | undefined => heldRequest(),\n {\n equal: (a, b) => {\n if (a === b) return true;\n if (a === undefined || b === undefined) return false;\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 // A disabled (offline / circuit-open / no-request) or PAUSED resource must not poll.\n resource = refresh(\n resource,\n destroyRef,\n options?.refresh,\n () => disabledReason() !== null,\n );\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 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 value = options?.cache\n ? toWritable(\n computed((): TResult => cacheEntry()?.value ?? resource.value()),\n set,\n 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') cb.fail(untracked(resource.error));\n else if (status === 'resolved') cb.success();\n });\n\n const client = options?.injector\n ? options.injector.get(HttpClient)\n : inject(HttpClient);\n\n const ref: QueryResourceRef<TResult | undefined> = {\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 referrerPolicy: prefetchRequest.referrerPolicy as\n | ReferrerPolicy\n | undefined,\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 // Auto-register into the nearest transition scope if the (merged) options ask for it.\n applyResourceRegistration(\n ref as ResourceRef<unknown>,\n options.register,\n options?.injector,\n );\n\n return ref;\n}\n","import { type HttpResourceRequest } from '@angular/common/http';\nimport { computed, inject, Injector, signal, untracked } from '@angular/core';\nimport { nestedEffect } from '@mmstack/primitives';\nimport {\n queryResource,\n type QueryResourceOptions,\n type QueryResourceRef,\n} from './query-resource';\n\n/**\n * A reference to a manually triggered query resource. Extends\n * {@link QueryResourceRef} with a `trigger()` method that runs the request\n * imperatively and returns a `Promise<TResult>`. Useful when a request should\n * only happen on user action (search submit, button click) rather than on\n * every reactive change of the request inputs.\n *\n * @example\n * ```ts\n * const search = manualQueryResource<SearchResults>(() => ({\n * url: '/api/search',\n * params: { q: query() },\n * }));\n *\n * async function onSubmit() {\n * try {\n * const results = await search.trigger();\n * showResults(results);\n * } catch (err) {\n * toast.error('Search failed');\n * }\n * }\n * ```\n *\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 *\n * @example\n * ```ts\n * const search = manualQueryResource<SearchResults>(\n * () => ({ url: '/api/search', params: { q: query() } }),\n * { defaultValue: { hits: [], total: 0 } },\n * );\n *\n * // search.value() is always SearchResults (never undefined) thanks to defaultValue.\n * const results = await search.trigger();\n * ```\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 *\n * @example\n * ```ts\n * const exportReport = manualQueryResource<Report>(() => ({\n * url: '/api/reports/export',\n * params: { range: range() },\n * }));\n *\n * async function onExportClick() {\n * try {\n * const report = await exportReport.trigger();\n * download(report);\n * } catch (err) {\n * toast.error('Export failed');\n * }\n * }\n * ```\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 InjectionToken,\n type Injector,\n isDevMode,\n linkedSignal,\n type Provider,\n type ResourceRef,\n type Signal,\n signal,\n type ValueEqualityFn,\n} from '@angular/core';\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\nimport { catchError, combineLatestWith, filter, map, of } from 'rxjs';\nimport {\n applyResourceRegistration,\n injectResourceOptions,\n provideTypedResourceOptions,\n} from './options';\nimport {\n queryResource,\n type QueryResourceOptions,\n type QueryResourceRef,\n} from './query-resource';\nimport { createCircuitBreaker, createEqualRequest } from './util';\n\nconst NULL_VALUE = Symbol('@mmstack/resource:null');\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`. Inherits from\n * `QueryResourceOptions` (minus options that don't apply to mutations:\n * `equal`, `keepPrevious`, `refresh`, `cache`) and adds lifecycle callbacks\n * (`onMutate`, `onError`, `onSuccess`, `onSettled`) for managing optimistic\n * updates, rollback, and side effects.\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 *\n * @example\n * ```ts\n * const options: MutationResourceOptions<User, User, Partial<User>, { previous: User | null }> = {\n * onMutate: (patch) => {\n * const previous = current();\n * current.update((u) => (u ? { ...u, ...patch } : u)); // optimistic\n * return { previous };\n * },\n * onError: (_err, { previous }) => current.set(previous), // rollback\n * onSuccess: (saved) => toast.success(`Updated ${saved.name}`),\n * queue: true, // serialize requests when offline / circuit open\n * };\n * ```\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\nconst MUTATION_RESOURCE_OPTIONS = new InjectionToken<\n Partial<MutationResourceOptions<any, any, any, any, any, any>>\n>('@mmstack/resource:mutation-resource-options', { factory: () => ({}) });\n\n/**\n * Layer 2 (mutation): default options for every `mutationResource`, inheriting + overriding the\n * common defaults from `provideResourceOptions`. Per-call options override these in turn.\n */\nexport function provideMutationResourceOptions(\n valueOrFn:\n | Partial<MutationResourceOptions<any, any, any, any, any, any>>\n | (() => Partial<MutationResourceOptions<any, any, any, any, any, any>>),\n): Provider {\n return provideTypedResourceOptions(MUTATION_RESOURCE_OPTIONS, valueOrFn);\n}\n\nfunction injectMutationResourceOptions(\n injector?: Injector,\n): Partial<MutationResourceOptions<any, any, any, any, any, any>> {\n return injector\n ? injector.get(MUTATION_RESOURCE_OPTIONS)\n : inject(MUTATION_RESOURCE_OPTIONS);\n}\n\n/**\n * Represents a mutation resource created by `mutationResource`. Extends\n * `QueryResourceRef` but strips methods that don't make sense for one-off\n * writes (`prefetch`, `value`, `hasValue`, `set`, `update`) and adds `mutate()`\n * for triggering a mutation plus `current()` for tracking the in-flight value.\n *\n * @typeParam TResult - The type of the expected result from the mutation.\n *\n * @example\n * ```ts\n * const updateUser = mutationResource<User, User, Partial<User>>(...);\n *\n * effect(() => console.log('mutating:', updateUser.current()));\n * effect(() => {\n * if (updateUser.status() === 'error') toast.error(updateUser.error());\n * });\n *\n * updateUser.mutate({ name: 'Alice' });\n * ```\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 *\n * @example\n * ```ts\n * // Basic PATCH mutation\n * const updateUser = mutationResource<User, User, Partial<User>>(\n * (body) => ({ url: `/api/users/${userId()}`, method: 'PATCH', body }),\n * {\n * onSuccess: (saved) => toast.success(`Updated ${saved.name}`),\n * onError: (err) => toast.error(err),\n * },\n * );\n *\n * updateUser.mutate({ name: 'Alice' });\n * ```\n *\n * @example\n * ```ts\n * // Optimistic update with rollback via the `ctx` returned from `onMutate`\n * const updateUser = mutationResource<User, User, Partial<User>, { prev: User | null }>(\n * (body) => ({ url: `/api/users/${userId()}`, method: 'PATCH', body }),\n * {\n * onMutate: (patch) => {\n * const prev = current();\n * current.update((u) => (u ? { ...u, ...patch } : u));\n * return { prev };\n * },\n * onError: (_err, { prev }) => current.set(prev),\n * },\n * );\n * ```\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 options0: MutationResourceOptions<TResult, TRaw, TMutation, TCTX, TICTX> = {},\n): MutationResourceRef<TResult, TMutation, TICTX> {\n // Two-layer option injection: per-call > provideMutationResourceOptions > provideResourceOptions.\n const options = {\n ...injectResourceOptions(options0.injector),\n ...injectMutationResourceOptions(options0.injector),\n ...options0,\n } as MutationResourceOptions<TResult, TRaw, TMutation, TCTX, TICTX>;\n\n // `register` is pulled out (and forced off on the inner query below) so the mutation ref is\n // the only thing registered into the transition scope, not its internal query resource.\n const {\n onMutate,\n onError,\n onSuccess,\n onSettled,\n equal,\n register,\n equalRequest,\n ...rest\n } = options;\n\n const requestEqual = equalRequest ?? createEqualRequest(equal);\n\n // A mutation is an imperative command, so `triggerOnSameRequest` means \"fire on EVERY mutate(),\n // even with an identical body\". By default we dedup an identical value/request while one is in\n // flight (double-click protection); when this is set, both the `next` and `req` dedup are bypassed\n // so a repeat click isn't silently swallowed mid-flight. (Otherwise it'd be dropped until `next`\n // resets to NULL on settle — the \"every other click\" symptom.)\n const triggerOnSame = options.triggerOnSameRequest ?? false;\n\n const eq = equal ?? Object.is;\n const next = signal<TMutation | typeof NULL_VALUE>(NULL_VALUE, {\n equal: (a, b) => {\n if (a === NULL_VALUE && b === NULL_VALUE) return true;\n if (a === NULL_VALUE || b === NULL_VALUE) return false;\n if (triggerOnSame) 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 === undefined || next() !== NULL_VALUE) return;\n queue.update((q) => q.slice(1));\n const [value, ictx] = nextInQueue;\n try {\n ctx = onMutate?.(value, ictx) as TCTX;\n next.set(value);\n } catch (mutationErr) {\n ctx = undefined as TCTX;\n next.set(NULL_VALUE);\n if (isDevMode())\n console.error(\n '[@mmstack/resource]: error thrown in onMutate hook, mutation was not applied',\n mutationErr,\n );\n }\n });\n\n const req = computed(\n (): HttpResourceRequest | undefined => {\n const nr = next();\n if (nr === NULL_VALUE) return;\n\n return request(nr) ?? undefined;\n },\n {\n equal: (a, b) => {\n if (a === undefined && b === undefined) return true;\n if (a === undefined || b === undefined) return false;\n if (triggerOnSame) return false;\n return requestEqual(a, b);\n },\n },\n );\n\n const lastValue = linkedSignal<\n TMutation | typeof NULL_VALUE,\n TMutation | typeof NULL_VALUE\n >({\n source: next,\n computation: (next, prev) => {\n if (next === NULL_VALUE && !!prev) return prev.value;\n return next;\n },\n });\n\n const lastValueRequest = computed(\n (): HttpResourceRequest | undefined => {\n const nr = lastValue();\n if (nr === NULL_VALUE) return;\n\n return request(nr) ?? undefined;\n },\n {\n equal: (a, b) => {\n if (a === b) return true;\n if (a === undefined || b === undefined) return false;\n return requestEqual(a, b);\n },\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 register: false, // the mutation ref handles registration; never register the inner query\n circuitBreaker: cb,\n equalRequest: requestEqual,\n defaultValue: NULL_VALUE 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(\n catchError(() => of(NULL_VALUE)),\n );\n\n const statusSub = toObservable(resource.status)\n .pipe(\n combineLatestWith(error$, value$),\n map(\n ([status, error, value]): StatusResult<TResult> | typeof NULL_VALUE => {\n if (status === 'error' && error) {\n return {\n status: 'error',\n error,\n };\n }\n\n if (status === 'resolved' && value !== NULL_VALUE) {\n return {\n status: 'resolved',\n value,\n };\n }\n\n return NULL_VALUE;\n },\n ),\n filter((v) => v !== NULL_VALUE),\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_VALUE);\n });\n\n const shouldQueue = options.queue ?? false;\n\n const ref: MutationResourceRef<TResult, TMutation, TICTX> = {\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 try {\n ctx = onMutate?.(value, ictx) as TCTX;\n next.set(value);\n } catch (mutationErr) {\n ctx = undefined as TCTX;\n next.set(NULL_VALUE);\n if (isDevMode())\n console.error(\n '[@mmstack/resource]: error thrown in onMutate hook, mutation was not applied',\n mutationErr,\n );\n }\n }\n },\n current: computed(() => {\n const nv = next();\n return nv === NULL_VALUE ? null : nv;\n }),\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 applyResourceRegistration(\n ref as unknown as ResourceRef<unknown>,\n register,\n options0.injector,\n );\n\n return ref;\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/options.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 { type 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 type Injector,\n isDevMode,\n type Provider,\n type Signal,\n untracked,\n} from '@angular/core';\nimport { mutable } from '@mmstack/primitives';\nimport { type 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 // eslint-disable-next-line @typescript-eslint/no-unused-vars\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 { HttpParams, type HttpRequest, type HttpResourceRequest } 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(params: NonNullable<HashableRequest['params']>): string {\n const p = params instanceof HttpParams ? params : 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) ?? []).map((v) => `${encodedKey}=${encodeURIComponent(v)}`).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: [string, string][] = [];\n body.forEach((value, key) => {\n entries.push([key, hashBody(value)]);\n });\n entries.sort(([ak, av], [bk, bv]) => ak.localeCompare(bk) || av.localeCompare(bv));\n return `FormData:${entries.map(([k, v]) => `${k}=${v}`).join('&')}`;\n }\n\n if (typeof URLSearchParams !== 'undefined' && body instanceof URLSearchParams) {\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 { type 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 type Provider,\n type 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 type 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: (string | number | boolean)[],\n b: (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<Required<HttpResourceRequest['headers']>, HttpHeaders | undefined> = {};\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<Required<HttpResourceRequest['params']>, HttpParams | undefined> = {};\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(a: HttpResourceRequest['params'], b: HttpResourceRequest['params']): 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(a: HttpResourceRequest['body'], b: HttpResourceRequest['body']): 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 [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>(equalResult?: ValueEqualityFn<TResult>) {\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 { type ValueEqualityFn } from '@angular/core';\nimport { keepPrevious } from '@mmstack/primitives';\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: keepPrevious<number | undefined>(resource.statusCode),\n headers: keepPrevious<HttpHeaders | undefined>(resource.headers),\n value: keepPrevious<T>(resource.value, { equal }),\n };\n}\n","import { type HttpResourceRef } from '@angular/common/http';\nimport { type 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 inactive?: () => boolean,\n): HttpResourceRef<T> {\n if (!refresh) return resource; // no refresh requested\n\n const tick = () => {\n if (inactive?.()) return; // disabled / paused → skip the poll\n resource.reload();\n };\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(tick);\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(tick);\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 timeout = 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 { type HttpResourceRef } from '@angular/common/http';\n\nexport function toResourceObject<T>(\n res: HttpResourceRef<T>,\n): HttpResourceRef<T> {\n return {\n snapshot: res.snapshot,\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 DestroyRef,\n inject,\n InjectionToken,\n type Injector,\n type Provider,\n type ResourceRef,\n runInInjectionContext,\n} from '@angular/core';\nimport {\n injectTransitionScope,\n type RegisterOptions,\n} from '@mmstack/primitives';\nimport { type CircuitBreakerOptions, type RetryOptions } from './util';\n\n/**\n * Auto-registration into the nearest transition scope, as a resource OPTION:\n * - `true` — register for the pending indicator + hold-stale (does NOT block first paint);\n * - `{ suspends: true }` — register as *suspending* (the boundary holds its placeholder until\n * this resource has a value), i.e. full Suspense;\n * - `{ suspends: false }` — same as `true`;\n * - `false` / omitted — don't register.\n *\n * Defaultable via `provideResourceOptions` / `provideQueryResourceOptions` and overridable\n * (including opting out with `false`) per call — so a dev can make \"all queries participate in\n * transitions\" the default and turn it off for the odd one.\n */\nexport type TransitionRegistration = boolean | RegisterOptions;\n\n/** Options common to every resource kind (the base layer for the options-injection system). */\nexport type CommonResourceOptions = {\n /** Auto-registration into the nearest transition scope. */\n readonly register?: TransitionRegistration;\n /** Retry failed requests. */\n readonly retry?: RetryOptions;\n /** Configure a circuit breaker for the resource. */\n readonly circuitBreaker?: CircuitBreakerOptions | true;\n /** Trigger a request even when the request parameters are unchanged. @default false */\n readonly triggerOnSameRequest?: boolean;\n};\n\nconst RESOURCE_OPTIONS = new InjectionToken<CommonResourceOptions>(\n '@mmstack/resource:resource-options',\n { factory: () => ({}) },\n);\n\nfunction asProvider<T>(\n token: InjectionToken<T>,\n valueOrFn: T | (() => T),\n): Provider {\n return typeof valueOrFn === 'function'\n ? { provide: token, useFactory: valueOrFn as () => T }\n : { provide: token, useValue: valueOrFn };\n}\n\n/** Layer 1: defaults that apply to ALL resource kinds. Type-specific providers inherit + override these. */\nexport function provideResourceOptions(\n valueOrFn: CommonResourceOptions | (() => CommonResourceOptions),\n): Provider {\n return asProvider(RESOURCE_OPTIONS, valueOrFn);\n}\n\nexport function injectResourceOptions(\n injector?: Injector,\n): CommonResourceOptions {\n return injector ? injector.get(RESOURCE_OPTIONS) : inject(RESOURCE_OPTIONS);\n}\n\n/** Shared helper for the type-specific providers (query/mutation), so precedence is identical. */\nexport function provideTypedResourceOptions<T>(\n token: InjectionToken<T>,\n valueOrFn: T | (() => T),\n): Provider {\n return asProvider(token, valueOrFn);\n}\n\n/**\n * Applies a resolved `register` option to a freshly-created resource — adds it to the nearest\n * transition scope and removes it on destroy. Runs in the resource's injection context (or the\n * provided `injector`), since registration needs `TRANSITION_SCOPE` + `DestroyRef`.\n */\nexport function applyResourceRegistration(\n ref: ResourceRef<unknown>,\n register: TransitionRegistration | undefined,\n injector?: Injector,\n): void {\n if (!register) return;\n const opt: RegisterOptions =\n register === true ? { suspends: false } : register;\n const run = injector\n ? (fn: () => void) => runInInjectionContext(injector, fn)\n : (fn: () => void) => fn();\n run(() => {\n const scope = injectTransitionScope();\n const destroyRef = inject(DestroyRef);\n scope.add(ref, opt);\n destroyRef.onDestroy(() => scope.remove(ref));\n });\n}\n","import {\n HttpClient,\n type HttpHeaders,\n httpResource,\n type HttpResourceOptions,\n type HttpResourceRef,\n type HttpResourceRequest,\n HttpResponse,\n} from '@angular/common/http';\nimport {\n computed,\n DestroyRef,\n effect,\n inject,\n InjectionToken,\n type Injector,\n isDevMode,\n linkedSignal,\n type Provider,\n type ResourceRef,\n type Signal,\n untracked,\n type WritableSignal,\n} from '@angular/core';\nimport { toWritable } from '@mmstack/primitives';\nimport { firstValueFrom } from 'rxjs';\nimport {\n applyResourceRegistration,\n type CommonResourceOptions,\n injectResourceOptions,\n provideTypedResourceOptions,\n} from './options';\nimport {\n catchValueError,\n createCircuitBreaker,\n createEqualRequest,\n hashRequest,\n hasSlowConnection,\n injectNetworkStatus,\n injectQueryCache,\n persistResourceValues,\n refresh,\n retryOnError,\n setCacheContext,\n toResourceObject,\n} from './util';\nimport { type 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`. Extends Angular's\n * `HttpResourceOptions` with caching, retries, refresh intervals, circuit\n * breakers, and lifecycle callbacks. See the linked properties below for the\n * full list.\n *\n * @example\n * ```ts\n * const options: QueryResourceOptions<User> = {\n * defaultValue: { id: 0, name: 'Anonymous' },\n * cache: { ttl: 60_000, staleTime: 10_000 },\n * refresh: 30_000,\n * retry: { max: 3 },\n * circuitBreaker: true,\n * onError: (err, retry, isFinal) => isFinal && toast.error(err),\n * };\n * ```\n */\nexport type QueryResourceOptions<TResult, TRaw = TResult> = HttpResourceOptions<\n TResult,\n TRaw\n> &\n CommonResourceOptions & {\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 * 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 enabling and configuring caching for the resource.\n */\n cache?: ResourceCacheOptions;\n /**\n * Comparison of request object\n */\n equalRequest?: (a: HttpResourceRequest, b: HttpResourceRequest) => boolean;\n };\n\nconst QUERY_RESOURCE_OPTIONS = new InjectionToken<\n Partial<QueryResourceOptions<any, any>>\n>('@mmstack/resource:query-resource-options', { factory: () => ({}) });\n\n/**\n * Layer 2 (query): default options for every `queryResource`, inheriting + overriding the\n * common defaults from `provideResourceOptions`. Per-call options override these in turn.\n */\nexport function provideQueryResourceOptions(\n valueOrFn:\n | Partial<QueryResourceOptions<any, any>>\n | (() => Partial<QueryResourceOptions<any, any>>),\n): Provider {\n return provideTypedResourceOptions(QUERY_RESOURCE_OPTIONS, valueOrFn);\n}\n\nfunction injectQueryResourceOptions(\n injector?: Injector,\n): Partial<QueryResourceOptions<any, any>> {\n return injector\n ? injector.get(QUERY_RESOURCE_OPTIONS)\n : inject(QUERY_RESOURCE_OPTIONS);\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 *\n * @example\n * ```ts\n * effect(() => {\n * switch (user.disabledReason()) {\n * case 'offline': return toast.warn('You are offline');\n * case 'circuit-open': return toast.warn('Service temporarily unavailable');\n * case 'no-request': return; // expected — request signal returned undefined\n * case null: return; // resource is enabled\n * }\n * });\n * ```\n */\nexport type DisabledReason = 'offline' | 'circuit-open' | 'no-request';\n\n/**\n * Returned from a resource's request fn to PAUSE it: the resource holds its current value and last\n * request (so it does not refetch on resume), and stops background work (no polling, no refetch\n * while paused). Distinct from returning `undefined` (DISABLE), which drops the request — a\n * disabled resource may refetch when re-enabled, a paused one resumes exactly where it left off.\n *\n * The request fn receives a {@link RequestContext} and can just return `ctx.paused`.\n */\nexport const PAUSED: unique symbol = Symbol('@mmstack/resource:paused');\n\n/**\n * Context passed to a resource's request fn. An object (not positional args) so it can grow\n * without changing the call signature. Today it carries {@link PAUSED} so the fn can return it.\n */\nexport type RequestContext = { readonly paused: typeof PAUSED };\n\n/** The request fn shape: build a request, or return `undefined` (disable) / `ctx.paused` (pause). */\nexport type ResourceRequestFn = (\n ctx: RequestContext,\n) => HttpResourceRequest | string | undefined | void | typeof PAUSED;\n\n/**\n * Represents a resource created by `queryResource`. Extends `HttpResourceRef`\n * with `disabled` / `disabledReason` signals, writable `headers` / `statusCode`\n * (so optimistic updates can patch them), and `prefetch()` for proactive cache\n * warm-up.\n *\n * @example\n * ```ts\n * const user = queryResource<User>(() => `/api/users/${userId()}`);\n *\n * effect(() => {\n * if (user.status() === 'resolved') console.log(user.value());\n * });\n *\n * // Warm the cache before navigating\n * onMouseEnter(() => user.prefetch());\n * ```\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 *\n * @example\n * ```ts\n * const userId = signal(1);\n *\n * const user = queryResource<User>(\n * () => `/api/users/${userId()}`,\n * { defaultValue: { id: 0, name: 'Anonymous' } },\n * );\n *\n * user.value(); // always User — never undefined, even before the first fetch resolves\n * ```\n */\nexport function queryResource<TResult, TRaw = TResult>(\n request: ResourceRequestFn,\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 *\n * @example\n * ```ts\n * const userId = signal<number | undefined>(undefined);\n *\n * const user = queryResource<User>(\n * () => userId() ? `/api/users/${userId()}` : undefined,\n * {\n * cache: { ttl: 60_000, staleTime: 10_000 },\n * refresh: 30_000,\n * retry: { max: 3 },\n * },\n * );\n *\n * user.value(); // User | undefined\n * user.status(); // 'idle' | 'loading' | 'resolved' | 'error'\n * user.disabledReason(); // null while enabled; 'offline' / 'circuit-open' / 'no-request' otherwise\n * ```\n */\nexport function queryResource<TResult, TRaw = TResult>(\n request: ResourceRequestFn,\n options?: QueryResourceOptions<TResult, TRaw>,\n): QueryResourceRef<TResult | undefined>;\n\nexport function queryResource<TResult, TRaw = TResult>(\n request: ResourceRequestFn,\n options0?: QueryResourceOptions<TResult, TRaw>,\n): QueryResourceRef<TResult | undefined> {\n // Two-layer option injection: per-call > provideQueryResourceOptions > provideResourceOptions.\n const options = {\n ...injectResourceOptions(options0?.injector),\n ...injectQueryResourceOptions(options0?.injector),\n ...options0,\n } as QueryResourceOptions<TResult, TRaw>;\n\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 : (options?.equalRequest ?? createEqualRequest());\n\n const requestCtx: RequestContext = { paused: PAUSED };\n const rawResult = computed(() => request(requestCtx));\n const paused = computed(() => rawResult() === PAUSED);\n const rawRequest = computed(() => {\n const r = rawResult();\n return r === PAUSED ? undefined : (r ?? undefined);\n });\n\n const disabledReason = computed<DisabledReason | null>(() => {\n if (!networkAvailable()) return 'offline';\n if (cb.isOpen()) return 'circuit-open';\n // PAUSED makes rawRequest undefined, so it reports 'no-request' here (and skips polling),\n // while stableRequest below HOLDS the last request so the value is kept (no refetch on resume).\n if (!rawRequest()) return 'no-request';\n return null;\n });\n\n // While PAUSED, hold the previous request so httpResource sees no change — it keeps its value and\n // does NOT refetch. On resume the request is re-evaluated, so it refetches only if it changed.\n const heldRequest = linkedSignal<\n { req: HttpResourceRequest | undefined; held: boolean },\n HttpResourceRequest | undefined\n >({\n source: () => {\n if (paused()) return { req: undefined, held: true };\n if (disabledReason() !== null) return { req: undefined, held: false };\n const req = rawRequest();\n if (!req) return { req: undefined, held: false };\n if (typeof req === 'string')\n return { req: { method: 'GET', url: req }, held: false };\n return { req, held: false };\n },\n computation: (curr, prev) =>\n curr.held && prev !== undefined ? prev.value : curr.req,\n });\n\n // Dedup via the request-equality (the linkedSignal re-runs on every source tick; this computed\n // is what actually gates httpResource — so an equal/held request never triggers a refetch).\n const stableRequest = computed(\n (): HttpResourceRequest | undefined => heldRequest(),\n {\n equal: (a, b) => {\n if (a === b) return true;\n if (a === undefined || b === undefined) return false;\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 // A disabled (offline / circuit-open / no-request) or PAUSED resource must not poll.\n resource = refresh(\n resource,\n destroyRef,\n options?.refresh,\n () => disabledReason() !== null,\n );\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 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 value = options?.cache\n ? toWritable(\n computed((): TResult => cacheEntry()?.value ?? resource.value()),\n set,\n 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') cb.fail(untracked(resource.error));\n else if (status === 'resolved') cb.success();\n });\n\n const client = options?.injector\n ? options.injector.get(HttpClient)\n : inject(HttpClient);\n\n const ref: QueryResourceRef<TResult | undefined> = {\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 referrerPolicy: prefetchRequest.referrerPolicy as\n | ReferrerPolicy\n | undefined,\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 // Auto-register into the nearest transition scope if the (merged) options ask for it.\n applyResourceRegistration(\n ref as ResourceRef<unknown>,\n options.register,\n options?.injector,\n );\n\n return ref;\n}\n","import { type HttpResourceRequest } from '@angular/common/http';\nimport { computed, inject, Injector, signal, untracked } from '@angular/core';\nimport { nestedEffect } from '@mmstack/primitives';\nimport {\n queryResource,\n type QueryResourceOptions,\n type QueryResourceRef,\n} from './query-resource';\n\n/**\n * A reference to a manually triggered query resource. Extends\n * {@link QueryResourceRef} with a `trigger()` method that runs the request\n * imperatively and returns a `Promise<TResult>`. Useful when a request should\n * only happen on user action (search submit, button click) rather than on\n * every reactive change of the request inputs.\n *\n * @example\n * ```ts\n * const search = manualQueryResource<SearchResults>(() => ({\n * url: '/api/search',\n * params: { q: query() },\n * }));\n *\n * async function onSubmit() {\n * try {\n * const results = await search.trigger();\n * showResults(results);\n * } catch (err) {\n * toast.error('Search failed');\n * }\n * }\n * ```\n *\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 *\n * @example\n * ```ts\n * const search = manualQueryResource<SearchResults>(\n * () => ({ url: '/api/search', params: { q: query() } }),\n * { defaultValue: { hits: [], total: 0 } },\n * );\n *\n * // search.value() is always SearchResults (never undefined) thanks to defaultValue.\n * const results = await search.trigger();\n * ```\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 *\n * @example\n * ```ts\n * const exportReport = manualQueryResource<Report>(() => ({\n * url: '/api/reports/export',\n * params: { range: range() },\n * }));\n *\n * async function onExportClick() {\n * try {\n * const report = await exportReport.trigger();\n * download(report);\n * } catch (err) {\n * toast.error('Export failed');\n * }\n * }\n * ```\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 InjectionToken,\n type Injector,\n isDevMode,\n linkedSignal,\n type Provider,\n type ResourceRef,\n type Signal,\n signal,\n type ValueEqualityFn,\n} from '@angular/core';\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\nimport { catchError, combineLatestWith, filter, map, of } from 'rxjs';\nimport {\n applyResourceRegistration,\n injectResourceOptions,\n provideTypedResourceOptions,\n} from './options';\nimport {\n queryResource,\n type QueryResourceOptions,\n type QueryResourceRef,\n} from './query-resource';\nimport { createCircuitBreaker, createEqualRequest } from './util';\n\nconst NULL_VALUE = Symbol('@mmstack/resource:null');\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`. Inherits from\n * `QueryResourceOptions` (minus options that don't apply to mutations:\n * `equal`, `keepPrevious`, `refresh`, `cache`) and adds lifecycle callbacks\n * (`onMutate`, `onError`, `onSuccess`, `onSettled`) for managing optimistic\n * updates, rollback, and side effects.\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 *\n * @example\n * ```ts\n * const options: MutationResourceOptions<User, User, Partial<User>, { previous: User | null }> = {\n * onMutate: (patch) => {\n * const previous = current();\n * current.update((u) => (u ? { ...u, ...patch } : u)); // optimistic\n * return { previous };\n * },\n * onError: (_err, { previous }) => current.set(previous), // rollback\n * onSuccess: (saved) => toast.success(`Updated ${saved.name}`),\n * queue: true, // serialize requests when offline / circuit open\n * };\n * ```\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\nconst MUTATION_RESOURCE_OPTIONS = new InjectionToken<\n Partial<MutationResourceOptions<any, any, any, any, any, any>>\n>('@mmstack/resource:mutation-resource-options', { factory: () => ({}) });\n\n/**\n * Layer 2 (mutation): default options for every `mutationResource`, inheriting + overriding the\n * common defaults from `provideResourceOptions`. Per-call options override these in turn.\n */\nexport function provideMutationResourceOptions(\n valueOrFn:\n | Partial<MutationResourceOptions<any, any, any, any, any, any>>\n | (() => Partial<MutationResourceOptions<any, any, any, any, any, any>>),\n): Provider {\n return provideTypedResourceOptions(MUTATION_RESOURCE_OPTIONS, valueOrFn);\n}\n\nfunction injectMutationResourceOptions(\n injector?: Injector,\n): Partial<MutationResourceOptions<any, any, any, any, any, any>> {\n return injector\n ? injector.get(MUTATION_RESOURCE_OPTIONS)\n : inject(MUTATION_RESOURCE_OPTIONS);\n}\n\n/**\n * Represents a mutation resource created by `mutationResource`. Extends\n * `QueryResourceRef` but strips methods that don't make sense for one-off\n * writes (`prefetch`, `value`, `hasValue`, `set`, `update`) and adds `mutate()`\n * for triggering a mutation plus `current()` for tracking the in-flight value.\n *\n * @typeParam TResult - The type of the expected result from the mutation.\n *\n * @example\n * ```ts\n * const updateUser = mutationResource<User, User, Partial<User>>(...);\n *\n * effect(() => console.log('mutating:', updateUser.current()));\n * effect(() => {\n * if (updateUser.status() === 'error') toast.error(updateUser.error());\n * });\n *\n * updateUser.mutate({ name: 'Alice' });\n * ```\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 *\n * @example\n * ```ts\n * // Basic PATCH mutation\n * const updateUser = mutationResource<User, User, Partial<User>>(\n * (body) => ({ url: `/api/users/${userId()}`, method: 'PATCH', body }),\n * {\n * onSuccess: (saved) => toast.success(`Updated ${saved.name}`),\n * onError: (err) => toast.error(err),\n * },\n * );\n *\n * updateUser.mutate({ name: 'Alice' });\n * ```\n *\n * @example\n * ```ts\n * // Optimistic update with rollback via the `ctx` returned from `onMutate`\n * const updateUser = mutationResource<User, User, Partial<User>, { prev: User | null }>(\n * (body) => ({ url: `/api/users/${userId()}`, method: 'PATCH', body }),\n * {\n * onMutate: (patch) => {\n * const prev = current();\n * current.update((u) => (u ? { ...u, ...patch } : u));\n * return { prev };\n * },\n * onError: (_err, { prev }) => current.set(prev),\n * },\n * );\n * ```\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 options0: MutationResourceOptions<TResult, TRaw, TMutation, TCTX, TICTX> = {},\n): MutationResourceRef<TResult, TMutation, TICTX> {\n // Two-layer option injection: per-call > provideMutationResourceOptions > provideResourceOptions.\n const options = {\n ...injectResourceOptions(options0.injector),\n ...injectMutationResourceOptions(options0.injector),\n ...options0,\n } as MutationResourceOptions<TResult, TRaw, TMutation, TCTX, TICTX>;\n\n // `register` is pulled out (and forced off on the inner query below) so the mutation ref is\n // the only thing registered into the transition scope, not its internal query resource.\n const {\n onMutate,\n onError,\n onSuccess,\n onSettled,\n equal,\n register,\n equalRequest,\n ...rest\n } = options;\n\n const requestEqual = equalRequest ?? createEqualRequest(equal);\n\n // A mutation is an imperative command, so `triggerOnSameRequest` means \"fire on EVERY mutate(),\n // even with an identical body\". By default we dedup an identical value/request while one is in\n // flight (double-click protection); when this is set, both the `next` and `req` dedup are bypassed\n // so a repeat click isn't silently swallowed mid-flight. (Otherwise it'd be dropped until `next`\n // resets to NULL on settle — the \"every other click\" symptom.)\n const triggerOnSame = options.triggerOnSameRequest ?? false;\n\n const eq = equal ?? Object.is;\n const next = signal<TMutation | typeof NULL_VALUE>(NULL_VALUE, {\n equal: (a, b) => {\n if (a === NULL_VALUE && b === NULL_VALUE) return true;\n if (a === NULL_VALUE || b === NULL_VALUE) return false;\n if (triggerOnSame) 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 === undefined || next() !== NULL_VALUE) return;\n queue.update((q) => q.slice(1));\n const [value, ictx] = nextInQueue;\n try {\n ctx = onMutate?.(value, ictx) as TCTX;\n next.set(value);\n } catch (mutationErr) {\n ctx = undefined as TCTX;\n next.set(NULL_VALUE);\n if (isDevMode())\n console.error(\n '[@mmstack/resource]: error thrown in onMutate hook, mutation was not applied',\n mutationErr,\n );\n }\n });\n\n const req = computed(\n (): HttpResourceRequest | undefined => {\n const nr = next();\n if (nr === NULL_VALUE) return;\n\n return request(nr) ?? undefined;\n },\n {\n equal: (a, b) => {\n if (a === undefined && b === undefined) return true;\n if (a === undefined || b === undefined) return false;\n if (triggerOnSame) return false;\n return requestEqual(a, b);\n },\n },\n );\n\n const lastValue = linkedSignal<\n TMutation | typeof NULL_VALUE,\n TMutation | typeof NULL_VALUE\n >({\n source: next,\n computation: (next, prev) => {\n if (next === NULL_VALUE && !!prev) return prev.value;\n return next;\n },\n });\n\n const lastValueRequest = computed(\n (): HttpResourceRequest | undefined => {\n const nr = lastValue();\n if (nr === NULL_VALUE) return;\n\n return request(nr) ?? undefined;\n },\n {\n equal: (a, b) => {\n if (a === b) return true;\n if (a === undefined || b === undefined) return false;\n return requestEqual(a, b);\n },\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 register: false, // the mutation ref handles registration; never register the inner query\n circuitBreaker: cb,\n equalRequest: requestEqual,\n defaultValue: NULL_VALUE 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(\n catchError(() => of(NULL_VALUE)),\n );\n\n const statusSub = toObservable(resource.status)\n .pipe(\n combineLatestWith(error$, value$),\n map(\n ([status, error, value]): StatusResult<TResult> | typeof NULL_VALUE => {\n if (status === 'error' && error) {\n return {\n status: 'error',\n error,\n };\n }\n\n if (status === 'resolved' && value !== NULL_VALUE) {\n return {\n status: 'resolved',\n value,\n };\n }\n\n return NULL_VALUE;\n },\n ),\n filter((v) => v !== NULL_VALUE),\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_VALUE);\n });\n\n const shouldQueue = options.queue ?? false;\n\n const ref: MutationResourceRef<TResult, TMutation, TICTX> = {\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 try {\n ctx = onMutate?.(value, ictx) as TCTX;\n next.set(value);\n } catch (mutationErr) {\n ctx = undefined as TCTX;\n next.set(NULL_VALUE);\n if (isDevMode())\n console.error(\n '[@mmstack/resource]: error thrown in onMutate hook, mutation was not applied',\n mutationErr,\n );\n }\n }\n },\n current: computed(() => {\n const nv = next();\n return nv === NULL_VALUE ? null : nv;\n }),\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 applyResourceRegistration(\n ref as unknown as ResourceRef<unknown>,\n register,\n options0.injector,\n );\n\n return ref;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmstack/resource",
3
- "version": "21.4.0",
3
+ "version": "22.1.0",
4
4
  "keywords": [
5
5
  "angular",
6
6
  "signals",
@@ -18,12 +18,12 @@
18
18
  },
19
19
  "homepage": "https://github.com/mihajm/mmstack/blob/master/packages/resource",
20
20
  "dependencies": {
21
- "@mmstack/primitives": "^21.1.0",
21
+ "@mmstack/primitives": "^22.1.0",
22
22
  "tslib": "^2.3.0"
23
23
  },
24
24
  "peerDependencies": {
25
- "@angular/common": ">=21.2 <22",
26
- "@angular/core": ">=21.2 <22",
25
+ "@angular/common": ">=22 <23",
26
+ "@angular/core": ">=22 <23",
27
27
  "rxjs": "~7.8.2"
28
28
  },
29
29
  "sideEffects": false,