@mmstack/resource 21.0.0 → 21.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025-present Miha J. Mulec
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025-present Miha J. Mulec
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,120 +1,120 @@
1
- # @mmstack/resource
2
-
3
- [![npm version](https://badge.fury.io/js/%40mmstack%2Fresource.svg)](https://www.npmjs.com/package/@mmstack/resource)
4
- [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/mihajm/mmstack/blob/master/packages/resource/LICENSE)
5
-
6
- `@mmstack/resource` is an Angular library that provides powerful, signal-based primitives for managing asynchronous data fetching and mutations. It builds upon Angular's `httpResource` and offers features like caching, retries, refresh intervals, circuit breakers, and request deduplication, all while maintaining a fine-grained reactive graph. It's inspired by libraries like TanStack Query, but aims for a more Angular-idiomatic and signal-centric approach.
7
-
8
- ## Features
9
-
10
- - **Signal-Based:** Fully integrates with Angular's signal system for efficient change detection and reactivity.
11
- - **Caching:** Built-in caching with configurable TTL (Time To Live) and stale-while-revalidate behavior. Supports custom cache key generation and respects HTTP caching headers.
12
- - **Retries:** Automatic retries on failure with configurable backoff strategies.
13
- - **Refresh Intervals:** Automatically refetch data at specified intervals.
14
- - **Circuit Breaker:** Protects your application from cascading failures by temporarily disabling requests to failing endpoints.
15
- - **Request Deduplication:** Avoids making multiple identical requests concurrently.
16
- - **Mutations:** Provides a dedicated `mutationResource` for handling data modifications, with callbacks for `onMutate`, `onError`, `onSuccess`, and `onSettled`.
17
- - **Prefetching:** Allows you to prefetch data into the cache, improving perceived performance.
18
- - **Extensible:** Designed to be modular and extensible. You can easily add your own custom features or integrate with other libraries.
19
- - **TypeScript Support:** A strong focus on typesafety
20
-
21
- ## Quick Start
22
-
23
- 1. Install mmstack-resource
24
-
25
- ```bash
26
- npm install @mmstack/resource
27
- ```
28
-
29
- 2. Initialize the QueryCache & interceptors (optional)
30
-
31
- ```typescript
32
- import { provideHttpClient, withInterceptors } from '@angular/common/http';
33
- import { ApplicationConfig } from '@angular/core';
34
- import { createCacheInterceptor, createDedupeRequestsInterceptor, provideQueryCache } from '@mmstack/resource';
35
-
36
- export const appConfig: ApplicationConfig = {
37
- providers: [
38
- // ..other providers
39
- provideQueryCache(),
40
-
41
- // --- Example of a more advanced setup ---
42
- // provideQueryCache({
43
- // persist: true, // Enable IndexedDB persistence
44
- // version: 1, // Version for the cache schema
45
- // syncTabs: true // enable BroadcastChannel
46
- // }),
47
-
48
- provideHttpClient(withInterceptors([createCacheInterceptor(), createDedupeRequestsInterceptor()])),
49
- ],
50
- };
51
- ```
52
-
53
- 3. Use it :)
54
-
55
- ```typescript
56
- import { Injectable, isDevMode, untracked } from '@angular/core';
57
- import { createCircuitBreaker, mutationResource, queryResource } from '@mmstack/resource';
58
-
59
- type Post = {
60
- userId: number;
61
- id: number;
62
- title: string;
63
- body: string;
64
- };
65
-
66
- @Injectable({
67
- providedIn: 'root',
68
- })
69
- export class PostsService {
70
- private readonly endpoint = 'https://jsonplaceholder.typicode.com/posts';
71
- private readonly cb = createCircuitBreaker();
72
- readonly posts = queryResource<Post[]>(
73
- () => ({
74
- url: this.endpoint,
75
- }),
76
- {
77
- keepPrevious: true, // keep data between requests
78
- refresh: 5 * 60 * 1000, // refresh every 5 minutes
79
- circuitBreaker: this.cb, // use shared circuit breaker use true if not sharing
80
- retry: 3, // retry 3 times on error using default backoff
81
- onError: (err) => {
82
- if (!isDevMode()) return;
83
- console.error(err);
84
- }, // log errors in dev mode
85
- defaultValue: [],
86
- },
87
- );
88
-
89
- private readonly createPostResource = mutationResource(
90
- (post: Post) => ({
91
- url: this.endpoint,
92
- method: 'POST',
93
- body: post,
94
- }),
95
- {
96
- circuitBreaker: this.cb, // use shared circuit breaker use true if not sharing
97
- onMutate: (post: Post) => {
98
- const prev = untracked(this.posts.value);
99
- this.posts.set([...prev, post]); // optimistically update
100
- return prev;
101
- },
102
- onError: (err, prev) => {
103
- if (isDevMode()) console.error(err);
104
- this.posts.set(prev); // rollback on error
105
- },
106
- onSuccess: (next) => {
107
- this.posts.update((posts) => posts.map((p) => (p.id === next.id ? next : p))); // replace with value from server
108
- },
109
- },
110
- );
111
-
112
- createPost(post: Post) {
113
- this.createPostResource.mutate(post); // send the request
114
- }
115
- }
116
- ```
117
-
118
- ## In-depth
119
-
120
- For an in-depth explanation of the primitives & how they work check out this article: [Fun-grained Reactivity in Angular: Part 3 - Resources](https://dev.to/mihamulec/fun-grained-reactivity-in-angular-part-3-client-side-http-57g4)
1
+ # @mmstack/resource
2
+
3
+ [![npm version](https://badge.fury.io/js/%40mmstack%2Fresource.svg)](https://www.npmjs.com/package/@mmstack/resource)
4
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/mihajm/mmstack/blob/master/packages/resource/LICENSE)
5
+
6
+ `@mmstack/resource` is an Angular library that provides powerful, signal-based primitives for managing asynchronous data fetching and mutations. It builds upon Angular's `httpResource` and offers features like caching, retries, refresh intervals, circuit breakers, and request deduplication, all while maintaining a fine-grained reactive graph. It's inspired by libraries like TanStack Query, but aims for a more Angular-idiomatic and signal-centric approach.
7
+
8
+ ## Features
9
+
10
+ - **Signal-Based:** Fully integrates with Angular's signal system for efficient change detection and reactivity.
11
+ - **Caching:** Built-in caching with configurable TTL (Time To Live) and stale-while-revalidate behavior. Supports custom cache key generation and respects HTTP caching headers.
12
+ - **Retries:** Automatic retries on failure with configurable backoff strategies.
13
+ - **Refresh Intervals:** Automatically refetch data at specified intervals.
14
+ - **Circuit Breaker:** Protects your application from cascading failures by temporarily disabling requests to failing endpoints.
15
+ - **Request Deduplication:** Avoids making multiple identical requests concurrently.
16
+ - **Mutations:** Provides a dedicated `mutationResource` for handling data modifications, with callbacks for `onMutate`, `onError`, `onSuccess`, and `onSettled`.
17
+ - **Prefetching:** Allows you to prefetch data into the cache, improving perceived performance.
18
+ - **Extensible:** Designed to be modular and extensible. You can easily add your own custom features or integrate with other libraries.
19
+ - **TypeScript Support:** A strong focus on typesafety
20
+
21
+ ## Quick Start
22
+
23
+ 1. Install mmstack-resource
24
+
25
+ ```bash
26
+ npm install @mmstack/resource
27
+ ```
28
+
29
+ 2. Initialize the QueryCache & interceptors (optional)
30
+
31
+ ```typescript
32
+ import { provideHttpClient, withInterceptors } from '@angular/common/http';
33
+ import { ApplicationConfig } from '@angular/core';
34
+ import { createCacheInterceptor, createDedupeRequestsInterceptor, provideQueryCache } from '@mmstack/resource';
35
+
36
+ export const appConfig: ApplicationConfig = {
37
+ providers: [
38
+ // ..other providers
39
+ provideQueryCache(),
40
+
41
+ // --- Example of a more advanced setup ---
42
+ // provideQueryCache({
43
+ // persist: true, // Enable IndexedDB persistence
44
+ // version: 1, // Version for the cache schema
45
+ // syncTabs: true // enable BroadcastChannel
46
+ // }),
47
+
48
+ provideHttpClient(withInterceptors([createCacheInterceptor(), createDedupeRequestsInterceptor()])),
49
+ ],
50
+ };
51
+ ```
52
+
53
+ 3. Use it :)
54
+
55
+ ```typescript
56
+ import { Injectable, isDevMode, untracked } from '@angular/core';
57
+ import { createCircuitBreaker, mutationResource, queryResource } from '@mmstack/resource';
58
+
59
+ type Post = {
60
+ userId: number;
61
+ id: number;
62
+ title: string;
63
+ body: string;
64
+ };
65
+
66
+ @Injectable({
67
+ providedIn: 'root',
68
+ })
69
+ export class PostsService {
70
+ private readonly endpoint = 'https://jsonplaceholder.typicode.com/posts';
71
+ private readonly cb = createCircuitBreaker();
72
+ readonly posts = queryResource<Post[]>(
73
+ () => ({
74
+ url: this.endpoint,
75
+ }),
76
+ {
77
+ keepPrevious: true, // keep data between requests
78
+ refresh: 5 * 60 * 1000, // refresh every 5 minutes
79
+ circuitBreaker: this.cb, // use shared circuit breaker use true if not sharing
80
+ retry: 3, // retry 3 times on error using default backoff
81
+ onError: (err) => {
82
+ if (!isDevMode()) return;
83
+ console.error(err);
84
+ }, // log errors in dev mode
85
+ defaultValue: [],
86
+ },
87
+ );
88
+
89
+ private readonly createPostResource = mutationResource(
90
+ (post: Post) => ({
91
+ url: this.endpoint,
92
+ method: 'POST',
93
+ body: post,
94
+ }),
95
+ {
96
+ circuitBreaker: this.cb, // use shared circuit breaker use true if not sharing
97
+ onMutate: (post: Post) => {
98
+ const prev = untracked(this.posts.value);
99
+ this.posts.set([...prev, post]); // optimistically update
100
+ return prev;
101
+ },
102
+ onError: (err, prev) => {
103
+ if (isDevMode()) console.error(err);
104
+ this.posts.set(prev); // rollback on error
105
+ },
106
+ onSuccess: (next) => {
107
+ this.posts.update((posts) => posts.map((p) => (p.id === next.id ? next : p))); // replace with value from server
108
+ },
109
+ },
110
+ );
111
+
112
+ createPost(post: Post) {
113
+ this.createPostResource.mutate(post); // send the request
114
+ }
115
+ }
116
+ ```
117
+
118
+ ## In-depth
119
+
120
+ For an in-depth explanation of the primitives & how they work check out this article: [Fun-grained Reactivity in Angular: Part 3 - Resources](https://dev.to/mihamulec/fun-grained-reactivity-in-angular-part-3-client-side-http-57g4)
@@ -1178,21 +1178,13 @@ function hasSlowConnection() {
1178
1178
 
1179
1179
  function persist(src, equal) {
1180
1180
  // linkedSignal allows us to access previous source value
1181
- const persisted = linkedSignal(...(ngDevMode ? [{ debugName: "persisted", source: () => src(),
1182
- computation: (next, prev) => {
1183
- if (next === undefined && prev !== undefined)
1184
- return prev.value;
1185
- return next;
1186
- },
1187
- equal }] : [{
1188
- source: () => src(),
1189
- computation: (next, prev) => {
1190
- if (next === undefined && prev !== undefined)
1191
- return prev.value;
1192
- return next;
1193
- },
1194
- equal,
1195
- }]));
1181
+ const persisted = linkedSignal({ ...(ngDevMode ? { debugName: "persisted" } : {}), source: () => src(),
1182
+ computation: (next, prev) => {
1183
+ if (next === undefined && prev !== undefined)
1184
+ return prev.value;
1185
+ return next;
1186
+ },
1187
+ equal });
1196
1188
  // if original value was WritableSignal then override linkedSignal methods to original...angular uses linkedSignal under the hood in ResourceImpl, this applies to that.
1197
1189
  if ('set' in src) {
1198
1190
  persisted.set = src.set;
@@ -1277,10 +1269,10 @@ function retryOnError(res, opt) {
1277
1269
 
1278
1270
  class ResourceSensors {
1279
1271
  networkStatus = sensor('networkStatus');
1280
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: ResourceSensors, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1281
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: ResourceSensors, providedIn: 'root' });
1272
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: ResourceSensors, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1273
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: ResourceSensors, providedIn: 'root' });
1282
1274
  }
1283
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: ResourceSensors, decorators: [{
1275
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: ResourceSensors, decorators: [{
1284
1276
  type: Injectable,
1285
1277
  args: [{
1286
1278
  providedIn: 'root',
@@ -1347,17 +1339,11 @@ function queryResource(request, options) {
1347
1339
  if (!networkAvailable() || cb.isOpen())
1348
1340
  return undefined;
1349
1341
  return request() ?? undefined;
1350
- }, ...(ngDevMode ? [{ debugName: "stableRequest", equal: (a, b) => {
1351
- if (eq)
1352
- return eq(a, b);
1353
- return a === b;
1354
- } }] : [{
1355
- equal: (a, b) => {
1356
- if (eq)
1357
- return eq(a, b);
1358
- return a === b;
1359
- },
1360
- }]));
1342
+ }, { ...(ngDevMode ? { debugName: "stableRequest" } : {}), equal: (a, b) => {
1343
+ if (eq)
1344
+ return eq(a, b);
1345
+ return a === b;
1346
+ } });
1361
1347
  const hashFn = typeof options?.cache === 'object'
1362
1348
  ? (options.cache.hash ?? urlWithParams)
1363
1349
  : urlWithParams;
@@ -1399,45 +1385,25 @@ function queryResource(request, options) {
1399
1385
  resource = catchValueError(resource, options?.defaultValue);
1400
1386
  // get full HttpResonse from Cache
1401
1387
  const cachedEvent = cache.getEntryOrKey(cacheKey);
1402
- const cacheEntry = linkedSignal(...(ngDevMode ? [{ debugName: "cacheEntry", source: () => cachedEvent(),
1403
- computation: (entry, prev) => {
1404
- if (!entry)
1405
- return null;
1406
- if (typeof entry === 'string' &&
1407
- prev &&
1408
- prev.value !== null &&
1409
- prev.value.key === entry) {
1410
- return prev.value;
1411
- }
1412
- if (typeof entry === 'string')
1413
- return { key: entry, value: null };
1414
- if (!(entry.value instanceof HttpResponse))
1415
- return { key: entry.key, value: null };
1416
- return {
1417
- value: entry.value.body,
1418
- key: entry.key,
1419
- };
1420
- } }] : [{
1421
- source: () => cachedEvent(),
1422
- computation: (entry, prev) => {
1423
- if (!entry)
1424
- return null;
1425
- if (typeof entry === 'string' &&
1426
- prev &&
1427
- prev.value !== null &&
1428
- prev.value.key === entry) {
1429
- return prev.value;
1430
- }
1431
- if (typeof entry === 'string')
1432
- return { key: entry, value: null };
1433
- if (!(entry.value instanceof HttpResponse))
1434
- return { key: entry.key, value: null };
1435
- return {
1436
- value: entry.value.body,
1437
- key: entry.key,
1438
- };
1439
- },
1440
- }]));
1388
+ const cacheEntry = linkedSignal({ ...(ngDevMode ? { debugName: "cacheEntry" } : {}), source: () => cachedEvent(),
1389
+ computation: (entry, prev) => {
1390
+ if (!entry)
1391
+ return null;
1392
+ if (typeof entry === 'string' &&
1393
+ prev &&
1394
+ prev.value !== null &&
1395
+ prev.value.key === entry) {
1396
+ return prev.value;
1397
+ }
1398
+ if (typeof entry === 'string')
1399
+ return { key: entry, value: null };
1400
+ if (!(entry.value instanceof HttpResponse))
1401
+ return { key: entry.key, value: null };
1402
+ return {
1403
+ value: entry.value.body,
1404
+ key: entry.key,
1405
+ };
1406
+ } });
1441
1407
  resource = refresh(resource, destroyRef, options?.refresh);
1442
1408
  resource = retryOnError(resource, options?.retry);
1443
1409
  resource = persistResourceValues(resource, options?.keepPrevious, options?.equal);
@@ -1576,21 +1542,13 @@ function mutationResource(request, options = {}) {
1576
1542
  const { onMutate, onError, onSuccess, onSettled, equal, ...rest } = options;
1577
1543
  const requestEqual = createEqualRequest(equal);
1578
1544
  const eq = equal ?? Object.is;
1579
- const next = signal(null, ...(ngDevMode ? [{ debugName: "next", equal: (a, b) => {
1580
- if (!a && !b)
1581
- return true;
1582
- if (!a || !b)
1583
- return false;
1584
- return eq(a, b);
1585
- } }] : [{
1586
- equal: (a, b) => {
1587
- if (!a && !b)
1588
- return true;
1589
- if (!a || !b)
1590
- return false;
1591
- return eq(a, b);
1592
- },
1593
- }]));
1545
+ const next = signal(null, { ...(ngDevMode ? { debugName: "next" } : {}), equal: (a, b) => {
1546
+ if (!a && !b)
1547
+ return true;
1548
+ if (!a || !b)
1549
+ return false;
1550
+ return eq(a, b);
1551
+ } });
1594
1552
  const queue = signal([], ...(ngDevMode ? [{ debugName: "queue" }] : []));
1595
1553
  let ctx = undefined;
1596
1554
  const queueRef = effect(() => {
@@ -1607,30 +1565,19 @@ function mutationResource(request, options = {}) {
1607
1565
  if (!nr)
1608
1566
  return;
1609
1567
  return request(nr) ?? undefined;
1610
- }, ...(ngDevMode ? [{ debugName: "req", equal: requestEqual }] : [{
1611
- equal: requestEqual,
1612
- }]));
1613
- const lastValue = linkedSignal(...(ngDevMode ? [{ debugName: "lastValue", source: next,
1614
- computation: (next, prev) => {
1615
- if (next === null && !!prev)
1616
- return prev.value;
1617
- return next;
1618
- } }] : [{
1619
- source: next,
1620
- computation: (next, prev) => {
1621
- if (next === null && !!prev)
1622
- return prev.value;
1623
- return next;
1624
- },
1625
- }]));
1568
+ }, { ...(ngDevMode ? { debugName: "req" } : {}), equal: requestEqual });
1569
+ const lastValue = linkedSignal({ ...(ngDevMode ? { debugName: "lastValue" } : {}), source: next,
1570
+ computation: (next, prev) => {
1571
+ if (next === null && !!prev)
1572
+ return prev.value;
1573
+ return next;
1574
+ } });
1626
1575
  const lastValueRequest = computed(() => {
1627
1576
  const nr = lastValue();
1628
1577
  if (!nr)
1629
1578
  return;
1630
1579
  return request(nr) ?? undefined;
1631
- }, ...(ngDevMode ? [{ debugName: "lastValueRequest", equal: requestEqual }] : [{
1632
- equal: requestEqual,
1633
- }]));
1580
+ }, { ...(ngDevMode ? { debugName: "lastValueRequest" } : {}), equal: requestEqual });
1634
1581
  const cb = createCircuitBreaker(options?.circuitBreaker === true
1635
1582
  ? undefined
1636
1583
  : (options?.circuitBreaker ?? false), options?.injector);
@@ -1 +1 @@
1
- {"version":3,"file":"mmstack-resource.mjs","sources":["../../../../packages/resource/src/lib/util/cache/persistence.ts","../../../../packages/resource/src/lib/util/cache/cache.ts","../../../../packages/resource/src/lib/util/cache/cache-interceptor.ts","../../../../packages/resource/src/lib/util/catch-value-error.ts","../../../../packages/resource/src/lib/util/circuit-breaker.ts","../../../../packages/resource/src/lib/util/dedupe-interceptor.ts","../../../../packages/resource/src/lib/util/equality.ts","../../../../packages/resource/src/lib/util/has-slow-connection.ts","../../../../packages/resource/src/lib/util/persist.ts","../../../../packages/resource/src/lib/util/refresh.ts","../../../../packages/resource/src/lib/util/retry-on-error.ts","../../../../packages/resource/src/lib/util/sensors.ts","../../../../packages/resource/src/lib/util/to-resource-object.ts","../../../../packages/resource/src/lib/util/url-with-params.ts","../../../../packages/resource/src/lib/query-resource.ts","../../../../packages/resource/src/lib/mutation-resource.ts","../../../../packages/resource/src/mmstack-resource.ts"],"sourcesContent":["import { isDevMode } from '@angular/core';\r\nimport { CacheEntry } from './cache';\r\n\r\ntype StoredEntry<T> = Omit<CacheEntry<T>, 'timeout'>;\r\n\r\nexport type CacheDB<T> = {\r\n getAll: () => Promise<StoredEntry<T>[]>;\r\n store: (value: StoredEntry<T>) => Promise<void>;\r\n remove: (key: string) => Promise<void>;\r\n};\r\n\r\nexport function createNoopDB<T>(): CacheDB<T> {\r\n return {\r\n getAll: async () => [],\r\n store: async () => {\r\n // noop\r\n },\r\n remove: async () => {\r\n // noop\r\n },\r\n };\r\n}\r\n\r\nfunction toCacheDB<T>(db: IDBDatabase, storeName: string): CacheDB<T> {\r\n const getAll = async () => {\r\n const now = Date.now();\r\n return new Promise<StoredEntry<T>[]>((res, rej) => {\r\n const transaction = db.transaction(storeName, 'readonly');\r\n const store = transaction.objectStore(storeName);\r\n const request = store.getAll();\r\n\r\n request.onsuccess = () => res(request.result);\r\n request.onerror = () => rej(request.error);\r\n })\r\n .then((entries) => entries.filter((e) => e.expiresAt > now))\r\n .catch((err) => {\r\n if (isDevMode())\r\n console.error('Error getting all items from cache DB:', err);\r\n return [];\r\n });\r\n };\r\n\r\n const store = (value: StoredEntry<T>) => {\r\n return new Promise<void>((res, rej) => {\r\n const transaction = db.transaction(storeName, 'readwrite');\r\n const store = transaction.objectStore(storeName);\r\n\r\n store.put(value);\r\n\r\n transaction.oncomplete = () => res();\r\n transaction.onerror = () => rej(transaction.error);\r\n }).catch((err) => {\r\n if (isDevMode()) console.error('Error storing item in cache DB:', err);\r\n });\r\n };\r\n\r\n const remove = (key: string) => {\r\n return new Promise<void>((res, rej) => {\r\n const transaction = db.transaction(storeName, 'readwrite');\r\n const store = transaction.objectStore(storeName);\r\n\r\n store.delete(key);\r\n\r\n transaction.oncomplete = () => res();\r\n transaction.onerror = () => rej(transaction.error);\r\n }).catch((err) => {\r\n if (isDevMode()) console.error('Error removing item from cache DB:', err);\r\n });\r\n };\r\n\r\n return {\r\n getAll,\r\n store,\r\n remove,\r\n };\r\n}\r\n\r\nexport function createSingleStoreDB<T>(\r\n name: string,\r\n getStoreName: (version: number) => string,\r\n version = 1,\r\n): Promise<CacheDB<T>> {\r\n const storeName = getStoreName(version);\r\n\r\n if (!globalThis.indexedDB) return Promise.resolve(createNoopDB());\r\n\r\n return new Promise<IDBDatabase>((res, rej) => {\r\n if (version < 1) rej(new Error('Version must be 1 or greater'));\r\n\r\n const req = indexedDB.open(name, version);\r\n\r\n req.onupgradeneeded = (event) => {\r\n const db = req.result;\r\n const oldVersion = event.oldVersion;\r\n\r\n db.createObjectStore(storeName, { keyPath: 'key' });\r\n\r\n if (oldVersion > 0) {\r\n db.deleteObjectStore(getStoreName(oldVersion));\r\n }\r\n };\r\n\r\n req.onerror = () => {\r\n rej(req.error);\r\n };\r\n\r\n req.onsuccess = () => res(req.result);\r\n })\r\n .then((db) => toCacheDB<T>(db, storeName))\r\n .catch((err) => {\r\n if (isDevMode()) console.error('Error creating query DB:', err);\r\n return createNoopDB();\r\n });\r\n}\r\n","import { HttpHeaders, HttpResponse } from '@angular/common/http';\r\nimport {\r\n computed,\r\n inject,\r\n InjectionToken,\r\n Injector,\r\n isDevMode,\r\n type Provider,\r\n type Signal,\r\n untracked,\r\n} from '@angular/core';\r\nimport { mutable } from '@mmstack/primitives';\r\nimport { CacheDB, createNoopDB, createSingleStoreDB } from './persistence';\r\n\r\nfunction generateID() {\r\n if (globalThis.crypto?.randomUUID) {\r\n return globalThis.crypto.randomUUID();\r\n }\r\n return Math.random().toString(36).substring(2);\r\n}\r\n\r\ntype BaseSyncMessage<TEntry, TAction extends string> = {\r\n entry: TEntry;\r\n action: TAction;\r\n};\r\n\r\ntype InvalidateMessage<T> = BaseSyncMessage<\r\n Pick<CacheEntry<T>, 'key'>,\r\n 'invalidate'\r\n>;\r\n\r\ntype StoreMessage<T> = BaseSyncMessage<Omit<CacheEntry<T>, 'timeout'>, 'store'>;\r\n\r\ntype InternalSyncMessage<T> = InvalidateMessage<T> | StoreMessage<T>;\r\n\r\n/**\r\n * A message type used for synchronizing cache updates across tabs.\r\n * @internal\r\n * @template T - The type of data being cached.\r\n */\r\ntype SyncMessage<T> = InternalSyncMessage<T> & {\r\n cacheId: string;\r\n type: 'cache-sync-message';\r\n};\r\n\r\nfunction isSyncMessage<T>(msg: unknown): msg is SyncMessage<T> {\r\n return (\r\n typeof msg === 'object' &&\r\n msg !== null &&\r\n 'type' in msg &&\r\n (msg as SyncMessage<T>).type === 'cache-sync-message'\r\n );\r\n}\r\n\r\n/**\r\n * Options for configuring the Least Recently Used (LRU) cache cleanup strategy.\r\n * @internal\r\n */\r\ntype LRUCleanupType = {\r\n type: 'lru';\r\n /**\r\n * How often to check for expired or excess entries, in milliseconds.\r\n */\r\n checkInterval: number;\r\n /**\r\n * The maximum number of entries to keep in the cache. When the cache exceeds this size,\r\n * the least recently used entries will be removed.\r\n */\r\n maxSize: number;\r\n};\r\n\r\n/**\r\n * Options for configuring the \"oldest first\" cache cleanup strategy.\r\n * @internal\r\n */\r\ntype OldsetCleanupType = {\r\n type: 'oldest';\r\n /**\r\n * How often to check for expired or excess entries, in milliseconds.\r\n */\r\n checkInterval: number;\r\n /**\r\n * The maximum number of entries to keep in the cache. When the cache exceeds this size,\r\n * the oldest entries will be removed.\r\n */\r\n maxSize: number;\r\n};\r\n\r\n/**\r\n * Represents an entry in the cache.\r\n * @internal\r\n */\r\nexport type CacheEntry<T> = {\r\n value: T;\r\n created: number;\r\n updated: number;\r\n stale: number;\r\n useCount: number;\r\n expiresAt: number;\r\n timeout: ReturnType<typeof setTimeout>;\r\n key: string;\r\n};\r\n\r\n/**\r\n * Defines the types of cleanup strategies available for the cache.\r\n * - `lru`: Least Recently Used. Removes the least recently accessed entries when the cache is full.\r\n * - `oldest`: Removes the oldest entries when the cache is full.\r\n */\r\nexport type CleanupType = LRUCleanupType | OldsetCleanupType;\r\n\r\nconst ONE_DAY = 1000 * 60 * 60 * 24;\r\nconst ONE_HOUR = 1000 * 60 * 60;\r\n\r\nconst DEFAULT_CLEANUP_OPT = {\r\n type: 'lru',\r\n maxSize: 200,\r\n checkInterval: ONE_HOUR,\r\n} satisfies LRUCleanupType;\r\n\r\n/**\r\n * A generic cache implementation that stores data with time-to-live (TTL) and stale-while-revalidate capabilities.\r\n *\r\n * @typeParam T - The type of data to be stored in the cache.\r\n */\r\nexport class Cache<T> {\r\n private readonly internal = mutable(new Map<string, CacheEntry<T>>());\r\n private readonly cleanupOpt: CleanupType;\r\n private readonly id = generateID();\r\n\r\n /**\r\n * Destroys the cache instance, cleaning up any resources used by the cache.\r\n * This method is called automatically when the cache instance is garbage collected.\r\n */\r\n readonly destroy: () => void;\r\n\r\n private readonly broadcast: (msg: InternalSyncMessage<T>) => void = () => {\r\n // noop\r\n };\r\n\r\n /**\r\n * Creates a new `Cache` instance.\r\n *\r\n * @param ttl - The default Time To Live (TTL) for cache entries, in milliseconds. Defaults to one day.\r\n * @param staleTime - The default duration, in milliseconds, during which a cache entry is considered\r\n * stale but can still be used while revalidation occurs in the background. Defaults to 1 hour.\r\n * @param cleanupOpt - Options for configuring the cache cleanup strategy. Defaults to LRU with a\r\n * `maxSize` of 200 and a `checkInterval` of one hour.\r\n * @param syncTabs - If provided, the cache will use the options a BroadcastChannel to send updates between tabs.\r\n * Defaults to `undefined`, meaning no synchronization across tabs.\r\n */\r\n constructor(\r\n protected readonly ttl: number = ONE_DAY,\r\n protected readonly staleTime: number = ONE_HOUR,\r\n cleanupOpt: Partial<CleanupType> = {\r\n type: 'lru',\r\n maxSize: 1000,\r\n checkInterval: ONE_HOUR,\r\n },\r\n syncTabs?: {\r\n id: string;\r\n serialize: (value: T) => string;\r\n deserialize: (value: string) => T | null;\r\n },\r\n\r\n private readonly db: Promise<CacheDB<T>> = Promise.resolve(\r\n createNoopDB<T>(),\r\n ),\r\n ) {\r\n this.cleanupOpt = {\r\n ...DEFAULT_CLEANUP_OPT,\r\n ...cleanupOpt,\r\n };\r\n\r\n if (this.cleanupOpt.maxSize <= 0)\r\n throw new Error('maxSize must be greater than 0');\r\n\r\n // cleanup cache based on provided options regularly\r\n const cleanupInterval = setInterval(() => {\r\n this.cleanup();\r\n }, cleanupOpt.checkInterval);\r\n\r\n let destroySyncTabs = () => {\r\n // noop\r\n };\r\n\r\n if (syncTabs) {\r\n const channel = new BroadcastChannel(syncTabs.id);\r\n this.broadcast = (msg: InternalSyncMessage<T>) => {\r\n if (msg.action === 'invalidate')\r\n return channel.postMessage({\r\n action: 'invalidate',\r\n entry: { key: msg.entry.key },\r\n cacheId: this.id,\r\n type: 'cache-sync-message',\r\n } satisfies SyncMessage<string>);\r\n\r\n return channel.postMessage({\r\n ...msg,\r\n entry: {\r\n ...msg.entry,\r\n value: syncTabs.serialize(msg.entry.value),\r\n },\r\n cacheId: this.id,\r\n type: 'cache-sync-message',\r\n } satisfies SyncMessage<string>);\r\n };\r\n\r\n channel.onmessage = (event) => {\r\n const msg = event.data;\r\n if (!isSyncMessage<string>(msg)) return;\r\n if (msg.cacheId === this.id) return; // ignore messages from this cache\r\n\r\n if (msg.action === 'store') {\r\n const value = syncTabs.deserialize(msg.entry.value);\r\n if (value === null) return;\r\n this.storeInternal(\r\n msg.entry.key,\r\n value,\r\n msg.entry.stale - msg.entry.updated,\r\n msg.entry.expiresAt - msg.entry.updated,\r\n true,\r\n false,\r\n );\r\n } else if (msg.action === 'invalidate') {\r\n this.invalidateInternal(msg.entry.key, true);\r\n }\r\n };\r\n\r\n destroySyncTabs = () => {\r\n channel.close();\r\n };\r\n }\r\n\r\n let destroyed = false;\r\n const destroy = () => {\r\n if (destroyed) return;\r\n destroyed = true;\r\n clearInterval(cleanupInterval);\r\n destroySyncTabs();\r\n };\r\n\r\n this.db\r\n .then(async (db) => {\r\n if (destroyed) return [];\r\n return db.getAll();\r\n })\r\n .then((entries) => {\r\n if (destroyed) return;\r\n // load entries into the cache\r\n\r\n const current = untracked(this.internal);\r\n entries.forEach((entry) => {\r\n if (current.has(entry.key)) return;\r\n this.storeInternal(\r\n entry.key,\r\n entry.value,\r\n entry.stale - entry.updated,\r\n entry.expiresAt - entry.updated,\r\n true, // like from sync because we dont want to trigger sync or db writes\r\n );\r\n });\r\n });\r\n\r\n this.destroy = destroy;\r\n\r\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\r\n const registry = new FinalizationRegistry((id: string) => {\r\n if (id === this.id) {\r\n destroy();\r\n }\r\n });\r\n\r\n registry.register(this, this.id);\r\n }\r\n\r\n /** @internal */\r\n private getInternal(\r\n key: () => string | null,\r\n ): Signal<(CacheEntry<T> & { isStale: boolean }) | null> {\r\n const keySignal = computed(() => key());\r\n\r\n return computed(() => {\r\n const key = keySignal();\r\n if (!key) return null;\r\n const found = this.internal().get(key);\r\n\r\n const now = Date.now();\r\n\r\n if (!found || found.expiresAt <= now) return null;\r\n found.useCount++;\r\n return {\r\n ...found,\r\n isStale: found.stale <= now,\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Retrieves a cache entry without affecting its usage count (for LRU). This is primarily\r\n * for internal use or debugging.\r\n * @internal\r\n * @param key - The key of the entry to retrieve.\r\n * @returns The cache entry, or `null` if not found or expired.\r\n */\r\n getUntracked(key: string): (CacheEntry<T> & { isStale: boolean }) | null {\r\n return untracked(this.getInternal(() => key));\r\n }\r\n\r\n /**\r\n * Retrieves a cache entry as a signal.\r\n *\r\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.\r\n * @returns A signal that holds the cache entry, or `null` if not found or expired. The signal\r\n * updates whenever the cache entry changes (e.g., due to revalidation or expiration).\r\n */\r\n get(\r\n key: () => string | null,\r\n ): Signal<(CacheEntry<T> & { isStale: boolean }) | null> {\r\n return this.getInternal(key);\r\n }\r\n\r\n /**\r\n * Retrieves a cache entry or an object with the key if not found.\r\n *\r\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.\r\n * @returns A signal that holds the cache entry or an object with the key if not found. The signal\r\n * updates whenever the cache entry changes (e.g., due to revalidation or expiration).\r\n */\r\n getEntryOrKey(\r\n key: () => string | null,\r\n ): Signal<(CacheEntry<T> & { isStale: boolean }) | string | null> {\r\n const valueSig = this.getInternal(key);\r\n return computed(() => valueSig() ?? key());\r\n }\r\n\r\n /**\r\n * Stores a value in the cache.\r\n *\r\n * @param key - The key under which to store the value.\r\n * @param value - The value to store.\r\n * @param staleTime - (Optional) The stale time for this entry, in milliseconds. Overrides the default `staleTime`.\r\n * @param ttl - (Optional) The TTL for this entry, in milliseconds. Overrides the default `ttl`.\r\n */\r\n store(\r\n key: string,\r\n value: T,\r\n staleTime = this.staleTime,\r\n ttl = this.ttl,\r\n persist = false,\r\n ) {\r\n this.storeInternal(key, value, staleTime, ttl, false, persist);\r\n }\r\n\r\n private storeInternal(\r\n key: string,\r\n value: T,\r\n staleTime = this.staleTime,\r\n ttl = this.ttl,\r\n fromSync = false,\r\n persist = false,\r\n ) {\r\n const entry = this.getUntracked(key);\r\n if (entry) {\r\n clearTimeout(entry.timeout); // stop invalidation\r\n }\r\n\r\n const prevCount = entry?.useCount ?? 0;\r\n\r\n // ttl cannot be less than staleTime\r\n if (ttl < staleTime) staleTime = ttl;\r\n\r\n const now = Date.now();\r\n\r\n const next: Omit<CacheEntry<T>, 'timeout'> = {\r\n value,\r\n created: entry?.created ?? now,\r\n updated: now,\r\n useCount: prevCount + 1,\r\n stale: now + staleTime,\r\n expiresAt: now + ttl,\r\n key,\r\n };\r\n\r\n this.internal.mutate((map) => {\r\n map.set(key, {\r\n ...next,\r\n timeout: setTimeout(() => this.invalidate(key), ttl),\r\n });\r\n return map;\r\n });\r\n\r\n if (!fromSync) {\r\n if (persist) this.db.then((db) => db.store(next));\r\n\r\n this.broadcast({\r\n action: 'store',\r\n entry: next,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Invalidates (removes) a cache entry.\r\n *\r\n * @param key - The key of the entry to invalidate.\r\n */\r\n invalidate(key: string) {\r\n this.invalidateInternal(key);\r\n }\r\n\r\n private invalidateInternal(key: string, fromSync = false) {\r\n const entry = this.getUntracked(key);\r\n if (!entry) return;\r\n clearTimeout(entry.timeout);\r\n this.internal.mutate((map) => {\r\n map.delete(key);\r\n return map;\r\n });\r\n if (!fromSync) {\r\n this.db.then((db) => db.remove(key));\r\n this.broadcast({ action: 'invalidate', entry: { key } });\r\n }\r\n }\r\n\r\n /** @internal */\r\n private cleanup() {\r\n if (untracked(this.internal).size <= this.cleanupOpt.maxSize) return;\r\n\r\n const sorted = Array.from(untracked(this.internal).entries()).toSorted(\r\n (a, b) => {\r\n if (this.cleanupOpt.type === 'lru') {\r\n return a[1].useCount - b[1].useCount; // least used first\r\n } else {\r\n return a[1].created - b[1].created; // oldest first\r\n }\r\n },\r\n );\r\n\r\n const keepCount = Math.floor(this.cleanupOpt.maxSize / 2);\r\n\r\n const removed = sorted.slice(0, sorted.length - keepCount);\r\n const keep = sorted.slice(removed.length, sorted.length);\r\n\r\n removed.forEach(([, e]) => {\r\n clearTimeout(e.timeout);\r\n });\r\n\r\n this.internal.set(new Map(keep));\r\n }\r\n}\r\n\r\n/**\r\n * Options for configuring the cache.\r\n */\r\ntype CacheOptions = {\r\n /**\r\n * The default Time To Live (TTL) for cache entries, in milliseconds.\r\n */\r\n ttl?: number;\r\n /**\r\n * The default duration, in milliseconds, during which a cache entry is considered\r\n * stale but can still be used while revalidation occurs in the background.\r\n */\r\n staleTime?: number;\r\n /**\r\n * Options for configuring the cache cleanup strategy.\r\n */\r\n cleanup?: Partial<CleanupType>;\r\n /**\r\n * Whether to synchronize cache across tabs. If true, the cache will use a BroadcastChannel to send updates between tabs.\r\n */\r\n syncTabs?: boolean;\r\n /**\r\n * Globally disable persistence of cache entries.\r\n * If set to `false`, cache entries will not be persisted to the database.\r\n * `true` means, cache entries can be persisted, they must still be opted into on the resource level & allowed by server headers.\r\n * @default true\r\n */\r\n persist?: boolean;\r\n /**\r\n * Version of the caches database, increment this if the interfaces change, this will cause the old data to be deleted.\r\n * Minimum value is 1, so first increment should be 2.\r\n * @default 1\r\n */\r\n version?: number;\r\n};\r\n\r\nconst CLIENT_CACHE_TOKEN = new InjectionToken<Cache<HttpResponse<unknown>>>(\r\n 'INTERNAL_CLIENT_CACHE',\r\n);\r\n\r\n/**\r\n * Provides the instance of the QueryCache for queryResource. This should probably be called\r\n * in your application's root configuration, but can also be overriden with component/module providers.\r\n *\r\n * @param options - Optional configuration options for the cache.\r\n * @returns An Angular `Provider` for the cache.\r\n *\r\n * @example\r\n * // In your app.config.ts or AppModule providers:\r\n *\r\n * import { provideQueryCache } from './your-cache';\r\n *\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideQueryCache({\r\n * ttl: 60000, // Default TTL of 60 seconds\r\n * staleTime: 30000, // Default staleTime of 30 seconds\r\n * }),\r\n * // ... other providers\r\n * ]\r\n * };\r\n */\r\nexport function provideQueryCache(opt?: CacheOptions): Provider {\r\n const serialize = (value: HttpResponse<unknown>) => {\r\n const headersRecord: Record<string, string[]> = {};\r\n\r\n const headerKeys = value.headers.keys();\r\n headerKeys.forEach((key) => {\r\n const values = value.headers.getAll(key);\r\n if (!values) return;\r\n headersRecord[key] = values;\r\n });\r\n\r\n return JSON.stringify({\r\n body: value.body,\r\n status: value.status,\r\n statusText: value.statusText,\r\n headers: headerKeys.length > 0 ? headersRecord : undefined,\r\n url: value.url,\r\n });\r\n };\r\n\r\n const deserialize = (value: string) => {\r\n try {\r\n const parsed = JSON.parse(value);\r\n\r\n if (!parsed || typeof parsed !== 'object' || !('body' in parsed))\r\n throw new Error('Invalid cache entry format');\r\n\r\n const headers = parsed.headers\r\n ? new HttpHeaders(parsed.headers)\r\n : undefined;\r\n\r\n return new HttpResponse({\r\n body: parsed.body,\r\n status: parsed.status,\r\n statusText: parsed.statusText,\r\n headers: headers,\r\n url: parsed.url,\r\n });\r\n } catch (err) {\r\n if (isDevMode()) console.error('Failed to deserialize cache entry:', err);\r\n return null;\r\n }\r\n };\r\n\r\n const syncTabsOpt = opt?.syncTabs\r\n ? {\r\n id: 'mmstack-query-cache-sync',\r\n serialize,\r\n deserialize,\r\n }\r\n : undefined;\r\n\r\n const db =\r\n opt?.persist === false\r\n ? undefined\r\n : createSingleStoreDB<string>(\r\n 'mmstack-query-cache-db',\r\n (version) => `query-store_v${version}`,\r\n opt?.version,\r\n ).then((db): CacheDB<HttpResponse<unknown>> => {\r\n return {\r\n getAll: () => {\r\n return db.getAll().then((entries) => {\r\n return entries\r\n .map((entry) => {\r\n const value = deserialize(entry.value);\r\n if (value === null) return null;\r\n return {\r\n ...entry,\r\n value,\r\n };\r\n })\r\n .filter((e) => e !== null);\r\n });\r\n },\r\n store: (entry) => {\r\n return db.store({ ...entry, value: serialize(entry.value) });\r\n },\r\n remove: db.remove,\r\n };\r\n });\r\n\r\n return {\r\n provide: CLIENT_CACHE_TOKEN,\r\n useValue: new Cache(\r\n opt?.ttl,\r\n opt?.staleTime,\r\n opt?.cleanup,\r\n syncTabsOpt,\r\n db,\r\n ),\r\n };\r\n}\r\n\r\nclass NoopCache<T> extends Cache<T> {\r\n override store(_: string, __: T, ___ = super.staleTime, ____ = super.ttl) {\r\n // noop\r\n }\r\n}\r\n\r\n/**\r\n * Injects the `QueryCache` instance that is used within queryResource.\r\n * Allows for direct modification of cached data, but is mostly meant for internal use.\r\n *\r\n * @param injector - (Optional) The injector to use. If not provided, the current\r\n * injection context is used.\r\n * @returns The `QueryCache` instance.\r\n *\r\n * @example\r\n * // In your component or service:\r\n *\r\n * import { injectQueryCache } from './your-cache';\r\n *\r\n * constructor() {\r\n * const cache = injectQueryCache();\r\n *\r\n * const myData = cache.get(() => 'my-data-key');\r\n * if (myData() !== null) {\r\n * // ... use cached data ...\r\n * }\r\n * }\r\n */\r\nexport function injectQueryCache<TRaw = unknown>(\r\n injector?: Injector,\r\n): Cache<HttpResponse<TRaw>> {\r\n const cache = injector\r\n ? injector.get(CLIENT_CACHE_TOKEN, null, {\r\n optional: true,\r\n })\r\n : inject(CLIENT_CACHE_TOKEN, {\r\n optional: true,\r\n });\r\n\r\n if (!cache) {\r\n if (isDevMode())\r\n throw new Error(\r\n 'Cache not provided, please add provideQueryCache() to providers array',\r\n );\r\n else return new NoopCache();\r\n }\r\n\r\n return cache as Cache<HttpResponse<TRaw>>;\r\n}\r\n","import {\r\n HttpContext,\r\n HttpContextToken,\r\n type HttpEvent,\r\n type HttpHandlerFn,\r\n type HttpInterceptorFn,\r\n type HttpRequest,\r\n HttpResponse,\r\n} from '@angular/common/http';\r\nimport { map, Observable, of, tap } from 'rxjs';\r\nimport { injectQueryCache } from './cache';\r\n\r\ntype CacheEntryOptions = {\r\n key?: string;\r\n ttl?: number;\r\n staleTime?: number;\r\n cache: boolean;\r\n bustBrowserCache?: boolean;\r\n ignoreCacheControl?: boolean;\r\n parse?: (val: unknown) => unknown;\r\n persist?: boolean;\r\n};\r\n\r\nconst CACHE_CONTEXT = new HttpContextToken<CacheEntryOptions>(() => ({\r\n cache: false,\r\n}));\r\n\r\nexport function setCacheContext(\r\n ctx = new HttpContext(),\r\n opt: Omit<CacheEntryOptions, 'cache' | 'key'> & {\r\n key: Required<CacheEntryOptions>['key'];\r\n },\r\n) {\r\n return ctx.set(CACHE_CONTEXT, { ...opt, cache: true });\r\n}\r\n\r\nfunction getCacheContext(ctx: HttpContext): CacheEntryOptions {\r\n return ctx.get(CACHE_CONTEXT);\r\n}\r\n\r\ntype ResolvedCacheControl = {\r\n noStore: boolean;\r\n noCache: boolean;\r\n mustRevalidate: boolean;\r\n immutable: boolean;\r\n maxAge: number | null;\r\n staleWhileRevalidate: number | null;\r\n};\r\n\r\nfunction parseCacheControlHeader(\r\n req: HttpResponse<unknown>,\r\n): ResolvedCacheControl {\r\n const header = req.headers.get('Cache-Control');\r\n\r\n let sMaxAge: number | null = null;\r\n const directives: ResolvedCacheControl = {\r\n noStore: false,\r\n noCache: false,\r\n mustRevalidate: false,\r\n immutable: false,\r\n maxAge: null,\r\n staleWhileRevalidate: null,\r\n };\r\n\r\n if (!header) return directives;\r\n\r\n const parts = header.split(',');\r\n\r\n for (const part of parts) {\r\n const [unparsedKey, value] = part.trim().split('=');\r\n const key = unparsedKey.trim().toLowerCase();\r\n\r\n switch (key) {\r\n case 'no-store':\r\n directives.noStore = true;\r\n break;\r\n case 'no-cache':\r\n directives.noCache = true;\r\n break;\r\n case 'must-revalidate':\r\n case 'proxy-revalidate':\r\n directives.mustRevalidate = true;\r\n break;\r\n case 'immutable':\r\n directives.immutable = true;\r\n break;\r\n case 'max-age': {\r\n if (!value) break;\r\n const parsedValue = parseInt(value, 10);\r\n if (!isNaN(parsedValue)) directives.maxAge = parsedValue;\r\n break;\r\n }\r\n case 's-max-age': {\r\n if (!value) break;\r\n const parsedValue = parseInt(value, 10);\r\n if (!isNaN(parsedValue)) sMaxAge = parsedValue;\r\n break;\r\n }\r\n case 'stale-while-revalidate': {\r\n if (!value) break;\r\n const parsedValue = parseInt(value, 10);\r\n if (!isNaN(parsedValue)) directives.staleWhileRevalidate = parsedValue;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // s-max-age takes precedence over max-age\r\n if (sMaxAge !== null) directives.maxAge = sMaxAge;\r\n\r\n // if no store nothing else is relevant\r\n if (directives.noStore)\r\n return {\r\n noStore: true,\r\n noCache: false,\r\n mustRevalidate: false,\r\n immutable: false,\r\n maxAge: null,\r\n staleWhileRevalidate: null,\r\n };\r\n\r\n // max age does not apply to immutable resources\r\n if (directives.immutable)\r\n return {\r\n ...directives,\r\n maxAge: null,\r\n };\r\n\r\n return directives;\r\n}\r\n\r\nfunction resolveTimings(\r\n cacheControl: ResolvedCacheControl,\r\n optStaleTime?: number,\r\n optTTL?: number,\r\n): { staleTime?: number; ttl?: number } {\r\n let staleTime = optStaleTime;\r\n let ttl = optTTL;\r\n\r\n if (cacheControl.immutable)\r\n return {\r\n staleTime: Infinity,\r\n ttl: Infinity,\r\n };\r\n\r\n if (cacheControl.maxAge !== null) ttl = cacheControl.maxAge * 1000;\r\n\r\n if (cacheControl.staleWhileRevalidate !== null)\r\n staleTime = cacheControl.staleWhileRevalidate * 1000;\r\n\r\n // if no-cache is set, we must always revalidate\r\n if (cacheControl.noCache || cacheControl.mustRevalidate) staleTime = 0;\r\n\r\n if (ttl !== undefined && staleTime !== undefined && ttl < staleTime) {\r\n staleTime = ttl;\r\n }\r\n\r\n return { staleTime, ttl };\r\n}\r\n\r\n/**\r\n * Creates an `HttpInterceptorFn` that implements caching for HTTP requests. This interceptor\r\n * checks for a caching configuration in the request's `HttpContext` (internally set by the queryResource).\r\n * If caching is enabled, it attempts to retrieve responses from the cache. If a cached response\r\n * is found and is not stale, it's returned directly. If the cached response is stale, it's returned,\r\n * and a background revalidation request is made. If no cached response is found, the request\r\n * is made to the server, and the response is cached according to the configured TTL and staleness.\r\n * The interceptor also respects `Cache-Control` headers from the server.\r\n *\r\n * @param allowedMethods - An array of HTTP methods for which caching should be enabled.\r\n * Defaults to `['GET', 'HEAD', 'OPTIONS']`.\r\n *\r\n * @returns An `HttpInterceptorFn` that implements the caching logic.\r\n *\r\n * @example\r\n * // In your app.config.ts or module providers:\r\n *\r\n * import { provideHttpClient, withInterceptors } from '@angular/common/http';\r\n * import { createCacheInterceptor } from '@mmstack/resource';\r\n *\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideHttpClient(withInterceptors([createCacheInterceptor()])),\r\n * // ... other providers\r\n * ],\r\n * };\r\n */\r\nexport function createCacheInterceptor(\r\n allowedMethods = ['GET', 'HEAD', 'OPTIONS'],\r\n): HttpInterceptorFn {\r\n const CACHE_METHODS = new Set<string>(allowedMethods);\r\n\r\n return (\r\n req: HttpRequest<unknown>,\r\n next: HttpHandlerFn,\r\n ): Observable<HttpEvent<unknown>> => {\r\n const cache = injectQueryCache();\r\n\r\n if (!CACHE_METHODS.has(req.method)) return next(req);\r\n const opt = getCacheContext(req.context);\r\n\r\n if (!opt.cache) return next(req);\r\n\r\n const key = opt.key ?? req.urlWithParams;\r\n const entry = cache.getUntracked(key); // null if expired or not found\r\n\r\n // If the entry is not stale, return it\r\n if (entry && !entry.isStale) return of(entry.value);\r\n\r\n // resource itself handles case of showing stale data...the request must process as this will \"refresh said data\"\r\n\r\n const eTag = entry?.value.headers.get('ETag');\r\n const lastModified = entry?.value.headers.get('Last-Modified');\r\n\r\n if (eTag) {\r\n req = req.clone({ setHeaders: { 'If-None-Match': eTag } });\r\n }\r\n\r\n if (lastModified) {\r\n req = req.clone({ setHeaders: { 'If-Modified-Since': lastModified } });\r\n }\r\n\r\n if (opt.bustBrowserCache) {\r\n req = req.clone({\r\n setParams: { _cb: Date.now().toString() },\r\n });\r\n }\r\n\r\n return next(req).pipe(\r\n tap((event) => {\r\n if (event instanceof HttpResponse && event.ok) {\r\n const cacheControl = parseCacheControlHeader(event);\r\n\r\n if (cacheControl.noStore && !opt.ignoreCacheControl) return;\r\n\r\n const { staleTime, ttl } = opt.ignoreCacheControl\r\n ? opt\r\n : resolveTimings(cacheControl, opt.staleTime, opt.ttl);\r\n\r\n if (opt.ttl === 0) return; // no point\r\n\r\n const parsedResponse = opt.parse\r\n ? new HttpResponse({\r\n body: opt.parse(event.body),\r\n headers: event.headers,\r\n status: event.status,\r\n statusText: event.statusText,\r\n url: event.url ?? undefined,\r\n })\r\n : event;\r\n\r\n cache.store(key, parsedResponse, staleTime, ttl, opt.persist);\r\n }\r\n }),\r\n map((event) => {\r\n // handle 304 responses due to eTag/last-modified\r\n if (event instanceof HttpResponse && event.status === 304 && entry) {\r\n return entry.value;\r\n }\r\n\r\n return event;\r\n }),\r\n );\r\n };\r\n}\r\n","import { HttpResourceRef } from '@angular/common/http';\r\nimport { computed } from '@angular/core';\r\nimport { toWritable } from '@mmstack/primitives';\r\n\r\nexport function catchValueError<T>(\r\n resource: HttpResourceRef<T>,\r\n fallback: T,\r\n): HttpResourceRef<T> {\r\n return {\r\n ...resource,\r\n value: toWritable(\r\n computed(() => {\r\n try {\r\n return resource.value();\r\n } catch {\r\n return fallback;\r\n }\r\n }),\r\n (value) => resource.value.set(value),\r\n ),\r\n };\r\n}\r\n","import {\r\n computed,\r\n effect,\r\n inject,\r\n InjectionToken,\r\n Injector,\r\n Provider,\r\n Signal,\r\n signal,\r\n untracked,\r\n} from '@angular/core';\r\n\r\n/**\r\n * Represents the possible states of a circuit breaker.\r\n * - `CLOSED`: The circuit breaker is closed, and operations are allowed to proceed.\r\n * - `OPEN`: The circuit breaker is open, and operations are blocked.\r\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.\r\n */\r\ntype CircuitBreakerState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';\r\n\r\n/**\r\n * Represents a circuit breaker, which monitors operations and prevents failures from cascading.\r\n */\r\nexport type CircuitBreaker = {\r\n /**\r\n * A signal indicating whether the circuit breaker is currently closed (allowing operations).\r\n */\r\n isClosed: Signal<boolean>;\r\n /**\r\n * A signal indicating whether the circuit breaker is either open or in a half-open state.\r\n * This is useful for checking if operations are blocked.\r\n * If the circuit breaker is open, operations should not proceed.\r\n */\r\n isOpen: Signal<boolean>;\r\n /**\r\n * A signal representing the current state of the circuit breaker.\r\n */\r\n status: Signal<CircuitBreakerState>;\r\n /**\r\n * Signals a failure to the circuit breaker. This may cause the circuit breaker to open.\r\n */\r\n fail: (err?: Error) => void;\r\n /**\r\n * Signals a success to the circuit breaker. This may cause the circuit breaker to close.\r\n */\r\n success: () => void;\r\n /**\r\n * Attempts to transition the circuit breaker to the half-open state. This is typically used\r\n * to test if the underlying issue has been resolved after the circuit breaker has been open.\r\n */\r\n halfOpen: () => void;\r\n /**\r\n * Destroys the circuit breaker & initiates related cleanup\r\n */\r\n destroy: () => void;\r\n};\r\n\r\n/**\r\n * Options for creating a circuit breaker.\r\n */\r\ntype CreateCircuitBreakerOptions = {\r\n /**\r\n * The number of failures that will cause the circuit breaker to open.\r\n * @default 5\r\n */\r\n treshold?: number;\r\n /**\r\n * The time in milliseconds after which the circuit breaker will reset and allow operations to proceed again.\r\n * @default 30000 (30 seconds)\r\n */\r\n timeout?: number;\r\n /**\r\n * A function that determines whether an error should cause the circuit breaker to increment the failure count.\r\n * @default Always returns true\r\n */\r\n shouldFail?: (err?: Error) => boolean;\r\n /**\r\n * A function that determines whether an error should cause the circuit breaker to be open forever.\r\n * @default Always returns false\r\n */\r\n shouldFailForever?: (err?: Error) => boolean;\r\n};\r\n\r\n/**\r\n * Options for creating a circuit breaker.\r\n * - `false`: Disables circuit breaker functionality (always open).\r\n * - true: Creates a new circuit breaker with default options.\r\n * - `CircuitBreaker`: Provides an existing `CircuitBreaker` instance to use.\r\n * - `{ treshold?: number; timeout?: number; }`: Creates a new circuit breaker with the specified options.\r\n */\r\nexport type CircuitBreakerOptions =\r\n | false\r\n | CircuitBreaker\r\n | CreateCircuitBreakerOptions;\r\n\r\n/** @internal */\r\nconst DEFAULT_OPTIONS: Required<CreateCircuitBreakerOptions> = {\r\n treshold: 5,\r\n timeout: 30000,\r\n shouldFail: () => true,\r\n shouldFailForever: () => false,\r\n};\r\n\r\n/** @internal */\r\nfunction internalCeateCircuitBreaker(\r\n treshold = 5,\r\n resetTimeout = 30000,\r\n shouldFail: (err?: Error) => boolean = () => true,\r\n shouldFailForever: (err?: Error) => boolean = () => false,\r\n): CircuitBreaker {\r\n const halfOpen = signal(false);\r\n const failureCount = signal(0);\r\n\r\n const status = computed<CircuitBreakerState>(() => {\r\n if (failureCount() >= treshold) return 'OPEN';\r\n return halfOpen() ? 'HALF_OPEN' : 'CLOSED';\r\n });\r\n\r\n const isClosed = computed(() => status() !== 'OPEN');\r\n const isOpen = computed(() => status() !== 'CLOSED');\r\n\r\n const success = () => {\r\n failureCount.set(0);\r\n halfOpen.set(false);\r\n };\r\n\r\n const tryOnce = () => {\r\n if (!untracked(isOpen)) return;\r\n halfOpen.set(true);\r\n failureCount.set(treshold - 1);\r\n };\r\n\r\n let failForeverResetId: ReturnType<typeof setTimeout> | null = null;\r\n const effectRef = effect((cleanup) => {\r\n if (!isOpen()) return;\r\n\r\n const timeout = setTimeout(tryOnce, resetTimeout);\r\n failForeverResetId = timeout;\r\n return cleanup(() => {\r\n clearTimeout(timeout);\r\n failForeverResetId = null;\r\n });\r\n });\r\n\r\n const failInternal = () => {\r\n failureCount.set(failureCount() + 1);\r\n halfOpen.set(false);\r\n };\r\n\r\n const failForever = () => {\r\n if (failForeverResetId) clearTimeout(failForeverResetId);\r\n effectRef.destroy();\r\n failureCount.set(Infinity);\r\n halfOpen.set(false);\r\n return;\r\n };\r\n\r\n const fail = (err?: Error) => {\r\n if (shouldFailForever(err)) return failForever();\r\n if (shouldFail(err)) return failInternal();\r\n // If the error does not trigger a failure, we do nothing.\r\n };\r\n\r\n return {\r\n status,\r\n isClosed,\r\n isOpen,\r\n fail,\r\n success,\r\n halfOpen: tryOnce,\r\n destroy: () => effectRef.destroy(),\r\n };\r\n}\r\n\r\n/** @internal */\r\nfunction createNeverBrokenCircuitBreaker(): CircuitBreaker {\r\n return {\r\n isClosed: computed(() => true),\r\n isOpen: computed(() => false),\r\n status: signal('CLOSED'),\r\n fail: () => {\r\n // noop\r\n },\r\n success: () => {\r\n // noop\r\n },\r\n halfOpen: () => {\r\n // noop\r\n },\r\n destroy: () => {\r\n // noop\r\n },\r\n };\r\n}\r\n\r\nconst CB_DEFAULT_OPTIONS = new InjectionToken<\r\n Required<CreateCircuitBreakerOptions>\r\n>('MMSTACK_CIRCUIT_BREAKER_DEFAULT_OPTIONS');\r\n\r\nexport function provideCircuitBreakerDefaultOptions(\r\n options: CircuitBreakerOptions,\r\n): Provider {\r\n return {\r\n provide: CB_DEFAULT_OPTIONS,\r\n useValue: {\r\n ...DEFAULT_OPTIONS,\r\n ...options,\r\n },\r\n };\r\n}\r\n\r\nfunction injectCircuitBreakerOptions(\r\n injector = inject(Injector),\r\n): Required<CreateCircuitBreakerOptions> {\r\n return injector.get(CB_DEFAULT_OPTIONS, DEFAULT_OPTIONS, {\r\n optional: true,\r\n });\r\n}\r\n\r\n/**\r\n * Creates a circuit breaker instance.\r\n *\r\n * @param options - Configuration options for the circuit breaker. Can be:\r\n * - `undefined`: Creates a \"no-op\" circuit breaker that is always open (never trips).\r\n * - `true`: Creates a circuit breaker with default settings (threshold: 5, timeout: 30000ms).\r\n * - `CircuitBreaker`: Reuses an existing `CircuitBreaker` instance.\r\n * - `{ threshold?: number; timeout?: number; }`: Creates a circuit breaker with the specified threshold and timeout.\r\n *\r\n * @returns A `CircuitBreaker` instance.\r\n *\r\n * @example\r\n * // Create a circuit breaker with default settings:\r\n * const breaker = createCircuitBreaker();\r\n *\r\n * // Create a circuit breaker with custom settings:\r\n * const customBreaker = createCircuitBreaker({ threshold: 10, timeout: 60000 });\r\n *\r\n * // Share a single circuit breaker instance across multiple resources:\r\n * const sharedBreaker = createCircuitBreaker();\r\n * const resource1 = queryResource(..., { circuitBreaker: sharedBreaker });\r\n * const resource2 = mutationResource(..., { circuitBreaker: sharedBreaker });\r\n */\r\nexport function createCircuitBreaker(\r\n opt?: CircuitBreakerOptions,\r\n injector?: Injector,\r\n): CircuitBreaker {\r\n if (opt === false) return createNeverBrokenCircuitBreaker();\r\n\r\n if (typeof opt === 'object' && 'isClosed' in opt) return opt;\r\n\r\n const { treshold, timeout, shouldFail, shouldFailForever } = {\r\n ...injectCircuitBreakerOptions(injector),\r\n ...opt,\r\n };\r\n\r\n return internalCeateCircuitBreaker(\r\n treshold,\r\n timeout,\r\n shouldFail,\r\n shouldFailForever,\r\n );\r\n}\r\n","// Heavily inspired by: https://dev.to/kasual1/request-deduplication-in-angular-3pd8\r\n\r\nimport {\r\n HttpContext,\r\n HttpContextToken,\r\n HttpInterceptorFn,\r\n type HttpEvent,\r\n type HttpHandlerFn,\r\n type HttpRequest,\r\n} from '@angular/common/http';\r\nimport { finalize, shareReplay, type Observable } from 'rxjs';\r\n\r\nconst NO_DEDUPE = new HttpContextToken<boolean>(() => false);\r\n\r\n/**\r\n * Disables request deduplication for a specific HTTP request.\r\n *\r\n * @param ctx - The `HttpContext` to modify. If not provided, a new `HttpContext` is created.\r\n * @returns The modified `HttpContext` with the `NO_DEDUPE` token set to `true`.\r\n *\r\n * @example\r\n * // Disable deduplication for a specific POST request:\r\n * const context = noDedupe();\r\n * this.http.post('/api/data', payload, { context }).subscribe(...);\r\n *\r\n * // Disable deduplication, modifying an existing context:\r\n * let context = new HttpContext();\r\n * context = noDedupe(context);\r\n * this.http.post('/api/data', payload, { context }).subscribe(...);\r\n */\r\nexport function noDedupe(ctx: HttpContext = new HttpContext()) {\r\n return ctx.set(NO_DEDUPE, true);\r\n}\r\n\r\n/**\r\n * Creates an `HttpInterceptorFn` that deduplicates identical HTTP requests.\r\n * If multiple identical requests (same URL and parameters) are made concurrently,\r\n * only the first request will be sent to the server. Subsequent requests will\r\n * receive the response from the first request.\r\n *\r\n * @param allowed - An array of HTTP methods for which deduplication should be enabled.\r\n * Defaults to `['GET', 'DELETE', 'HEAD', 'OPTIONS']`.\r\n *\r\n * @returns An `HttpInterceptorFn` that implements the request deduplication logic.\r\n *\r\n * @example\r\n * // In your app.config.ts or module providers:\r\n * import { provideHttpClient, withInterceptors } from '@angular/common/http';\r\n * import { createDedupeRequestsInterceptor } from './your-dedupe-interceptor';\r\n *\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideHttpClient(withInterceptors([createDedupeRequestsInterceptor()])),\r\n * // ... other providers\r\n * ],\r\n * };\r\n *\r\n * // You can also specify which methods should be deduped\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideHttpClient(withInterceptors([createDedupeRequestsInterceptor(['GET'])])), // only dedupe GET calls\r\n * // ... other providers\r\n * ],\r\n * };\r\n */\r\nexport function createDedupeRequestsInterceptor(\r\n allowed = ['GET', 'DELETE', 'HEAD', 'OPTIONS'],\r\n): HttpInterceptorFn {\r\n const inFlight = new Map<string, Observable<HttpEvent<unknown>>>();\r\n\r\n const DEDUPE_METHODS = new Set<string>(allowed);\r\n\r\n return (\r\n req: HttpRequest<unknown>,\r\n next: HttpHandlerFn,\r\n ): Observable<HttpEvent<unknown>> => {\r\n if (!DEDUPE_METHODS.has(req.method) || req.context.get(NO_DEDUPE))\r\n return next(req);\r\n\r\n const found = inFlight.get(req.urlWithParams);\r\n\r\n if (found) return found;\r\n\r\n const request = next(req).pipe(\r\n finalize(() => inFlight.delete(req.urlWithParams)),\r\n shareReplay(),\r\n );\r\n inFlight.set(req.urlWithParams, request);\r\n\r\n return request;\r\n };\r\n}\r\n","import {\r\n HttpContext,\r\n HttpHeaders,\r\n HttpParams,\r\n HttpResourceRequest,\r\n} from '@angular/common/http';\r\nimport { type ValueEqualityFn } from '@angular/core';\r\n\r\ntype UnknownObject = Record<PropertyKey, unknown>;\r\n\r\n/**\r\n * Checks if `value` is a plain JavaScript object (e.g., `{}` or `new Object()`).\r\n * Distinguishes from arrays, null, and class instances. Acts as a type predicate,\r\n * narrowing `value` to `UnknownObject` if `true`.\r\n *\r\n * @param value The value to check.\r\n * @returns {value is UnknownObject} `true` if `value` is a plain object, otherwise `false`.\r\n * @example\r\n * isPlainObject({}) // => true\r\n * isPlainObject([]) // => false\r\n * isPlainObject(null) // => false\r\n * isPlainObject(new Date()) // => false\r\n */\r\nfunction isPlainObject(value: unknown): value is UnknownObject {\r\n if (value === null || typeof value !== 'object') return false;\r\n const proto = Object.getPrototypeOf(value);\r\n if (proto === null) return false; // remove Object.create(null);\r\n return proto === Object.prototype;\r\n}\r\n\r\n/**\r\n * Internal helper to generate a stable JSON string from an array.\r\n * Sorts keys of plain objects within the array alphabetically before serialization\r\n * to ensure hash stability regardless of key order.\r\n *\r\n * @param queryKey The array of values to serialize.\r\n * @returns A stable JSON string representation.\r\n * @internal\r\n */\r\nfunction hashKey(queryKey: unknown[]): string {\r\n return JSON.stringify(queryKey, (_, val) =>\r\n isPlainObject(val)\r\n ? Object.keys(val)\r\n .toSorted()\r\n .reduce((result, key) => {\r\n result[key] = val[key];\r\n return result;\r\n }, {} as UnknownObject)\r\n : val,\r\n );\r\n}\r\n\r\n/**\r\n * Generates a stable, unique string hash from one or more arguments.\r\n * Useful for creating cache keys or identifiers where object key order shouldn't matter.\r\n *\r\n * How it works:\r\n * - Plain objects within the arguments have their keys sorted alphabetically before hashing.\r\n * This ensures that `{ a: 1, b: 2 }` and `{ b: 2, a: 1 }` produce the same hash.\r\n * - Uses `JSON.stringify` internally with custom sorting for plain objects via `hashKey`.\r\n * - Non-plain objects (arrays, Dates, etc.) and primitives are serialized naturally.\r\n *\r\n * @param {...unknown} args Values to include in the hash.\r\n * @returns A stable string hash representing the input arguments.\r\n * @example\r\n * const userQuery = (id: number) => ['user', { id, timestamp: Date.now() }];\r\n *\r\n * const obj1 = { a: 1, b: 2 };\r\n * const obj2 = { b: 2, a: 1 }; // Same keys/values, different order\r\n *\r\n * hash('posts', 10);\r\n * // => '[\"posts\",10]'\r\n *\r\n * hash('config', obj1);\r\n * // => '[\"config\",{\"a\":1,\"b\":2}]'\r\n *\r\n * hash('config', obj2);\r\n * // => '[\"config\",{\"a\":1,\"b\":2}]' (Same as above due to key sorting)\r\n *\r\n * hash(['todos', { status: 'done', owner: obj1 }]);\r\n * // => '[[\"todos\",{\"owner\":{\"a\":1,\"b\":2},\"status\":\"done\"}]]'\r\n *\r\n * // Be mindful of values JSON.stringify cannot handle (functions, undefined, Symbols)\r\n * // hash('a', undefined, function() {}) => '[\"a\",null,null]'\r\n */\r\nfunction hash(...args: unknown[]): string {\r\n return hashKey(args);\r\n}\r\n\r\nfunction equalTransferCache(\r\n a: HttpResourceRequest['transferCache'],\r\n b: HttpResourceRequest['transferCache'],\r\n): boolean {\r\n if (!a && !b) return true;\r\n if (!a || !b) return false;\r\n\r\n if (typeof a !== typeof b) return false;\r\n if (typeof a === 'boolean' || typeof b === 'boolean') return a === b;\r\n\r\n if (!a.includeHeaders && !b.includeHeaders) return true;\r\n if (!a.includeHeaders || !b.includeHeaders) return false;\r\n\r\n if (a.includeHeaders.length !== b.includeHeaders.length) return false;\r\n\r\n if (a.includeHeaders.length === 0) return true;\r\n\r\n const aSet = new Set(a.includeHeaders ?? []);\r\n\r\n return b.includeHeaders.every((header) => aSet.has(header));\r\n}\r\n\r\nfunction equalParamArray(\r\n a: Array<string | number | boolean>,\r\n b: Array<string | number | boolean>,\r\n): boolean {\r\n if (!a && !b) return true;\r\n if (!a || !b) return false;\r\n if (a.length !== b.length) return false;\r\n\r\n return a.every((value) => b.includes(value));\r\n}\r\n\r\nfunction headersToObject(headerClass: HttpHeaders) {\r\n const headers: Exclude<\r\n Required<HttpResourceRequest['headers']>,\r\n HttpHeaders | undefined\r\n > = {};\r\n\r\n headerClass.keys().forEach((key) => {\r\n const value = headerClass.getAll(key);\r\n if (value === null) return;\r\n if (value.length === 1) {\r\n headers[key] = value[0];\r\n } else {\r\n headers[key] = value;\r\n }\r\n });\r\n\r\n return headers;\r\n}\r\n\r\nfunction paramToObject(paramsClass: HttpParams) {\r\n const params: Exclude<\r\n Required<HttpResourceRequest['params']>,\r\n HttpParams | undefined\r\n > = {};\r\n\r\n paramsClass.keys().forEach((key) => {\r\n const value = paramsClass.getAll(key);\r\n if (value === null) return;\r\n if (value.length === 1) {\r\n params[key] = value[0];\r\n } else {\r\n params[key] = value;\r\n }\r\n });\r\n\r\n return params;\r\n}\r\n\r\nfunction equalParams(\r\n a: HttpResourceRequest['params'],\r\n b: HttpResourceRequest['params'],\r\n): boolean {\r\n if (!a && !b) return true;\r\n if (!a || !b) return false;\r\n\r\n const aObj = a instanceof HttpParams ? paramToObject(a) : a;\r\n const bObj = b instanceof HttpParams ? paramToObject(b) : b;\r\n\r\n const aKeys = Object.keys(aObj);\r\n const bKeys = Object.keys(bObj);\r\n if (aKeys.length !== bKeys.length) return false;\r\n\r\n return aKeys.every((key) => {\r\n if (Array.isArray(aObj[key]) || Array.isArray(bObj[key])) {\r\n return equalParamArray(\r\n Array.isArray(aObj[key]) ? aObj[key] : [aObj[key]],\r\n Array.isArray(bObj[key]) ? bObj[key] : [bObj[key]],\r\n );\r\n }\r\n\r\n return aObj[key] === bObj[key];\r\n });\r\n}\r\n\r\nfunction equalBody(\r\n a: HttpResourceRequest['body'],\r\n b: HttpResourceRequest['body'],\r\n): boolean {\r\n if (!a && !b) return true;\r\n if (!a || !b) return false;\r\n return hash(a) === hash(b);\r\n}\r\n\r\nfunction equalHeaders(\r\n a: HttpResourceRequest['headers'],\r\n b: HttpResourceRequest['headers'],\r\n): boolean {\r\n if (!a && !b) return true;\r\n if (!a || !b) return false;\r\n\r\n const aObj = a instanceof HttpHeaders ? headersToObject(a) : a;\r\n const bObj = b instanceof HttpHeaders ? headersToObject(b) : b;\r\n\r\n const aKeys = Object.keys(aObj);\r\n const bKeys = Object.keys(bObj);\r\n if (aKeys.length !== bKeys.length) return false;\r\n return aKeys.every((key) => {\r\n if (Array.isArray(aObj[key]) || Array.isArray(bObj[key])) {\r\n return equalParamArray(\r\n Array.isArray(aObj[key]) ? aObj[key] : [aObj[key]],\r\n Array.isArray(bObj[key]) ? bObj[key] : [bObj[key]],\r\n );\r\n }\r\n\r\n return aObj[key] === bObj[key];\r\n });\r\n}\r\n\r\nfunction toHttpContextEntries(ctx: HttpResourceRequest['context']) {\r\n if (!ctx) return [];\r\n\r\n if (ctx instanceof HttpContext) {\r\n const tokens = Array.from(ctx.keys());\r\n return tokens.map((key) => [key.toString(), ctx.get(key)] as const);\r\n }\r\n\r\n if (typeof ctx === 'object') {\r\n return Object.entries(ctx) as Array<[string, unknown]>;\r\n }\r\n\r\n return [];\r\n}\r\n\r\nfunction equalContext(\r\n a: HttpResourceRequest['context'],\r\n b: HttpResourceRequest['context'],\r\n): boolean {\r\n if (!a && !b) return true;\r\n if (!a || !b) return false;\r\n\r\n const aEntries = toHttpContextEntries(a);\r\n const bEntries = toHttpContextEntries(b);\r\n if (aEntries.length !== bEntries.length) return false;\r\n if (aEntries.length === 0) return true;\r\n const bMap = new Map(bEntries);\r\n return aEntries.every(([key, value]) => value === bMap.get(key));\r\n}\r\n\r\nexport function createEqualRequest<TResult>(\r\n equalResult?: ValueEqualityFn<TResult>,\r\n) {\r\n const eqb = equalResult ?? equalBody;\r\n\r\n return (\r\n a: Partial<HttpResourceRequest> | undefined,\r\n b: Partial<HttpResourceRequest> | undefined,\r\n ) => {\r\n if (!a && !b) return true;\r\n if (!a || !b) return false;\r\n\r\n if (a.url !== b.url) return false;\r\n if (a.method !== b.method) return false;\r\n if (!equalParams(a.params, b.params)) return false;\r\n if (!equalHeaders(a.headers, b.headers)) return false;\r\n if (!eqb(a.body as TResult, b.body as TResult)) return false;\r\n if (!equalContext(a.context, b.context)) return false;\r\n\r\n if (a.withCredentials !== b.withCredentials) return false;\r\n if (a.reportProgress !== b.reportProgress) return false;\r\n if (!equalTransferCache(a.transferCache, b.transferCache)) return false;\r\n\r\n return true;\r\n };\r\n}\r\n","export function hasSlowConnection() {\r\n if (\r\n window &&\r\n 'navigator' in window &&\r\n 'connection' in window.navigator &&\r\n typeof window.navigator.connection === 'object' &&\r\n !!window.navigator.connection &&\r\n 'effectiveType' in window.navigator.connection &&\r\n typeof window.navigator.connection.effectiveType === 'string'\r\n )\r\n return window.navigator.connection.effectiveType.endsWith('2g');\r\n\r\n return false;\r\n}\r\n","import { type HttpHeaders, type HttpResourceRef } from '@angular/common/http';\r\nimport {\r\n linkedSignal,\r\n type Signal,\r\n type ValueEqualityFn,\r\n type WritableSignal,\r\n} from '@angular/core';\r\n\r\nfunction persist<T>(\r\n value: WritableSignal<T>,\r\n equal?: ValueEqualityFn<T>,\r\n): WritableSignal<T>;\r\n\r\nfunction persist<T>(value: Signal<T>, equal?: ValueEqualityFn<T>): Signal<T>;\r\n\r\nfunction persist<T>(\r\n src: WritableSignal<T> | Signal<T>,\r\n equal?: ValueEqualityFn<T>,\r\n): WritableSignal<T> | Signal<T> {\r\n // linkedSignal allows us to access previous source value\r\n\r\n const persisted = linkedSignal<T, T>({\r\n source: () => src(),\r\n computation: (next, prev) => {\r\n if (next === undefined && prev !== undefined) return prev.value;\r\n return next;\r\n },\r\n equal,\r\n });\r\n\r\n // if original value was WritableSignal then override linkedSignal methods to original...angular uses linkedSignal under the hood in ResourceImpl, this applies to that.\r\n if ('set' in src) {\r\n persisted.set = src.set;\r\n persisted.update = src.update;\r\n persisted.asReadonly = src.asReadonly;\r\n }\r\n\r\n return persisted;\r\n}\r\n\r\nexport function persistResourceValues<T>(\r\n resource: HttpResourceRef<T>,\r\n shouldPersist = false,\r\n equal?: ValueEqualityFn<T>,\r\n): HttpResourceRef<T> {\r\n if (!shouldPersist) return resource;\r\n\r\n return {\r\n ...resource,\r\n statusCode: persist<number | undefined>(resource.statusCode),\r\n headers: persist<HttpHeaders | undefined>(resource.headers),\r\n value: persist<T>(resource.value, equal),\r\n };\r\n}\r\n","import { HttpResourceRef } from '@angular/common/http';\r\nimport { DestroyRef } from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { interval } from 'rxjs';\r\n\r\n// refresh resource every n miliseconds or don't refresh if undefined provided. 0 also excluded, due to it not being a valid usecase\r\nexport function refresh<T>(\r\n resource: HttpResourceRef<T>,\r\n destroyRef: DestroyRef,\r\n refresh?: number,\r\n): HttpResourceRef<T> {\r\n if (!refresh) return resource; // no refresh requested\r\n\r\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.\r\n let sub = interval(refresh)\r\n .pipe(takeUntilDestroyed(destroyRef))\r\n .subscribe(() => resource.reload());\r\n\r\n const reload = (): boolean => {\r\n sub.unsubscribe(); // do not conflict with manual reload\r\n\r\n const hasReloaded = resource.reload();\r\n\r\n // resubscribe after manual reload\r\n sub = interval(refresh)\r\n .pipe(takeUntilDestroyed(destroyRef))\r\n .subscribe(() => resource.reload());\r\n\r\n return hasReloaded;\r\n };\r\n\r\n return {\r\n ...resource,\r\n reload,\r\n destroy: () => {\r\n sub.unsubscribe();\r\n resource.destroy();\r\n },\r\n };\r\n}\r\n","import { type HttpResourceRef } from '@angular/common/http';\r\nimport { effect } from '@angular/core';\r\n\r\nexport type RetryOptions =\r\n | number\r\n | {\r\n max?: number;\r\n backoff?: number;\r\n };\r\n\r\n// Retry on error, if number is provided it will retry that many times with exponential backoff, otherwise it will use the options provided\r\nexport function retryOnError<T>(\r\n res: HttpResourceRef<T>,\r\n opt?: RetryOptions,\r\n): HttpResourceRef<T> {\r\n const max = opt ? (typeof opt === 'number' ? opt : (opt.max ?? 0)) : 0;\r\n const backoff = typeof opt === 'object' ? (opt.backoff ?? 1000) : 1000;\r\n\r\n let retries = 0;\r\n\r\n let timeout: ReturnType<typeof setTimeout> | undefined;\r\n\r\n const onError = () => {\r\n if (retries >= max) return;\r\n retries++;\r\n\r\n if (timeout) clearTimeout(timeout);\r\n\r\n setTimeout(\r\n () => res.reload(),\r\n retries <= 0 ? 0 : backoff * Math.pow(2, retries - 1),\r\n );\r\n };\r\n\r\n const onSuccess = () => {\r\n if (timeout) clearTimeout(timeout);\r\n retries = 0;\r\n };\r\n\r\n const ref = effect(() => {\r\n switch (res.status()) {\r\n case 'error':\r\n return onError();\r\n case 'resolved':\r\n return onSuccess();\r\n }\r\n });\r\n\r\n return {\r\n ...res,\r\n destroy: () => {\r\n ref.destroy(); // cleanup on manual destroy\r\n res.destroy();\r\n },\r\n };\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { sensor } from '@mmstack/primitives';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ResourceSensors {\r\n readonly networkStatus = sensor('networkStatus');\r\n}\r\n\r\nexport function injectNetworkStatus() {\r\n return inject(ResourceSensors).networkStatus;\r\n}\r\n","import { HttpResourceRef } from '@angular/common/http';\r\n\r\nexport function toResourceObject<T>(\r\n res: HttpResourceRef<T>,\r\n): HttpResourceRef<T> {\r\n return {\r\n asReadonly: () => res.asReadonly(),\r\n destroy: () => res.destroy(),\r\n error: res.error,\r\n headers: res.headers,\r\n isLoading: res.isLoading,\r\n progress: res.progress,\r\n status: res.status,\r\n statusCode: res.statusCode,\r\n value: res.value,\r\n reload: () => res.reload(),\r\n hasValue: (() => res.hasValue()) as HttpResourceRef<T>['hasValue'],\r\n set: (v) => res.set(v),\r\n update: (v) => res.update(v),\r\n };\r\n}\r\n","import { HttpParams, HttpResourceRequest } from '@angular/common/http';\r\n\r\nfunction normalizeParams(\r\n params: Required<HttpResourceRequest>['params'],\r\n): string {\r\n if (params instanceof HttpParams) return params.toString();\r\n\r\n const paramMap = new Map<string, string>();\r\n\r\n for (const [key, value] of Object.entries(params)) {\r\n if (Array.isArray(value)) {\r\n paramMap.set(key, value.map(encodeURIComponent).join(','));\r\n } else {\r\n paramMap.set(key, encodeURIComponent(value.toString()));\r\n }\r\n }\r\n\r\n return Array.from(paramMap.entries())\r\n .sort(([a], [b]) => a.localeCompare(b))\r\n .map(([key, value]) => `${key}=${value}`)\r\n .join('&');\r\n}\r\n\r\nexport function urlWithParams(req: HttpResourceRequest): string {\r\n if (!req.params) return req.url;\r\n\r\n return `${req.url}?${normalizeParams(req.params)}`;\r\n}\r\n","import {\r\n HttpClient,\r\n HttpHeaders,\r\n httpResource,\r\n HttpResponse,\r\n type HttpResourceOptions,\r\n type HttpResourceRef,\r\n type HttpResourceRequest,\r\n} from '@angular/common/http';\r\nimport {\r\n computed,\r\n DestroyRef,\r\n effect,\r\n inject,\r\n isDevMode,\r\n linkedSignal,\r\n Signal,\r\n untracked,\r\n WritableSignal,\r\n} from '@angular/core';\r\nimport { toWritable } from '@mmstack/primitives';\r\nimport { firstValueFrom } from 'rxjs';\r\nimport {\r\n catchValueError,\r\n CircuitBreakerOptions,\r\n createCircuitBreaker,\r\n createEqualRequest,\r\n hasSlowConnection,\r\n injectNetworkStatus,\r\n injectQueryCache,\r\n persistResourceValues,\r\n refresh,\r\n retryOnError,\r\n setCacheContext,\r\n toResourceObject,\r\n urlWithParams,\r\n type RetryOptions,\r\n} from './util';\r\nimport { CacheEntry } from './util/cache/cache';\r\n\r\n/**\r\n * Options for configuring caching behavior of a `queryResource`.\r\n * - `true`: Enables caching with default settings.\r\n * - `{ ttl?: number; staleTime?: number; hash?: (req: HttpResourceRequest) => string; }`: Configures caching with custom settings.\r\n */\r\ntype ResourceCacheOptions =\r\n | true\r\n | {\r\n /**\r\n * The Time To Live (TTL) for the cached data, in milliseconds. After this time, the cached data is\r\n * considered expired and will be refetched.\r\n */\r\n ttl?: number;\r\n /**\r\n * The duration, in milliseconds, during which stale data can be served while a revalidation request\r\n * is made in the background.\r\n */\r\n staleTime?: number;\r\n /**\r\n * A custom function to generate the cache key. Defaults to using the request URL with parameters.\r\n * Provide a custom hash function if you need more control over how cache keys are generated,\r\n * for instance, to ignore certain query parameters or to use request body for the cache key.\r\n */\r\n hash?: (req: HttpResourceRequest) => string;\r\n /**\r\n * Whether to bust the browser cache by appending a unique query parameter to the request URL.\r\n * This is useful for ensuring that the latest data is fetched from the server, bypassing any\r\n * cached responses in the browser. The unique parameter is removed before calling the cache function, so it does not affect the cache key.\r\n * @default false - By default, the resource will not bust the browser cache.\r\n */\r\n bustBrowserCache?: boolean;\r\n /**\r\n * Whether to ignore the `Cache-Control` headers from the server when caching responses.\r\n * If set to `true`, the resource will not respect any cache directives from the server,\r\n * allowing you to control caching behavior entirely through the resource options.\r\n * @default false - By default the resource will respect `Cache-Control` headers.\r\n */\r\n ignoreCacheControl?: boolean;\r\n /**\r\n * Whether to persist the cache entry in the local DB instance.\r\n * @default false - By default, the cache entry is not persisted.\r\n */\r\n persist?: boolean;\r\n };\r\n\r\n/**\r\n * Options for configuring a `queryResource`.\r\n */\r\nexport type QueryResourceOptions<TResult, TRaw = TResult> = HttpResourceOptions<\r\n TResult,\r\n TRaw\r\n> & {\r\n /**\r\n * Whether to keep the previous value of the resource while a refresh is in progress.\r\n * Defaults to `false`. Also keeps status & headers while refreshing.\r\n */\r\n keepPrevious?: boolean;\r\n /**\r\n * The refresh interval, in milliseconds. If provided, the resource will automatically\r\n * refresh its data at the specified interval.\r\n */\r\n refresh?: number;\r\n /**\r\n * Options for retrying failed requests.\r\n */\r\n retry?: RetryOptions;\r\n /**\r\n * An optional error handler callback. This function will be called whenever the\r\n * underlying HTTP request fails. Useful for displaying toasts or other error messages.\r\n */\r\n onError?: (err: unknown) => void;\r\n /**\r\n * Options for configuring a circuit breaker for the resource.\r\n */\r\n circuitBreaker?: CircuitBreakerOptions | true;\r\n /**\r\n * Options for enabling and configuring caching for the resource.\r\n */\r\n cache?: ResourceCacheOptions;\r\n /**\r\n * Trigger a request every time the request function is triggered, even if the request parameters are the same.\r\n * @default false\r\n */\r\n triggerOnSameRequest?: boolean;\r\n};\r\n\r\n/**\r\n * Represents a resource created by `queryResource`. Extends `HttpResourceRef` with additional properties.\r\n */\r\nexport type QueryResourceRef<TResult> = Omit<\r\n HttpResourceRef<TResult>,\r\n 'headers' | 'statusCode'\r\n> & {\r\n /**\r\n * Linkedsignal of the response headers, when available.\r\n */\r\n readonly headers: WritableSignal<HttpHeaders | undefined>;\r\n /**\r\n * Linkedsignal of the response status code, when available.\r\n */\r\n readonly statusCode: WritableSignal<number | undefined>;\r\n /**\r\n * A signal indicating whether the resource is currently disabled (due to circuit breaker or undefined request).\r\n */\r\n disabled: Signal<boolean>;\r\n /**\r\n * Prefetches data for the resource, populating the cache if caching is enabled. This can be\r\n * used to proactively load data before it's needed. If a slow connection is detected, prefetching is skipped.\r\n *\r\n * @param req - Optional partial request parameters to use for the prefetch. This allows you\r\n * to prefetch data with different parameters than the main resource request.\r\n */\r\n prefetch: (req?: Partial<HttpResourceRequest>) => Promise<void>;\r\n};\r\n\r\nexport function queryResource<TResult, TRaw = TResult>(\r\n request: () => HttpResourceRequest | undefined | void,\r\n options: QueryResourceOptions<TResult, TRaw> & {\r\n defaultValue: NoInfer<TResult>;\r\n },\r\n): QueryResourceRef<TResult>;\r\n\r\n/**\r\n * Creates an extended HTTP resource with features like caching, retries, refresh intervals,\r\n * circuit breaker, and optimistic updates. Without additional options it is equivalent to simply calling `httpResource`.\r\n *\r\n * @param request A function that returns the `HttpResourceRequest` to be made. This function\r\n * is called reactively, so the request can change over time. If the function\r\n * returns `undefined`, the resource is considered \"disabled\" and no request will be made.\r\n * @param options Configuration options for the resource. These options extend the basic\r\n * `HttpResourceOptions` and add features like `keepPrevious`, `refresh`, `retry`,\r\n * `onError`, `circuitBreaker`, and `cache`.\r\n * @returns An `QueryResourceRef` instance, which extends the basic `HttpResourceRef` with additional features.\r\n */\r\nexport function queryResource<TResult, TRaw = TResult>(\r\n request: () => HttpResourceRequest | undefined | void,\r\n options?: QueryResourceOptions<TResult, TRaw>,\r\n): QueryResourceRef<TResult | undefined>;\r\n\r\nexport function queryResource<TResult, TRaw = TResult>(\r\n request: () => HttpResourceRequest | undefined | void,\r\n options?: QueryResourceOptions<TResult, TRaw>,\r\n): QueryResourceRef<TResult | undefined> {\r\n const cache = injectQueryCache<TResult>(options?.injector);\r\n\r\n const destroyRef = options?.injector\r\n ? options.injector.get(DestroyRef)\r\n : inject(DestroyRef);\r\n\r\n const cb = createCircuitBreaker(\r\n options?.circuitBreaker === true\r\n ? undefined\r\n : (options?.circuitBreaker ?? false),\r\n options?.injector,\r\n );\r\n\r\n const networkAvailable = injectNetworkStatus();\r\n\r\n const eq = options?.triggerOnSameRequest\r\n ? undefined\r\n : createEqualRequest(options?.equal);\r\n\r\n const stableRequest = computed(\r\n () => {\r\n if (!networkAvailable() || cb.isOpen()) return undefined;\r\n return request() ?? undefined;\r\n },\r\n {\r\n equal: (a, b) => {\r\n if (eq) return eq(a, b);\r\n return a === b;\r\n },\r\n },\r\n );\r\n\r\n const hashFn =\r\n typeof options?.cache === 'object'\r\n ? (options.cache.hash ?? urlWithParams)\r\n : urlWithParams;\r\n\r\n const staleTime =\r\n typeof options?.cache === 'object' ? options.cache.staleTime : 0;\r\n const ttl =\r\n typeof options?.cache === 'object' ? options.cache.ttl : undefined;\r\n\r\n const cacheKey = computed(() => {\r\n const r = stableRequest();\r\n if (!r) return null;\r\n return hashFn(r);\r\n });\r\n\r\n const bustBrowserCache =\r\n typeof options?.cache === 'object' &&\r\n options.cache.bustBrowserCache === true;\r\n\r\n const ignoreCacheControl =\r\n typeof options?.cache === 'object' &&\r\n options.cache.ignoreCacheControl === true;\r\n\r\n const persist =\r\n typeof options?.cache === 'object' && options.cache.persist === true;\r\n\r\n const cachedRequest = options?.cache\r\n ? computed(() => {\r\n const r = stableRequest();\r\n if (!r) return r;\r\n\r\n return {\r\n ...r,\r\n context: setCacheContext(r.context, {\r\n staleTime,\r\n ttl,\r\n key: cacheKey() ?? hashFn(r),\r\n bustBrowserCache,\r\n ignoreCacheControl,\r\n persist,\r\n }),\r\n };\r\n })\r\n : stableRequest;\r\n\r\n let resource = toResourceObject(\r\n httpResource<TResult>(cachedRequest, {\r\n ...options,\r\n parse: options?.parse as any, // Not my favorite thing to do, but here it is completely safe.\r\n }) as HttpResourceRef<TResult>,\r\n );\r\n\r\n resource = catchValueError(resource, options?.defaultValue as TResult);\r\n\r\n // get full HttpResonse from Cache\r\n const cachedEvent = cache.getEntryOrKey(cacheKey);\r\n\r\n const cacheEntry = linkedSignal<\r\n CacheEntry<HttpResponse<TResult>> | string | null,\r\n { key: string; value: TResult | null } | null\r\n >({\r\n source: () => cachedEvent(),\r\n computation: (entry, prev) => {\r\n if (!entry) return null;\r\n\r\n if (\r\n typeof entry === 'string' &&\r\n prev &&\r\n prev.value !== null &&\r\n prev.value.key === entry\r\n ) {\r\n return prev.value;\r\n }\r\n\r\n if (typeof entry === 'string') return { key: entry, value: null };\r\n\r\n if (!(entry.value instanceof HttpResponse))\r\n return { key: entry.key, value: null };\r\n\r\n return {\r\n value: entry.value.body,\r\n key: entry.key,\r\n };\r\n },\r\n });\r\n\r\n resource = refresh(resource, destroyRef, options?.refresh);\r\n resource = retryOnError(resource, options?.retry);\r\n\r\n resource = persistResourceValues<TResult>(\r\n resource,\r\n options?.keepPrevious,\r\n options?.equal,\r\n );\r\n\r\n const value = options?.cache\r\n ? toWritable(\r\n computed((): TResult => {\r\n resource.value();\r\n return cacheEntry()?.value ?? resource.value();\r\n }),\r\n resource.value.set,\r\n resource.value.update,\r\n )\r\n : resource.value;\r\n\r\n const onError = options?.onError; // Put in own variable to ensure value remains even if options are somehow mutated in-line\r\n\r\n if (onError) {\r\n const onErrorRef = effect(() => {\r\n const err = resource.error();\r\n if (err) onError(err);\r\n });\r\n\r\n // cleanup on manual destroy, I'm comfortable setting these props in-line as we have yet to 'release' the object out of this lexical scope\r\n const destroyRest = resource.destroy;\r\n resource.destroy = () => {\r\n onErrorRef.destroy();\r\n destroyRest();\r\n };\r\n }\r\n\r\n // iterate circuit breaker state, is effect as a computed would cause a circular dependency (resource -> cb -> resource)\r\n const cbEffectRef = effect(() => {\r\n const status = resource.status();\r\n if (status === 'error') cb.fail(untracked(resource.error));\r\n else if (status === 'resolved') cb.success();\r\n });\r\n\r\n const set = (value: TResult) => {\r\n resource.value.set(value);\r\n const k = untracked(cacheKey);\r\n if (options?.cache && k)\r\n cache.store(\r\n k,\r\n new HttpResponse({\r\n body: value,\r\n status: 200,\r\n statusText: 'OK',\r\n }),\r\n staleTime,\r\n ttl,\r\n persist,\r\n );\r\n };\r\n\r\n const update = (updater: (value: TResult) => TResult) => {\r\n set(updater(untracked(resource.value)));\r\n };\r\n\r\n const client = options?.injector\r\n ? options.injector.get(HttpClient)\r\n : inject(HttpClient);\r\n\r\n return {\r\n ...resource,\r\n value,\r\n set,\r\n update,\r\n statusCode: linkedSignal(resource.statusCode),\r\n headers: linkedSignal(resource.headers),\r\n disabled: computed(() => cb.isOpen() || stableRequest() === undefined),\r\n reload: () => {\r\n cb.halfOpen(); // open the circuit for manual reload\r\n return resource.reload();\r\n },\r\n destroy: () => {\r\n cbEffectRef.destroy();\r\n cb.destroy();\r\n resource.destroy();\r\n },\r\n prefetch: async (partial) => {\r\n if (!options?.cache || hasSlowConnection()) return Promise.resolve();\r\n\r\n const request = untracked(stableRequest);\r\n\r\n const prefetchRequest = {\r\n ...request,\r\n ...partial,\r\n };\r\n if (!prefetchRequest.url) return Promise.resolve();\r\n\r\n const key = hashFn({\r\n ...prefetchRequest,\r\n url: prefetchRequest.url ?? '',\r\n });\r\n\r\n const found = cache.getUntracked(key);\r\n if (found && !found.isStale) return Promise.resolve();\r\n\r\n try {\r\n await firstValueFrom(\r\n client.request(prefetchRequest.method ?? 'GET', prefetchRequest.url, {\r\n ...prefetchRequest,\r\n referrerPolicy: prefetchRequest.referrerPolicy as\r\n | ReferrerPolicy\r\n | undefined,\r\n credentials: prefetchRequest.credentials as\r\n | RequestCredentials\r\n | undefined,\r\n priority: prefetchRequest.priority as RequestPriority | undefined,\r\n cache: prefetchRequest.cache as RequestCache | undefined,\r\n mode: prefetchRequest.mode as RequestMode | undefined,\r\n redirect: prefetchRequest.redirect as RequestRedirect | undefined,\r\n context: setCacheContext(prefetchRequest.context, {\r\n staleTime,\r\n ttl,\r\n key: hashFn({\r\n ...prefetchRequest,\r\n url: prefetchRequest.url ?? '',\r\n }),\r\n bustBrowserCache,\r\n ignoreCacheControl,\r\n persist,\r\n }),\r\n headers: prefetchRequest.headers as HttpHeaders,\r\n observe: 'response',\r\n }),\r\n );\r\n\r\n return;\r\n } catch (err) {\r\n if (isDevMode()) console.error('Prefetch failed: ', err);\r\n return;\r\n }\r\n },\r\n };\r\n}\r\n","import { type HttpResourceRequest } from '@angular/common/http';\r\nimport {\r\n computed,\r\n DestroyRef,\r\n effect,\r\n inject,\r\n linkedSignal,\r\n Signal,\r\n signal,\r\n ValueEqualityFn,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\r\nimport { catchError, combineLatestWith, filter, map, of } from 'rxjs';\r\nimport {\r\n queryResource,\r\n type QueryResourceOptions,\r\n type QueryResourceRef,\r\n} from './query-resource';\r\nimport { createCircuitBreaker, createEqualRequest } from './util';\r\n\r\n/**\r\n * @internal\r\n * Helper type for inferring the request body type based on the HTTP method.\r\n */\r\ntype NextRequest<\r\n TMethod extends HttpResourceRequest['method'],\r\n TMutation,\r\n> = TMethod extends 'DELETE' | 'delete'\r\n ? Omit<HttpResourceRequest, 'body' | 'method'> & { method: TMethod }\r\n : Omit<HttpResourceRequest, 'body' | 'method'> & {\r\n body: TMutation;\r\n method: TMethod;\r\n };\r\n\r\n/**\r\n * @internal\r\n * Helper type for tracking mutation status.\r\n */\r\ntype StatusResult<TResult> =\r\n | {\r\n status: 'error';\r\n error: unknown;\r\n }\r\n | {\r\n status: 'resolved';\r\n value: TResult;\r\n };\r\n\r\n/**\r\n * Options for configuring a `mutationResource`.\r\n *\r\n * @typeParam TResult - The type of the expected result from the mutation.\r\n * @typeParam TRaw - The raw response type from the HTTP request (defaults to TResult).\r\n * @typeParam TCTX - The type of the context value returned by `onMutate`.\r\n */\r\nexport type MutationResourceOptions<\r\n TResult,\r\n TRaw = TResult,\r\n TMutation = TResult,\r\n TCTX = void,\r\n TICTX = TCTX,\r\n> = Omit<\r\n QueryResourceOptions<TResult, TRaw>,\r\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\r\n> & {\r\n /**\r\n * A callback function that is called before the mutation request is made.\r\n * @param value The value being mutated (the `body` of the request).\r\n * @returns An optional context value that will be passed to the `onError`, `onSuccess`, and `onSettled` callbacks. This is useful for storing\r\n * information needed during the mutation lifecycle, such as previous values for optimistic updates or rollback.\r\n */\r\n onMutate?: (value: TMutation, initialCTX?: TICTX) => TCTX;\r\n /**\r\n * A callback function that is called if the mutation request fails.\r\n * @param error The error that occurred.\r\n * @param ctx The context value returned by the `onMutate` callback (or `undefined` if `onMutate` was not provided or returned `undefined`).\r\n */\r\n onError?: (error: unknown, ctx: NoInfer<TCTX>) => void;\r\n /**\r\n * A callback function that is called if the mutation request succeeds.\r\n * @param value The result of the mutation (the parsed response body).\r\n * @param ctx The context value returned by the `onMutate` callback (or `undefined` if `onMutate` was not provided or returned `undefined`).\r\n */\r\n onSuccess?: (value: NoInfer<TResult>, ctx: NoInfer<TCTX>) => void;\r\n /**\r\n * A callback function that is called when the mutation request settles (either succeeds or fails).\r\n * @param ctx The context value returned by the `onMutate` callback (or `undefined` if `onMutate` was not provided or returned `undefined`).\r\n */\r\n onSettled?: (ctx: NoInfer<TCTX>) => void;\r\n /**\r\n * Whether to queue the mutation requests and execute them in series. For example if network is unavailable or circuit breaker is open.\r\n * @default false\r\n */\r\n queue?: boolean;\r\n equal?: ValueEqualityFn<TMutation>;\r\n};\r\n\r\n/**\r\n * Represents a mutation resource created by `mutationResource`. Extends `QueryResourceRef`\r\n * but removes methods that don't make sense for mutations (like `prefetch`, `value`, etc.).\r\n *\r\n * @typeParam TResult - The type of the expected result from the mutation.\r\n */\r\nexport type MutationResourceRef<\r\n TResult,\r\n TMutation = TResult,\r\n TICTX = void,\r\n> = Omit<\r\n QueryResourceRef<TResult>,\r\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\r\n> & {\r\n /**\r\n * Executes the mutation.\r\n *\r\n * @param value The mutation value (usually the request body).\r\n * @param ctx An optional initial context value that will be passed to the `onMutate` callback.\r\n */\r\n mutate: (value: TMutation, ctx?: TICTX) => void;\r\n /**\r\n * A signal that holds the current mutation request, or `null` if no mutation is in progress.\r\n * This can be useful for tracking the state of the mutation or for displaying loading indicators.\r\n */\r\n current: Signal<TMutation | null>;\r\n};\r\n\r\n/**\r\n * Creates a resource for performing mutations (e.g., POST, PUT, PATCH, DELETE requests).\r\n * Unlike `queryResource`, `mutationResource` is designed for one-off operations that change data.\r\n * It does *not* cache responses and does not provide a `value` signal. Instead, it focuses on\r\n * managing the mutation lifecycle (pending, error, success) and provides callbacks for handling\r\n * these states.\r\n *\r\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.\r\n * @param options Configuration options for the mutation resource. This includes callbacks\r\n * for `onMutate`, `onError`, `onSuccess`, and `onSettled`.\r\n * @typeParam TResult - The type of the expected result from the mutation.\r\n * @typeParam TRaw - The raw response type from the HTTP request (defaults to TResult).\r\n * @typeParam TMutation - The type of the mutation value (the request body).\r\n * @typeParam TICTX - The type of the initial context value passed to `onMutate`.\r\n * @typeParam TCTX - The type of the context value returned by `onMutate`.\r\n * @typeParam TMethod - The HTTP method to be used for the mutation (defaults to `HttpResourceRequest['method']`).\r\n * @returns A `MutationResourceRef` instance, which provides methods for triggering the mutation\r\n * and observing its status.\r\n */\r\nexport function mutationResource<\r\n TResult,\r\n TRaw = TResult,\r\n TMutation = TResult,\r\n TCTX = void,\r\n TICTX = TCTX,\r\n TMethod extends HttpResourceRequest['method'] = HttpResourceRequest['method'],\r\n>(\r\n request: (\r\n params: TMutation,\r\n ) => Omit<NextRequest<TMethod, TMutation>, 'body'> | undefined | void,\r\n options: MutationResourceOptions<TResult, TRaw, TMutation, TCTX, TICTX> = {},\r\n): MutationResourceRef<TResult, TMutation, TICTX> {\r\n const { onMutate, onError, onSuccess, onSettled, equal, ...rest } = options;\r\n\r\n const requestEqual = createEqualRequest(equal);\r\n\r\n const eq = equal ?? Object.is;\r\n const next = signal<TMutation | null>(null, {\r\n equal: (a, b) => {\r\n if (!a && !b) return true;\r\n if (!a || !b) return false;\r\n return eq(a, b);\r\n },\r\n });\r\n\r\n const queue = signal<[TMutation, TICTX | undefined][]>([]);\r\n\r\n let ctx: TCTX = undefined as TCTX;\r\n\r\n const queueRef = effect(() => {\r\n const nextInQueue = queue().at(0);\r\n if (!nextInQueue || next() !== null) return;\r\n queue.update((q) => q.slice(1));\r\n const [value, ictx] = nextInQueue;\r\n ctx = onMutate?.(value, ictx) as TCTX;\r\n next.set(value);\r\n });\r\n\r\n const req = computed(\r\n (): HttpResourceRequest | undefined => {\r\n const nr = next();\r\n if (!nr) return;\r\n\r\n return request(nr) ?? undefined;\r\n },\r\n {\r\n equal: requestEqual,\r\n },\r\n );\r\n\r\n const lastValue = linkedSignal<TMutation | null, TMutation | null>({\r\n source: next,\r\n computation: (next, prev) => {\r\n if (next === null && !!prev) return prev.value;\r\n return next;\r\n },\r\n });\r\n\r\n const lastValueRequest = computed(\r\n (): HttpResourceRequest | undefined => {\r\n const nr = lastValue();\r\n if (!nr) return;\r\n\r\n return request(nr) ?? undefined;\r\n },\r\n {\r\n equal: requestEqual,\r\n },\r\n );\r\n\r\n const cb = createCircuitBreaker(\r\n options?.circuitBreaker === true\r\n ? undefined\r\n : (options?.circuitBreaker ?? false),\r\n options?.injector,\r\n );\r\n\r\n const resource = queryResource<TResult, TRaw>(req, {\r\n ...rest,\r\n circuitBreaker: cb,\r\n defaultValue: null as unknown as TResult, // doesnt matter since .value is not accessible\r\n });\r\n\r\n const destroyRef = options.injector\r\n ? options.injector.get(DestroyRef)\r\n : inject(DestroyRef);\r\n\r\n const error$ = toObservable(resource.error);\r\n const value$ = toObservable(resource.value).pipe(catchError(() => of(null)));\r\n\r\n const statusSub = toObservable(resource.status)\r\n .pipe(\r\n combineLatestWith(error$, value$),\r\n map(([status, error, value]): StatusResult<TResult> | null => {\r\n if (status === 'error' && error) {\r\n return {\r\n status: 'error',\r\n error,\r\n };\r\n }\r\n\r\n if (status === 'resolved' && value !== null) {\r\n return {\r\n status: 'resolved',\r\n value,\r\n };\r\n }\r\n\r\n return null;\r\n }),\r\n filter((v) => v !== null),\r\n takeUntilDestroyed(destroyRef),\r\n )\r\n .subscribe((result) => {\r\n if (result.status === 'error') onError?.(result.error, ctx);\r\n else onSuccess?.(result.value, ctx);\r\n\r\n onSettled?.(ctx);\r\n ctx = undefined as TCTX;\r\n next.set(null);\r\n });\r\n\r\n const shouldQueue = options.queue ?? false;\r\n\r\n return {\r\n ...resource,\r\n destroy: () => {\r\n statusSub.unsubscribe();\r\n resource.destroy();\r\n queueRef.destroy();\r\n },\r\n mutate: (value, ictx) => {\r\n if (shouldQueue) {\r\n return queue.update((q) => [...q, [value, ictx]]);\r\n } else {\r\n ctx = onMutate?.(value, ictx) as TCTX;\r\n next.set(value);\r\n }\r\n },\r\n current: next,\r\n // redeclare disabled with last value so that it is not affected by the resource's internal disablement logic\r\n disabled: computed(() => cb.isOpen() || lastValueRequest() === undefined),\r\n };\r\n}\r\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/cache/cache-interceptor.ts","../../../../packages/resource/src/lib/util/catch-value-error.ts","../../../../packages/resource/src/lib/util/circuit-breaker.ts","../../../../packages/resource/src/lib/util/dedupe-interceptor.ts","../../../../packages/resource/src/lib/util/equality.ts","../../../../packages/resource/src/lib/util/has-slow-connection.ts","../../../../packages/resource/src/lib/util/persist.ts","../../../../packages/resource/src/lib/util/refresh.ts","../../../../packages/resource/src/lib/util/retry-on-error.ts","../../../../packages/resource/src/lib/util/sensors.ts","../../../../packages/resource/src/lib/util/to-resource-object.ts","../../../../packages/resource/src/lib/util/url-with-params.ts","../../../../packages/resource/src/lib/query-resource.ts","../../../../packages/resource/src/lib/mutation-resource.ts","../../../../packages/resource/src/mmstack-resource.ts"],"sourcesContent":["import { isDevMode } from '@angular/core';\nimport { CacheEntry } from './cache';\n\ntype StoredEntry<T> = Omit<CacheEntry<T>, 'timeout'>;\n\nexport type CacheDB<T> = {\n getAll: () => Promise<StoredEntry<T>[]>;\n store: (value: StoredEntry<T>) => Promise<void>;\n remove: (key: string) => Promise<void>;\n};\n\nexport function createNoopDB<T>(): CacheDB<T> {\n return {\n getAll: async () => [],\n store: async () => {\n // noop\n },\n remove: async () => {\n // noop\n },\n };\n}\n\nfunction toCacheDB<T>(db: IDBDatabase, storeName: string): CacheDB<T> {\n const getAll = async () => {\n const now = Date.now();\n return new Promise<StoredEntry<T>[]>((res, rej) => {\n const transaction = db.transaction(storeName, 'readonly');\n const store = transaction.objectStore(storeName);\n const request = store.getAll();\n\n request.onsuccess = () => res(request.result);\n request.onerror = () => rej(request.error);\n })\n .then((entries) => entries.filter((e) => e.expiresAt > now))\n .catch((err) => {\n if (isDevMode())\n console.error('Error getting all items from cache DB:', err);\n return [];\n });\n };\n\n const store = (value: StoredEntry<T>) => {\n return new Promise<void>((res, rej) => {\n const transaction = db.transaction(storeName, 'readwrite');\n const store = transaction.objectStore(storeName);\n\n store.put(value);\n\n transaction.oncomplete = () => res();\n transaction.onerror = () => rej(transaction.error);\n }).catch((err) => {\n if (isDevMode()) console.error('Error storing item in cache DB:', err);\n });\n };\n\n const remove = (key: string) => {\n return new Promise<void>((res, rej) => {\n const transaction = db.transaction(storeName, 'readwrite');\n const store = transaction.objectStore(storeName);\n\n store.delete(key);\n\n transaction.oncomplete = () => res();\n transaction.onerror = () => rej(transaction.error);\n }).catch((err) => {\n if (isDevMode()) console.error('Error removing item from cache DB:', err);\n });\n };\n\n return {\n getAll,\n store,\n remove,\n };\n}\n\nexport function createSingleStoreDB<T>(\n name: string,\n getStoreName: (version: number) => string,\n version = 1,\n): Promise<CacheDB<T>> {\n const storeName = getStoreName(version);\n\n if (!globalThis.indexedDB) return Promise.resolve(createNoopDB());\n\n return new Promise<IDBDatabase>((res, rej) => {\n if (version < 1) rej(new Error('Version must be 1 or greater'));\n\n const req = indexedDB.open(name, version);\n\n req.onupgradeneeded = (event) => {\n const db = req.result;\n const oldVersion = event.oldVersion;\n\n db.createObjectStore(storeName, { keyPath: 'key' });\n\n if (oldVersion > 0) {\n db.deleteObjectStore(getStoreName(oldVersion));\n }\n };\n\n req.onerror = () => {\n rej(req.error);\n };\n\n req.onsuccess = () => res(req.result);\n })\n .then((db) => toCacheDB<T>(db, storeName))\n .catch((err) => {\n if (isDevMode()) console.error('Error creating query DB:', err);\n return createNoopDB();\n });\n}\n","import { HttpHeaders, HttpResponse } from '@angular/common/http';\nimport {\n computed,\n inject,\n InjectionToken,\n Injector,\n isDevMode,\n type Provider,\n type Signal,\n untracked,\n} from '@angular/core';\nimport { mutable } from '@mmstack/primitives';\nimport { CacheDB, createNoopDB, createSingleStoreDB } from './persistence';\n\nfunction generateID() {\n if (globalThis.crypto?.randomUUID) {\n return globalThis.crypto.randomUUID();\n }\n return Math.random().toString(36).substring(2);\n}\n\ntype BaseSyncMessage<TEntry, TAction extends string> = {\n entry: TEntry;\n action: TAction;\n};\n\ntype InvalidateMessage<T> = BaseSyncMessage<\n Pick<CacheEntry<T>, 'key'>,\n 'invalidate'\n>;\n\ntype StoreMessage<T> = BaseSyncMessage<Omit<CacheEntry<T>, 'timeout'>, 'store'>;\n\ntype InternalSyncMessage<T> = InvalidateMessage<T> | StoreMessage<T>;\n\n/**\n * A message type used for synchronizing cache updates across tabs.\n * @internal\n * @template T - The type of data being cached.\n */\ntype SyncMessage<T> = InternalSyncMessage<T> & {\n cacheId: string;\n type: 'cache-sync-message';\n};\n\nfunction isSyncMessage<T>(msg: unknown): msg is SyncMessage<T> {\n return (\n typeof msg === 'object' &&\n msg !== null &&\n 'type' in msg &&\n (msg as SyncMessage<T>).type === 'cache-sync-message'\n );\n}\n\n/**\n * Options for configuring the Least Recently Used (LRU) cache cleanup strategy.\n * @internal\n */\ntype LRUCleanupType = {\n type: 'lru';\n /**\n * How often to check for expired or excess entries, in milliseconds.\n */\n checkInterval: number;\n /**\n * The maximum number of entries to keep in the cache. When the cache exceeds this size,\n * the least recently used entries will be removed.\n */\n maxSize: number;\n};\n\n/**\n * Options for configuring the \"oldest first\" cache cleanup strategy.\n * @internal\n */\ntype OldsetCleanupType = {\n type: 'oldest';\n /**\n * How often to check for expired or excess entries, in milliseconds.\n */\n checkInterval: number;\n /**\n * The maximum number of entries to keep in the cache. When the cache exceeds this size,\n * the oldest entries will be removed.\n */\n maxSize: number;\n};\n\n/**\n * Represents an entry in the cache.\n * @internal\n */\nexport type CacheEntry<T> = {\n value: T;\n created: number;\n updated: number;\n stale: number;\n useCount: number;\n expiresAt: number;\n timeout: ReturnType<typeof setTimeout>;\n key: string;\n};\n\n/**\n * Defines the types of cleanup strategies available for the cache.\n * - `lru`: Least Recently Used. Removes the least recently accessed entries when the cache is full.\n * - `oldest`: Removes the oldest entries when the cache is full.\n */\nexport type CleanupType = LRUCleanupType | OldsetCleanupType;\n\nconst ONE_DAY = 1000 * 60 * 60 * 24;\nconst ONE_HOUR = 1000 * 60 * 60;\n\nconst DEFAULT_CLEANUP_OPT = {\n type: 'lru',\n maxSize: 200,\n checkInterval: ONE_HOUR,\n} satisfies LRUCleanupType;\n\n/**\n * A generic cache implementation that stores data with time-to-live (TTL) and stale-while-revalidate capabilities.\n *\n * @typeParam T - The type of data to be stored in the cache.\n */\nexport class Cache<T> {\n private readonly internal = mutable(new Map<string, CacheEntry<T>>());\n private readonly cleanupOpt: CleanupType;\n private readonly id = generateID();\n\n /**\n * Destroys the cache instance, cleaning up any resources used by the cache.\n * This method is called automatically when the cache instance is garbage collected.\n */\n readonly destroy: () => void;\n\n private readonly broadcast: (msg: InternalSyncMessage<T>) => void = () => {\n // noop\n };\n\n /**\n * Creates a new `Cache` instance.\n *\n * @param ttl - The default Time To Live (TTL) for cache entries, in milliseconds. Defaults to one day.\n * @param staleTime - The default duration, in milliseconds, during which a cache entry is considered\n * stale but can still be used while revalidation occurs in the background. Defaults to 1 hour.\n * @param cleanupOpt - Options for configuring the cache cleanup strategy. Defaults to LRU with a\n * `maxSize` of 200 and a `checkInterval` of one hour.\n * @param syncTabs - If provided, the cache will use the options a BroadcastChannel to send updates between tabs.\n * Defaults to `undefined`, meaning no synchronization across tabs.\n */\n constructor(\n protected readonly ttl: number = ONE_DAY,\n protected readonly staleTime: number = ONE_HOUR,\n cleanupOpt: Partial<CleanupType> = {\n type: 'lru',\n maxSize: 1000,\n checkInterval: ONE_HOUR,\n },\n syncTabs?: {\n id: string;\n serialize: (value: T) => string;\n deserialize: (value: string) => T | null;\n },\n\n private readonly db: Promise<CacheDB<T>> = Promise.resolve(\n createNoopDB<T>(),\n ),\n ) {\n this.cleanupOpt = {\n ...DEFAULT_CLEANUP_OPT,\n ...cleanupOpt,\n };\n\n if (this.cleanupOpt.maxSize <= 0)\n throw new Error('maxSize must be greater than 0');\n\n // cleanup cache based on provided options regularly\n const cleanupInterval = setInterval(() => {\n this.cleanup();\n }, cleanupOpt.checkInterval);\n\n let destroySyncTabs = () => {\n // noop\n };\n\n if (syncTabs) {\n const channel = new BroadcastChannel(syncTabs.id);\n this.broadcast = (msg: InternalSyncMessage<T>) => {\n if (msg.action === 'invalidate')\n return channel.postMessage({\n action: 'invalidate',\n entry: { key: msg.entry.key },\n cacheId: this.id,\n type: 'cache-sync-message',\n } satisfies SyncMessage<string>);\n\n return channel.postMessage({\n ...msg,\n entry: {\n ...msg.entry,\n value: syncTabs.serialize(msg.entry.value),\n },\n cacheId: this.id,\n type: 'cache-sync-message',\n } satisfies SyncMessage<string>);\n };\n\n channel.onmessage = (event) => {\n const msg = event.data;\n if (!isSyncMessage<string>(msg)) return;\n if (msg.cacheId === this.id) return; // ignore messages from this cache\n\n if (msg.action === 'store') {\n const value = syncTabs.deserialize(msg.entry.value);\n if (value === null) return;\n 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 private invalidateInternal(key: string, fromSync = false) {\n const entry = this.getUntracked(key);\n if (!entry) return;\n clearTimeout(entry.timeout);\n this.internal.mutate((map) => {\n map.delete(key);\n return map;\n });\n if (!fromSync) {\n this.db.then((db) => db.remove(key));\n this.broadcast({ action: 'invalidate', entry: { key } });\n }\n }\n\n /** @internal */\n private cleanup() {\n if (untracked(this.internal).size <= this.cleanupOpt.maxSize) return;\n\n const sorted = Array.from(untracked(this.internal).entries()).toSorted(\n (a, b) => {\n if (this.cleanupOpt.type === 'lru') {\n return a[1].useCount - b[1].useCount; // least used first\n } else {\n return a[1].created - b[1].created; // oldest first\n }\n },\n );\n\n const keepCount = Math.floor(this.cleanupOpt.maxSize / 2);\n\n const removed = sorted.slice(0, sorted.length - keepCount);\n const keep = sorted.slice(removed.length, sorted.length);\n\n removed.forEach(([, e]) => {\n clearTimeout(e.timeout);\n });\n\n this.internal.set(new Map(keep));\n }\n}\n\n/**\n * Options for configuring the cache.\n */\ntype CacheOptions = {\n /**\n * The default Time To Live (TTL) for cache entries, in milliseconds.\n */\n ttl?: number;\n /**\n * The default duration, in milliseconds, during which a cache entry is considered\n * stale but can still be used while revalidation occurs in the background.\n */\n staleTime?: number;\n /**\n * Options for configuring the cache cleanup strategy.\n */\n cleanup?: Partial<CleanupType>;\n /**\n * Whether to synchronize cache across tabs. If true, the cache will use a BroadcastChannel to send updates between tabs.\n */\n syncTabs?: boolean;\n /**\n * Globally disable persistence of cache entries.\n * If set to `false`, cache entries will not be persisted to the database.\n * `true` means, cache entries can be persisted, they must still be opted into on the resource level & allowed by server headers.\n * @default true\n */\n persist?: boolean;\n /**\n * Version of the caches database, increment this if the interfaces change, this will cause the old data to be deleted.\n * Minimum value is 1, so first increment should be 2.\n * @default 1\n */\n version?: number;\n};\n\nconst CLIENT_CACHE_TOKEN = new InjectionToken<Cache<HttpResponse<unknown>>>(\n 'INTERNAL_CLIENT_CACHE',\n);\n\n/**\n * Provides the instance of the QueryCache for queryResource. This should probably be called\n * in your application's root configuration, but can also be overriden with component/module providers.\n *\n * @param options - Optional configuration options for the cache.\n * @returns An Angular `Provider` for the cache.\n *\n * @example\n * // In your app.config.ts or AppModule providers:\n *\n * import { provideQueryCache } from './your-cache';\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideQueryCache({\n * ttl: 60000, // Default TTL of 60 seconds\n * staleTime: 30000, // Default staleTime of 30 seconds\n * }),\n * // ... other providers\n * ]\n * };\n */\nexport function provideQueryCache(opt?: CacheOptions): Provider {\n const serialize = (value: HttpResponse<unknown>) => {\n const headersRecord: Record<string, string[]> = {};\n\n const headerKeys = value.headers.keys();\n headerKeys.forEach((key) => {\n const values = value.headers.getAll(key);\n if (!values) return;\n headersRecord[key] = values;\n });\n\n return JSON.stringify({\n body: value.body,\n status: value.status,\n statusText: value.statusText,\n headers: headerKeys.length > 0 ? headersRecord : undefined,\n url: value.url,\n });\n };\n\n const deserialize = (value: string) => {\n try {\n const parsed = JSON.parse(value);\n\n if (!parsed || typeof parsed !== 'object' || !('body' in parsed))\n throw new Error('Invalid cache entry format');\n\n const headers = parsed.headers\n ? new HttpHeaders(parsed.headers)\n : undefined;\n\n return new HttpResponse({\n body: parsed.body,\n status: parsed.status,\n statusText: parsed.statusText,\n headers: headers,\n url: parsed.url,\n });\n } catch (err) {\n if (isDevMode()) console.error('Failed to deserialize cache entry:', err);\n return null;\n }\n };\n\n const syncTabsOpt = opt?.syncTabs\n ? {\n id: 'mmstack-query-cache-sync',\n serialize,\n deserialize,\n }\n : undefined;\n\n const db =\n opt?.persist === false\n ? undefined\n : createSingleStoreDB<string>(\n 'mmstack-query-cache-db',\n (version) => `query-store_v${version}`,\n opt?.version,\n ).then((db): CacheDB<HttpResponse<unknown>> => {\n return {\n getAll: () => {\n return db.getAll().then((entries) => {\n return entries\n .map((entry) => {\n const value = deserialize(entry.value);\n if (value === null) return null;\n return {\n ...entry,\n value,\n };\n })\n .filter((e) => e !== null);\n });\n },\n store: (entry) => {\n return db.store({ ...entry, value: serialize(entry.value) });\n },\n remove: db.remove,\n };\n });\n\n return {\n provide: CLIENT_CACHE_TOKEN,\n useValue: new Cache(\n opt?.ttl,\n opt?.staleTime,\n opt?.cleanup,\n syncTabsOpt,\n db,\n ),\n };\n}\n\nclass NoopCache<T> extends Cache<T> {\n override store(_: string, __: T, ___ = super.staleTime, ____ = super.ttl) {\n // noop\n }\n}\n\n/**\n * Injects the `QueryCache` instance that is used within queryResource.\n * Allows for direct modification of cached data, but is mostly meant for internal use.\n *\n * @param injector - (Optional) The injector to use. If not provided, the current\n * injection context is used.\n * @returns The `QueryCache` instance.\n *\n * @example\n * // In your component or service:\n *\n * import { injectQueryCache } from './your-cache';\n *\n * constructor() {\n * const cache = injectQueryCache();\n *\n * const myData = cache.get(() => 'my-data-key');\n * if (myData() !== null) {\n * // ... use cached data ...\n * }\n * }\n */\nexport function injectQueryCache<TRaw = unknown>(\n injector?: Injector,\n): Cache<HttpResponse<TRaw>> {\n const cache = injector\n ? injector.get(CLIENT_CACHE_TOKEN, null, {\n optional: true,\n })\n : inject(CLIENT_CACHE_TOKEN, {\n optional: true,\n });\n\n if (!cache) {\n if (isDevMode())\n throw new Error(\n 'Cache not provided, please add provideQueryCache() to providers array',\n );\n else return new NoopCache();\n }\n\n return cache as Cache<HttpResponse<TRaw>>;\n}\n","import {\n HttpContext,\n HttpContextToken,\n type HttpEvent,\n type HttpHandlerFn,\n type HttpInterceptorFn,\n type HttpRequest,\n HttpResponse,\n} from '@angular/common/http';\nimport { map, Observable, of, tap } from 'rxjs';\nimport { injectQueryCache } from './cache';\n\ntype CacheEntryOptions = {\n key?: string;\n ttl?: number;\n staleTime?: number;\n cache: boolean;\n bustBrowserCache?: boolean;\n ignoreCacheControl?: boolean;\n parse?: (val: unknown) => unknown;\n persist?: boolean;\n};\n\nconst CACHE_CONTEXT = new HttpContextToken<CacheEntryOptions>(() => ({\n cache: false,\n}));\n\nexport function setCacheContext(\n ctx = new HttpContext(),\n opt: Omit<CacheEntryOptions, 'cache' | 'key'> & {\n key: Required<CacheEntryOptions>['key'];\n },\n) {\n return ctx.set(CACHE_CONTEXT, { ...opt, cache: true });\n}\n\nfunction getCacheContext(ctx: HttpContext): CacheEntryOptions {\n return ctx.get(CACHE_CONTEXT);\n}\n\ntype ResolvedCacheControl = {\n noStore: boolean;\n noCache: boolean;\n mustRevalidate: boolean;\n immutable: boolean;\n maxAge: number | null;\n staleWhileRevalidate: number | null;\n};\n\nfunction parseCacheControlHeader(\n req: HttpResponse<unknown>,\n): ResolvedCacheControl {\n const header = req.headers.get('Cache-Control');\n\n let sMaxAge: number | null = null;\n const directives: ResolvedCacheControl = {\n noStore: false,\n noCache: false,\n mustRevalidate: false,\n immutable: false,\n maxAge: null,\n staleWhileRevalidate: null,\n };\n\n if (!header) return directives;\n\n const parts = header.split(',');\n\n for (const part of parts) {\n const [unparsedKey, value] = part.trim().split('=');\n const key = unparsedKey.trim().toLowerCase();\n\n switch (key) {\n case 'no-store':\n directives.noStore = true;\n break;\n case 'no-cache':\n directives.noCache = true;\n break;\n case 'must-revalidate':\n case 'proxy-revalidate':\n directives.mustRevalidate = true;\n break;\n case 'immutable':\n directives.immutable = true;\n break;\n case 'max-age': {\n if (!value) break;\n const parsedValue = parseInt(value, 10);\n if (!isNaN(parsedValue)) directives.maxAge = parsedValue;\n break;\n }\n case 's-max-age': {\n if (!value) break;\n const parsedValue = parseInt(value, 10);\n if (!isNaN(parsedValue)) sMaxAge = parsedValue;\n break;\n }\n case 'stale-while-revalidate': {\n if (!value) break;\n const parsedValue = parseInt(value, 10);\n if (!isNaN(parsedValue)) directives.staleWhileRevalidate = parsedValue;\n break;\n }\n }\n }\n\n // s-max-age takes precedence over max-age\n if (sMaxAge !== null) directives.maxAge = sMaxAge;\n\n // if no store nothing else is relevant\n if (directives.noStore)\n return {\n noStore: true,\n noCache: false,\n mustRevalidate: false,\n immutable: false,\n maxAge: null,\n staleWhileRevalidate: null,\n };\n\n // max age does not apply to immutable resources\n if (directives.immutable)\n return {\n ...directives,\n maxAge: null,\n };\n\n return directives;\n}\n\nfunction resolveTimings(\n cacheControl: ResolvedCacheControl,\n optStaleTime?: number,\n optTTL?: number,\n): { staleTime?: number; ttl?: number } {\n let staleTime = optStaleTime;\n let ttl = optTTL;\n\n if (cacheControl.immutable)\n return {\n staleTime: Infinity,\n ttl: Infinity,\n };\n\n if (cacheControl.maxAge !== null) ttl = cacheControl.maxAge * 1000;\n\n if (cacheControl.staleWhileRevalidate !== null)\n staleTime = cacheControl.staleWhileRevalidate * 1000;\n\n // if no-cache is set, we must always revalidate\n if (cacheControl.noCache || cacheControl.mustRevalidate) staleTime = 0;\n\n if (ttl !== undefined && staleTime !== undefined && ttl < staleTime) {\n staleTime = ttl;\n }\n\n return { staleTime, ttl };\n}\n\n/**\n * Creates an `HttpInterceptorFn` that implements caching for HTTP requests. This interceptor\n * checks for a caching configuration in the request's `HttpContext` (internally set by the queryResource).\n * If caching is enabled, it attempts to retrieve responses from the cache. If a cached response\n * is found and is not stale, it's returned directly. If the cached response is stale, it's returned,\n * and a background revalidation request is made. If no cached response is found, the request\n * is made to the server, and the response is cached according to the configured TTL and staleness.\n * The interceptor also respects `Cache-Control` headers from the server.\n *\n * @param allowedMethods - An array of HTTP methods for which caching should be enabled.\n * Defaults to `['GET', 'HEAD', 'OPTIONS']`.\n *\n * @returns An `HttpInterceptorFn` that implements the caching logic.\n *\n * @example\n * // In your app.config.ts or module providers:\n *\n * import { provideHttpClient, withInterceptors } from '@angular/common/http';\n * import { createCacheInterceptor } from '@mmstack/resource';\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([createCacheInterceptor()])),\n * // ... other providers\n * ],\n * };\n */\nexport function createCacheInterceptor(\n allowedMethods = ['GET', 'HEAD', 'OPTIONS'],\n): HttpInterceptorFn {\n const CACHE_METHODS = new Set<string>(allowedMethods);\n\n return (\n req: HttpRequest<unknown>,\n next: HttpHandlerFn,\n ): Observable<HttpEvent<unknown>> => {\n const cache = injectQueryCache();\n\n if (!CACHE_METHODS.has(req.method)) return next(req);\n const opt = getCacheContext(req.context);\n\n if (!opt.cache) return next(req);\n\n const key = opt.key ?? req.urlWithParams;\n const entry = cache.getUntracked(key); // null if expired or not found\n\n // If the entry is not stale, return it\n if (entry && !entry.isStale) return of(entry.value);\n\n // resource itself handles case of showing stale data...the request must process as this will \"refresh said data\"\n\n const eTag = entry?.value.headers.get('ETag');\n const lastModified = entry?.value.headers.get('Last-Modified');\n\n if (eTag) {\n req = req.clone({ setHeaders: { 'If-None-Match': eTag } });\n }\n\n if (lastModified) {\n req = req.clone({ setHeaders: { 'If-Modified-Since': lastModified } });\n }\n\n if (opt.bustBrowserCache) {\n req = req.clone({\n setParams: { _cb: Date.now().toString() },\n });\n }\n\n return next(req).pipe(\n tap((event) => {\n if (event instanceof HttpResponse && 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 }\n }),\n map((event) => {\n // handle 304 responses due to eTag/last-modified\n if (event instanceof HttpResponse && event.status === 304 && entry) {\n return entry.value;\n }\n\n return event;\n }),\n );\n };\n}\n","import { HttpResourceRef } from '@angular/common/http';\nimport { computed } from '@angular/core';\nimport { toWritable } from '@mmstack/primitives';\n\nexport function catchValueError<T>(\n resource: HttpResourceRef<T>,\n fallback: T,\n): HttpResourceRef<T> {\n return {\n ...resource,\n value: toWritable(\n computed(() => {\n try {\n return resource.value();\n } catch {\n return fallback;\n }\n }),\n (value) => resource.value.set(value),\n ),\n };\n}\n","import {\n computed,\n effect,\n inject,\n InjectionToken,\n Injector,\n Provider,\n Signal,\n signal,\n untracked,\n} from '@angular/core';\n\n/**\n * Represents the possible states of a circuit breaker.\n * - `CLOSED`: The circuit breaker is closed, and operations are allowed to proceed.\n * - `OPEN`: The circuit breaker is open, and operations are blocked.\n * - `HALF_OPEN`: The circuit breaker is in a half-open state, allowing a limited number of operations to test if the underlying issue is resolved.\n */\ntype CircuitBreakerState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';\n\n/**\n * Represents a circuit breaker, which monitors operations and prevents failures from cascading.\n */\nexport type CircuitBreaker = {\n /**\n * A signal indicating whether the circuit breaker is currently closed (allowing operations).\n */\n isClosed: Signal<boolean>;\n /**\n * A signal indicating whether the circuit breaker is either open or in a half-open state.\n * This is useful for checking if operations are blocked.\n * If the circuit breaker is open, operations should not proceed.\n */\n isOpen: Signal<boolean>;\n /**\n * A signal representing the current state of the circuit breaker.\n */\n status: Signal<CircuitBreakerState>;\n /**\n * Signals a failure to the circuit breaker. This may cause the circuit breaker to open.\n */\n fail: (err?: Error) => void;\n /**\n * Signals a success to the circuit breaker. This may cause the circuit breaker to close.\n */\n success: () => void;\n /**\n * Attempts to transition the circuit breaker to the half-open state. This is typically used\n * to test if the underlying issue has been resolved after the circuit breaker has been open.\n */\n halfOpen: () => void;\n /**\n * 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 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 * @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 * - `{ treshold?: 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<CreateCircuitBreakerOptions> = {\n treshold: 5,\n timeout: 30000,\n shouldFail: () => true,\n shouldFailForever: () => false,\n};\n\n/** @internal */\nfunction internalCeateCircuitBreaker(\n treshold = 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\n const status = computed<CircuitBreakerState>(() => {\n if (failureCount() >= treshold) 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(treshold - 1);\n };\n\n let failForeverResetId: ReturnType<typeof setTimeout> | null = null;\n const effectRef = effect((cleanup) => {\n if (!isOpen()) return;\n\n const timeout = setTimeout(tryOnce, resetTimeout);\n failForeverResetId = timeout;\n return cleanup(() => {\n clearTimeout(timeout);\n failForeverResetId = null;\n });\n });\n\n const failInternal = () => {\n failureCount.set(failureCount() + 1);\n halfOpen.set(false);\n };\n\n const failForever = () => {\n if (failForeverResetId) clearTimeout(failForeverResetId);\n effectRef.destroy();\n failureCount.set(Infinity);\n halfOpen.set(false);\n return;\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 return {\n status,\n isClosed,\n isOpen,\n fail,\n success,\n halfOpen: tryOnce,\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 destroy: () => {\n // noop\n },\n };\n}\n\nconst CB_DEFAULT_OPTIONS = new InjectionToken<\n Required<CreateCircuitBreakerOptions>\n>('MMSTACK_CIRCUIT_BREAKER_DEFAULT_OPTIONS');\n\nexport function provideCircuitBreakerDefaultOptions(\n options: CircuitBreakerOptions,\n): Provider {\n return {\n provide: CB_DEFAULT_OPTIONS,\n useValue: {\n ...DEFAULT_OPTIONS,\n ...options,\n },\n };\n}\n\nfunction injectCircuitBreakerOptions(\n injector = inject(Injector),\n): Required<CreateCircuitBreakerOptions> {\n return injector.get(CB_DEFAULT_OPTIONS, DEFAULT_OPTIONS, {\n optional: true,\n });\n}\n\n/**\n * Creates a circuit breaker instance.\n *\n * @param options - Configuration options for the circuit breaker. Can be:\n * - `undefined`: Creates a \"no-op\" circuit breaker that is always open (never trips).\n * - `true`: Creates a circuit breaker with default settings (threshold: 5, timeout: 30000ms).\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 { treshold, timeout, shouldFail, shouldFailForever } = {\n ...injectCircuitBreakerOptions(injector),\n ...opt,\n };\n\n return internalCeateCircuitBreaker(\n treshold,\n timeout,\n shouldFail,\n shouldFailForever,\n );\n}\n","// Heavily inspired by: https://dev.to/kasual1/request-deduplication-in-angular-3pd8\n\nimport {\n HttpContext,\n HttpContextToken,\n HttpInterceptorFn,\n type HttpEvent,\n type HttpHandlerFn,\n type HttpRequest,\n} from '@angular/common/http';\nimport { finalize, shareReplay, type Observable } from 'rxjs';\n\nconst NO_DEDUPE = new HttpContextToken<boolean>(() => false);\n\n/**\n * Disables request deduplication for a specific HTTP request.\n *\n * @param ctx - The `HttpContext` to modify. If not provided, a new `HttpContext` is created.\n * @returns The modified `HttpContext` with the `NO_DEDUPE` token set to `true`.\n *\n * @example\n * // Disable deduplication for a specific POST request:\n * const context = noDedupe();\n * this.http.post('/api/data', payload, { context }).subscribe(...);\n *\n * // Disable deduplication, modifying an existing context:\n * let context = new HttpContext();\n * context = noDedupe(context);\n * this.http.post('/api/data', payload, { context }).subscribe(...);\n */\nexport function noDedupe(ctx: HttpContext = new HttpContext()) {\n return ctx.set(NO_DEDUPE, true);\n}\n\n/**\n * Creates an `HttpInterceptorFn` that deduplicates identical HTTP requests.\n * If multiple identical requests (same URL and parameters) are made concurrently,\n * only the first request will be sent to the server. Subsequent requests will\n * receive the response from the first request.\n *\n * @param allowed - An array of HTTP methods for which deduplication should be enabled.\n * Defaults to `['GET', 'DELETE', 'HEAD', 'OPTIONS']`.\n *\n * @returns An `HttpInterceptorFn` that implements the request deduplication logic.\n *\n * @example\n * // In your app.config.ts or module providers:\n * import { provideHttpClient, withInterceptors } from '@angular/common/http';\n * import { createDedupeRequestsInterceptor } from './your-dedupe-interceptor';\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([createDedupeRequestsInterceptor()])),\n * // ... other providers\n * ],\n * };\n *\n * // You can also specify which methods should be deduped\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([createDedupeRequestsInterceptor(['GET'])])), // only dedupe GET calls\n * // ... other providers\n * ],\n * };\n */\nexport function createDedupeRequestsInterceptor(\n allowed = ['GET', 'DELETE', 'HEAD', 'OPTIONS'],\n): HttpInterceptorFn {\n const inFlight = new Map<string, Observable<HttpEvent<unknown>>>();\n\n const DEDUPE_METHODS = new Set<string>(allowed);\n\n return (\n req: HttpRequest<unknown>,\n next: HttpHandlerFn,\n ): Observable<HttpEvent<unknown>> => {\n if (!DEDUPE_METHODS.has(req.method) || req.context.get(NO_DEDUPE))\n return next(req);\n\n const found = inFlight.get(req.urlWithParams);\n\n if (found) return found;\n\n const request = next(req).pipe(\n finalize(() => inFlight.delete(req.urlWithParams)),\n shareReplay(),\n );\n inFlight.set(req.urlWithParams, request);\n\n return request;\n };\n}\n","import {\n HttpContext,\n HttpHeaders,\n HttpParams,\n HttpResourceRequest,\n} from '@angular/common/http';\nimport { type ValueEqualityFn } from '@angular/core';\n\ntype UnknownObject = Record<PropertyKey, unknown>;\n\n/**\n * Checks if `value` is a plain JavaScript object (e.g., `{}` or `new Object()`).\n * Distinguishes from arrays, null, and class instances. Acts as a type predicate,\n * narrowing `value` to `UnknownObject` if `true`.\n *\n * @param value The value to check.\n * @returns {value is UnknownObject} `true` if `value` is a plain object, otherwise `false`.\n * @example\n * isPlainObject({}) // => true\n * isPlainObject([]) // => false\n * isPlainObject(null) // => false\n * isPlainObject(new Date()) // => false\n */\nfunction isPlainObject(value: unknown): value is UnknownObject {\n if (value === null || typeof value !== 'object') return false;\n const proto = Object.getPrototypeOf(value);\n if (proto === null) return false; // remove Object.create(null);\n return proto === Object.prototype;\n}\n\n/**\n * Internal helper to generate a stable JSON string from an array.\n * Sorts keys of plain objects within the array alphabetically before serialization\n * to ensure hash stability regardless of key order.\n *\n * @param queryKey The array of values to serialize.\n * @returns A stable JSON string representation.\n * @internal\n */\nfunction hashKey(queryKey: unknown[]): string {\n return JSON.stringify(queryKey, (_, val) =>\n isPlainObject(val)\n ? Object.keys(val)\n .toSorted()\n .reduce((result, key) => {\n result[key] = val[key];\n return result;\n }, {} as UnknownObject)\n : val,\n );\n}\n\n/**\n * Generates a stable, unique string hash from one or more arguments.\n * Useful for creating cache keys or identifiers where object key order shouldn't matter.\n *\n * How it works:\n * - Plain objects within the arguments have their keys sorted alphabetically before hashing.\n * This ensures that `{ a: 1, b: 2 }` and `{ b: 2, a: 1 }` produce the same hash.\n * - Uses `JSON.stringify` internally with custom sorting for plain objects via `hashKey`.\n * - Non-plain objects (arrays, Dates, etc.) and primitives are serialized naturally.\n *\n * @param {...unknown} args Values to include in the hash.\n * @returns A stable string hash representing the input arguments.\n * @example\n * const userQuery = (id: number) => ['user', { id, timestamp: Date.now() }];\n *\n * const obj1 = { a: 1, b: 2 };\n * const obj2 = { b: 2, a: 1 }; // Same keys/values, different order\n *\n * hash('posts', 10);\n * // => '[\"posts\",10]'\n *\n * hash('config', obj1);\n * // => '[\"config\",{\"a\":1,\"b\":2}]'\n *\n * hash('config', obj2);\n * // => '[\"config\",{\"a\":1,\"b\":2}]' (Same as above due to key sorting)\n *\n * hash(['todos', { status: 'done', owner: obj1 }]);\n * // => '[[\"todos\",{\"owner\":{\"a\":1,\"b\":2},\"status\":\"done\"}]]'\n *\n * // Be mindful of values JSON.stringify cannot handle (functions, undefined, Symbols)\n * // hash('a', undefined, function() {}) => '[\"a\",null,null]'\n */\nfunction hash(...args: unknown[]): string {\n return hashKey(args);\n}\n\nfunction equalTransferCache(\n a: HttpResourceRequest['transferCache'],\n b: HttpResourceRequest['transferCache'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n if (typeof a !== typeof b) return false;\n if (typeof a === 'boolean' || typeof b === 'boolean') return a === b;\n\n if (!a.includeHeaders && !b.includeHeaders) return true;\n if (!a.includeHeaders || !b.includeHeaders) return false;\n\n if (a.includeHeaders.length !== b.includeHeaders.length) return false;\n\n if (a.includeHeaders.length === 0) return true;\n\n const aSet = new Set(a.includeHeaders ?? []);\n\n return b.includeHeaders.every((header) => aSet.has(header));\n}\n\nfunction equalParamArray(\n a: Array<string | number | boolean>,\n b: Array<string | number | boolean>,\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n if (a.length !== b.length) return false;\n\n return a.every((value) => b.includes(value));\n}\n\nfunction headersToObject(headerClass: HttpHeaders) {\n const headers: Exclude<\n Required<HttpResourceRequest['headers']>,\n HttpHeaders | undefined\n > = {};\n\n headerClass.keys().forEach((key) => {\n const value = headerClass.getAll(key);\n if (value === null) return;\n if (value.length === 1) {\n headers[key] = value[0];\n } else {\n headers[key] = value;\n }\n });\n\n return headers;\n}\n\nfunction paramToObject(paramsClass: HttpParams) {\n const params: Exclude<\n Required<HttpResourceRequest['params']>,\n HttpParams | undefined\n > = {};\n\n paramsClass.keys().forEach((key) => {\n const value = paramsClass.getAll(key);\n if (value === null) return;\n if (value.length === 1) {\n params[key] = value[0];\n } else {\n params[key] = value;\n }\n });\n\n return params;\n}\n\nfunction equalParams(\n a: HttpResourceRequest['params'],\n b: HttpResourceRequest['params'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n const aObj = a instanceof HttpParams ? paramToObject(a) : a;\n const bObj = b instanceof HttpParams ? paramToObject(b) : b;\n\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n if (aKeys.length !== bKeys.length) return false;\n\n return aKeys.every((key) => {\n if (Array.isArray(aObj[key]) || Array.isArray(bObj[key])) {\n return equalParamArray(\n Array.isArray(aObj[key]) ? aObj[key] : [aObj[key]],\n Array.isArray(bObj[key]) ? bObj[key] : [bObj[key]],\n );\n }\n\n return aObj[key] === bObj[key];\n });\n}\n\nfunction equalBody(\n a: HttpResourceRequest['body'],\n b: HttpResourceRequest['body'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n return hash(a) === hash(b);\n}\n\nfunction equalHeaders(\n a: HttpResourceRequest['headers'],\n b: HttpResourceRequest['headers'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n const aObj = a instanceof HttpHeaders ? headersToObject(a) : a;\n const bObj = b instanceof HttpHeaders ? headersToObject(b) : b;\n\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n if (aKeys.length !== bKeys.length) return false;\n return aKeys.every((key) => {\n if (Array.isArray(aObj[key]) || Array.isArray(bObj[key])) {\n return equalParamArray(\n Array.isArray(aObj[key]) ? aObj[key] : [aObj[key]],\n Array.isArray(bObj[key]) ? bObj[key] : [bObj[key]],\n );\n }\n\n return aObj[key] === bObj[key];\n });\n}\n\nfunction toHttpContextEntries(ctx: HttpResourceRequest['context']) {\n if (!ctx) return [];\n\n if (ctx instanceof HttpContext) {\n const tokens = Array.from(ctx.keys());\n return tokens.map((key) => [key.toString(), ctx.get(key)] as const);\n }\n\n if (typeof ctx === 'object') {\n return Object.entries(ctx) as Array<[string, unknown]>;\n }\n\n return [];\n}\n\nfunction equalContext(\n a: HttpResourceRequest['context'],\n b: HttpResourceRequest['context'],\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n const aEntries = toHttpContextEntries(a);\n const bEntries = toHttpContextEntries(b);\n if (aEntries.length !== bEntries.length) return false;\n if (aEntries.length === 0) return true;\n const bMap = new Map(bEntries);\n return aEntries.every(([key, value]) => value === bMap.get(key));\n}\n\nexport function createEqualRequest<TResult>(\n equalResult?: ValueEqualityFn<TResult>,\n) {\n const eqb = equalResult ?? equalBody;\n\n return (\n a: Partial<HttpResourceRequest> | undefined,\n b: Partial<HttpResourceRequest> | undefined,\n ) => {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n if (a.url !== b.url) return false;\n if (a.method !== b.method) return false;\n if (!equalParams(a.params, b.params)) return false;\n if (!equalHeaders(a.headers, b.headers)) return false;\n if (!eqb(a.body as TResult, b.body as TResult)) return false;\n if (!equalContext(a.context, b.context)) return false;\n\n if (a.withCredentials !== b.withCredentials) return false;\n if (a.reportProgress !== b.reportProgress) return false;\n if (!equalTransferCache(a.transferCache, b.transferCache)) return false;\n\n return true;\n };\n}\n","export function hasSlowConnection() {\n if (\n window &&\n 'navigator' in window &&\n 'connection' in window.navigator &&\n typeof window.navigator.connection === 'object' &&\n !!window.navigator.connection &&\n 'effectiveType' in window.navigator.connection &&\n typeof window.navigator.connection.effectiveType === 'string'\n )\n return window.navigator.connection.effectiveType.endsWith('2g');\n\n return false;\n}\n","import { type HttpHeaders, type HttpResourceRef } from '@angular/common/http';\nimport {\n linkedSignal,\n type Signal,\n type ValueEqualityFn,\n type WritableSignal,\n} from '@angular/core';\n\nfunction persist<T>(\n value: WritableSignal<T>,\n equal?: ValueEqualityFn<T>,\n): WritableSignal<T>;\n\nfunction persist<T>(value: Signal<T>, equal?: ValueEqualityFn<T>): Signal<T>;\n\nfunction persist<T>(\n src: WritableSignal<T> | Signal<T>,\n equal?: ValueEqualityFn<T>,\n): WritableSignal<T> | Signal<T> {\n // linkedSignal allows us to access previous source value\n\n const persisted = linkedSignal<T, T>({\n source: () => src(),\n computation: (next, prev) => {\n if (next === undefined && prev !== undefined) return prev.value;\n return next;\n },\n equal,\n });\n\n // if original value was WritableSignal then override linkedSignal methods to original...angular uses linkedSignal under the hood in ResourceImpl, this applies to that.\n if ('set' in src) {\n persisted.set = src.set;\n persisted.update = src.update;\n persisted.asReadonly = src.asReadonly;\n }\n\n return persisted;\n}\n\nexport function persistResourceValues<T>(\n resource: HttpResourceRef<T>,\n shouldPersist = false,\n equal?: ValueEqualityFn<T>,\n): HttpResourceRef<T> {\n if (!shouldPersist) return resource;\n\n return {\n ...resource,\n statusCode: persist<number | undefined>(resource.statusCode),\n headers: persist<HttpHeaders | undefined>(resource.headers),\n value: persist<T>(resource.value, equal),\n };\n}\n","import { HttpResourceRef } from '@angular/common/http';\nimport { DestroyRef } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { interval } from 'rxjs';\n\n// refresh resource every n miliseconds or don't refresh if undefined provided. 0 also excluded, due to it not being a valid usecase\nexport function refresh<T>(\n resource: HttpResourceRef<T>,\n destroyRef: DestroyRef,\n refresh?: number,\n): HttpResourceRef<T> {\n if (!refresh) return resource; // no refresh requested\n\n // we can use RxJs here as reloading the resource will always be a side effect & as such does not impact the reactive graph in any way.\n let sub = interval(refresh)\n .pipe(takeUntilDestroyed(destroyRef))\n .subscribe(() => resource.reload());\n\n const reload = (): boolean => {\n sub.unsubscribe(); // do not conflict with manual reload\n\n const hasReloaded = resource.reload();\n\n // resubscribe after manual reload\n sub = interval(refresh)\n .pipe(takeUntilDestroyed(destroyRef))\n .subscribe(() => resource.reload());\n\n return hasReloaded;\n };\n\n return {\n ...resource,\n reload,\n destroy: () => {\n sub.unsubscribe();\n resource.destroy();\n },\n };\n}\n","import { type HttpResourceRef } from '@angular/common/http';\nimport { effect } from '@angular/core';\n\nexport type RetryOptions =\n | number\n | {\n max?: number;\n backoff?: number;\n };\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): 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 onError = () => {\n if (retries >= max) return;\n retries++;\n\n if (timeout) clearTimeout(timeout);\n\n setTimeout(\n () => res.reload(),\n retries <= 0 ? 0 : backoff * Math.pow(2, retries - 1),\n );\n };\n\n const onSuccess = () => {\n if (timeout) clearTimeout(timeout);\n retries = 0;\n };\n\n const ref = effect(() => {\n switch (res.status()) {\n case 'error':\n return onError();\n case 'resolved':\n return onSuccess();\n }\n });\n\n return {\n ...res,\n destroy: () => {\n ref.destroy(); // cleanup on manual destroy\n res.destroy();\n },\n };\n}\n","import { inject, Injectable } from '@angular/core';\nimport { sensor } from '@mmstack/primitives';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ResourceSensors {\n readonly networkStatus = sensor('networkStatus');\n}\n\nexport function injectNetworkStatus() {\n return inject(ResourceSensors).networkStatus;\n}\n","import { HttpResourceRef } from '@angular/common/http';\n\nexport function toResourceObject<T>(\n res: HttpResourceRef<T>,\n): HttpResourceRef<T> {\n return {\n asReadonly: () => res.asReadonly(),\n destroy: () => res.destroy(),\n error: res.error,\n headers: res.headers,\n isLoading: res.isLoading,\n progress: res.progress,\n status: res.status,\n statusCode: res.statusCode,\n value: res.value,\n reload: () => res.reload(),\n hasValue: (() => res.hasValue()) as HttpResourceRef<T>['hasValue'],\n set: (v) => res.set(v),\n update: (v) => res.update(v),\n };\n}\n","import { HttpParams, type HttpResourceRequest } from '@angular/common/http';\n\nfunction normalizeParams(\n params: Required<HttpResourceRequest>['params'],\n): string {\n if (params instanceof HttpParams) return params.toString();\n\n const paramMap = new Map<string, string>();\n\n for (const [key, value] of Object.entries(params)) {\n if (Array.isArray(value)) {\n paramMap.set(key, value.map(encodeURIComponent).join(','));\n } else {\n paramMap.set(key, encodeURIComponent(value.toString()));\n }\n }\n\n return Array.from(paramMap.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, value]) => `${key}=${value}`)\n .join('&');\n}\n\nexport function urlWithParams(req: HttpResourceRequest): string {\n if (!req.params) return req.url;\n\n return `${req.url}?${normalizeParams(req.params)}`;\n}\n","import {\n HttpClient,\n HttpHeaders,\n httpResource,\n HttpResponse,\n type HttpResourceOptions,\n type HttpResourceRef,\n type HttpResourceRequest,\n} from '@angular/common/http';\nimport {\n computed,\n DestroyRef,\n effect,\n inject,\n isDevMode,\n linkedSignal,\n Signal,\n untracked,\n WritableSignal,\n} from '@angular/core';\nimport { toWritable } from '@mmstack/primitives';\nimport { firstValueFrom } from 'rxjs';\nimport {\n catchValueError,\n CircuitBreakerOptions,\n createCircuitBreaker,\n createEqualRequest,\n hasSlowConnection,\n injectNetworkStatus,\n injectQueryCache,\n persistResourceValues,\n refresh,\n retryOnError,\n setCacheContext,\n toResourceObject,\n urlWithParams,\n type RetryOptions,\n} from './util';\nimport { CacheEntry } from './util/cache/cache';\n\n/**\n * Options for configuring caching behavior of a `queryResource`.\n * - `true`: Enables caching with default settings.\n * - `{ ttl?: number; staleTime?: number; hash?: (req: HttpResourceRequest) => string; }`: Configures caching with custom settings.\n */\ntype ResourceCacheOptions =\n | true\n | {\n /**\n * The Time To Live (TTL) for the cached data, in milliseconds. After this time, the cached data is\n * considered expired and will be refetched.\n */\n ttl?: number;\n /**\n * The duration, in milliseconds, during which stale data can be served while a revalidation request\n * is made in the background.\n */\n staleTime?: number;\n /**\n * A custom function to generate the cache key. Defaults to using the request URL with parameters.\n * Provide a custom hash function if you need more control over how cache keys are generated,\n * for instance, to ignore certain query parameters or to use request body for the cache key.\n */\n hash?: (req: HttpResourceRequest) => string;\n /**\n * Whether to bust the browser cache by appending a unique query parameter to the request URL.\n * This is useful for ensuring that the latest data is fetched from the server, bypassing any\n * cached responses in the browser. The unique parameter is removed before calling the cache function, so it does not affect the cache key.\n * @default false - By default, the resource will not bust the browser cache.\n */\n bustBrowserCache?: boolean;\n /**\n * Whether to ignore the `Cache-Control` headers from the server when caching responses.\n * If set to `true`, the resource will not respect any cache directives from the server,\n * allowing you to control caching behavior entirely through the resource options.\n * @default false - By default the resource will respect `Cache-Control` headers.\n */\n ignoreCacheControl?: boolean;\n /**\n * Whether to persist the cache entry in the local DB instance.\n * @default false - By default, the cache entry is not persisted.\n */\n persist?: boolean;\n };\n\n/**\n * Options for configuring a `queryResource`.\n */\nexport type QueryResourceOptions<TResult, TRaw = TResult> = HttpResourceOptions<\n TResult,\n TRaw\n> & {\n /**\n * Whether to keep the previous value of the resource while a refresh is in progress.\n * Defaults to `false`. Also keeps status & headers while refreshing.\n */\n keepPrevious?: boolean;\n /**\n * The refresh interval, in milliseconds. If provided, the resource will automatically\n * refresh its data at the specified interval.\n */\n refresh?: number;\n /**\n * Options for retrying failed requests.\n */\n retry?: RetryOptions;\n /**\n * An optional error handler callback. This function will be called whenever the\n * underlying HTTP request fails. Useful for displaying toasts or other error messages.\n */\n onError?: (err: unknown) => void;\n /**\n * Options for configuring a circuit breaker for the resource.\n */\n circuitBreaker?: CircuitBreakerOptions | true;\n /**\n * Options for enabling and configuring caching for the resource.\n */\n cache?: ResourceCacheOptions;\n /**\n * Trigger a request every time the request function is triggered, even if the request parameters are the same.\n * @default false\n */\n triggerOnSameRequest?: boolean;\n};\n\n/**\n * Represents a resource created by `queryResource`. Extends `HttpResourceRef` with additional properties.\n */\nexport type QueryResourceRef<TResult> = Omit<\n HttpResourceRef<TResult>,\n 'headers' | 'statusCode'\n> & {\n /**\n * Linkedsignal of the response headers, when available.\n */\n readonly headers: WritableSignal<HttpHeaders | undefined>;\n /**\n * Linkedsignal of the response status code, when available.\n */\n readonly statusCode: WritableSignal<number | undefined>;\n /**\n * A signal indicating whether the resource is currently disabled (due to circuit breaker or undefined request).\n */\n disabled: Signal<boolean>;\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>) => Promise<void>;\n};\n\nexport function queryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | undefined | void,\n options: QueryResourceOptions<TResult, TRaw> & {\n defaultValue: NoInfer<TResult>;\n },\n): QueryResourceRef<TResult>;\n\n/**\n * Creates an extended HTTP resource with features like caching, retries, refresh intervals,\n * circuit breaker, and optimistic updates. Without additional options it is equivalent to simply calling `httpResource`.\n *\n * @param request A function that returns the `HttpResourceRequest` to be made. This function\n * is called reactively, so the request can change over time. If the function\n * returns `undefined`, the resource is considered \"disabled\" and no request will be made.\n * @param options Configuration options for the resource. These options extend the basic\n * `HttpResourceOptions` and add features like `keepPrevious`, `refresh`, `retry`,\n * `onError`, `circuitBreaker`, and `cache`.\n * @returns An `QueryResourceRef` instance, which extends the basic `HttpResourceRef` with additional features.\n */\nexport function queryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | undefined | void,\n options?: QueryResourceOptions<TResult, TRaw>,\n): QueryResourceRef<TResult | undefined>;\n\nexport function queryResource<TResult, TRaw = TResult>(\n request: () => HttpResourceRequest | undefined | void,\n options?: QueryResourceOptions<TResult, TRaw>,\n): QueryResourceRef<TResult | undefined> {\n const cache = injectQueryCache<TResult>(options?.injector);\n\n const destroyRef = options?.injector\n ? options.injector.get(DestroyRef)\n : inject(DestroyRef);\n\n const cb = createCircuitBreaker(\n options?.circuitBreaker === true\n ? undefined\n : (options?.circuitBreaker ?? false),\n options?.injector,\n );\n\n const networkAvailable = injectNetworkStatus();\n\n const eq = options?.triggerOnSameRequest\n ? undefined\n : createEqualRequest(options?.equal);\n\n const stableRequest = computed(\n () => {\n if (!networkAvailable() || cb.isOpen()) return undefined;\n return request() ?? undefined;\n },\n {\n equal: (a, b) => {\n if (eq) return eq(a, b);\n return a === b;\n },\n },\n );\n\n const hashFn =\n typeof options?.cache === 'object'\n ? (options.cache.hash ?? urlWithParams)\n : urlWithParams;\n\n const staleTime =\n typeof options?.cache === 'object' ? options.cache.staleTime : 0;\n const ttl =\n typeof options?.cache === 'object' ? options.cache.ttl : undefined;\n\n const cacheKey = computed(() => {\n const r = stableRequest();\n if (!r) return null;\n return hashFn(r);\n });\n\n const bustBrowserCache =\n typeof options?.cache === 'object' &&\n options.cache.bustBrowserCache === true;\n\n const ignoreCacheControl =\n typeof options?.cache === 'object' &&\n options.cache.ignoreCacheControl === true;\n\n const persist =\n typeof options?.cache === 'object' && options.cache.persist === true;\n\n const cachedRequest = options?.cache\n ? computed(() => {\n const r = stableRequest();\n if (!r) return r;\n\n return {\n ...r,\n context: setCacheContext(r.context, {\n staleTime,\n ttl,\n key: cacheKey() ?? hashFn(r),\n bustBrowserCache,\n ignoreCacheControl,\n persist,\n }),\n };\n })\n : stableRequest;\n\n let resource = toResourceObject(\n httpResource<TResult>(cachedRequest, {\n ...options,\n parse: options?.parse as any, // Not my favorite thing to do, but here it is completely safe.\n }) as HttpResourceRef<TResult>,\n );\n\n resource = catchValueError(resource, options?.defaultValue as TResult);\n\n // get full HttpResonse from Cache\n const cachedEvent = cache.getEntryOrKey(cacheKey);\n\n const cacheEntry = linkedSignal<\n CacheEntry<HttpResponse<TResult>> | string | null,\n { key: string; value: TResult | null } | null\n >({\n source: () => cachedEvent(),\n computation: (entry, prev) => {\n if (!entry) return null;\n\n if (\n typeof entry === 'string' &&\n prev &&\n prev.value !== null &&\n prev.value.key === entry\n ) {\n return prev.value;\n }\n\n if (typeof entry === 'string') return { key: entry, value: null };\n\n if (!(entry.value instanceof HttpResponse))\n return { key: entry.key, value: null };\n\n return {\n value: entry.value.body,\n key: entry.key,\n };\n },\n });\n\n resource = refresh(resource, destroyRef, options?.refresh);\n resource = retryOnError(resource, options?.retry);\n\n resource = persistResourceValues<TResult>(\n resource,\n options?.keepPrevious,\n options?.equal,\n );\n\n const value = options?.cache\n ? toWritable(\n computed((): TResult => {\n resource.value();\n return cacheEntry()?.value ?? resource.value();\n }),\n resource.value.set,\n resource.value.update,\n )\n : resource.value;\n\n const onError = options?.onError; // Put in own variable to ensure value remains even if options are somehow mutated in-line\n\n if (onError) {\n const onErrorRef = effect(() => {\n const err = resource.error();\n if (err) onError(err);\n });\n\n // cleanup on manual destroy, I'm comfortable setting these props in-line as we have yet to 'release' the object out of this lexical scope\n const destroyRest = resource.destroy;\n resource.destroy = () => {\n onErrorRef.destroy();\n destroyRest();\n };\n }\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 set = (value: TResult) => {\n resource.value.set(value);\n const k = untracked(cacheKey);\n if (options?.cache && k)\n cache.store(\n k,\n new HttpResponse({\n body: value,\n status: 200,\n statusText: 'OK',\n }),\n staleTime,\n ttl,\n persist,\n );\n };\n\n const update = (updater: (value: TResult) => TResult) => {\n set(updater(untracked(resource.value)));\n };\n\n const client = options?.injector\n ? options.injector.get(HttpClient)\n : inject(HttpClient);\n\n return {\n ...resource,\n value,\n set,\n update,\n statusCode: linkedSignal(resource.statusCode),\n headers: linkedSignal(resource.headers),\n disabled: computed(() => cb.isOpen() || stableRequest() === undefined),\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 prefetchRequest = {\n ...request,\n ...partial,\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","import { type HttpResourceRequest } from '@angular/common/http';\nimport {\n computed,\n DestroyRef,\n effect,\n inject,\n linkedSignal,\n Signal,\n signal,\n ValueEqualityFn,\n} from '@angular/core';\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\nimport { catchError, combineLatestWith, filter, map, of } from 'rxjs';\nimport {\n queryResource,\n type QueryResourceOptions,\n type QueryResourceRef,\n} from './query-resource';\nimport { createCircuitBreaker, createEqualRequest } from './util';\n\n/**\n * @internal\n * Helper type for inferring the request body type based on the HTTP method.\n */\ntype NextRequest<\n TMethod extends HttpResourceRequest['method'],\n TMutation,\n> = TMethod extends 'DELETE' | 'delete'\n ? Omit<HttpResourceRequest, 'body' | 'method'> & { method: TMethod }\n : Omit<HttpResourceRequest, 'body' | 'method'> & {\n body: TMutation;\n method: TMethod;\n };\n\n/**\n * @internal\n * Helper type for tracking mutation status.\n */\ntype StatusResult<TResult> =\n | {\n status: 'error';\n error: unknown;\n }\n | {\n status: 'resolved';\n value: TResult;\n };\n\n/**\n * Options for configuring a `mutationResource`.\n *\n * @typeParam TResult - The type of the expected result from the mutation.\n * @typeParam TRaw - The raw response type from the HTTP request (defaults to TResult).\n * @typeParam TCTX - The type of the context value returned by `onMutate`.\n */\nexport type MutationResourceOptions<\n TResult,\n TRaw = TResult,\n TMutation = TResult,\n TCTX = void,\n TICTX = TCTX,\n> = 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: unknown, 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: NoInfer<TResult>, ctx: NoInfer<TCTX>) => void;\n /**\n * A callback function that is called when the mutation request settles (either succeeds or fails).\n * @param ctx The context value returned by the `onMutate` callback (or `undefined` if `onMutate` was not provided or returned `undefined`).\n */\n onSettled?: (ctx: NoInfer<TCTX>) => void;\n /**\n * Whether to queue the mutation requests and execute them in series. For example if network is unavailable or circuit breaker is open.\n * @default false\n */\n queue?: boolean;\n equal?: ValueEqualityFn<TMutation>;\n};\n\n/**\n * Represents a mutation resource created by `mutationResource`. Extends `QueryResourceRef`\n * but removes methods that don't make sense for mutations (like `prefetch`, `value`, etc.).\n *\n * @typeParam TResult - The type of the expected result from the mutation.\n */\nexport type MutationResourceRef<\n TResult,\n TMutation = TResult,\n TICTX = void,\n> = Omit<\n QueryResourceRef<TResult>,\n 'prefetch' | 'value' | 'hasValue' | 'set' | 'update' // we don't allow manually viewing the returned data or updating it manually, prefetching a mutation also doesn't make any sense\n> & {\n /**\n * Executes the mutation.\n *\n * @param value The mutation value (usually the request body).\n * @param ctx An optional initial context value that will be passed to the `onMutate` callback.\n */\n mutate: (value: TMutation, ctx?: TICTX) => void;\n /**\n * A signal that holds the current mutation request, or `null` if no mutation is in progress.\n * This can be useful for tracking the state of the mutation or for displaying loading indicators.\n */\n current: Signal<TMutation | null>;\n};\n\n/**\n * Creates a resource for performing mutations (e.g., POST, PUT, PATCH, DELETE requests).\n * Unlike `queryResource`, `mutationResource` is designed for one-off operations that change data.\n * It does *not* cache responses and does not provide a `value` signal. Instead, it focuses on\n * managing the mutation lifecycle (pending, error, success) and provides callbacks for handling\n * these states.\n *\n * @param request A function that returns the base `HttpResourceRequest` to be made. This function is called reactively. The parameter is the mutation value provided by the `mutate` method.\n * @param options Configuration options for the mutation resource. This includes callbacks\n * for `onMutate`, `onError`, `onSuccess`, and `onSettled`.\n * @typeParam TResult - The type of the expected result from the mutation.\n * @typeParam TRaw - The raw response type from the HTTP request (defaults to TResult).\n * @typeParam TMutation - The type of the mutation value (the request body).\n * @typeParam TICTX - The type of the initial context value passed to `onMutate`.\n * @typeParam TCTX - The type of the context value returned by `onMutate`.\n * @typeParam TMethod - The HTTP method to be used for the mutation (defaults to `HttpResourceRequest['method']`).\n * @returns A `MutationResourceRef` instance, which provides methods for triggering the mutation\n * and observing its status.\n */\nexport function mutationResource<\n TResult,\n TRaw = TResult,\n TMutation = TResult,\n TCTX = void,\n TICTX = TCTX,\n TMethod extends HttpResourceRequest['method'] = HttpResourceRequest['method'],\n>(\n request: (\n params: TMutation,\n ) => Omit<NextRequest<TMethod, TMutation>, 'body'> | undefined | void,\n options: MutationResourceOptions<TResult, TRaw, TMutation, TCTX, TICTX> = {},\n): MutationResourceRef<TResult, TMutation, TICTX> {\n const { onMutate, onError, onSuccess, onSettled, equal, ...rest } = options;\n\n const requestEqual = createEqualRequest(equal);\n\n const eq = equal ?? Object.is;\n const next = signal<TMutation | null>(null, {\n equal: (a, b) => {\n if (!a && !b) return true;\n if (!a || !b) return false;\n return eq(a, b);\n },\n });\n\n const queue = signal<[TMutation, TICTX | undefined][]>([]);\n\n let ctx: TCTX = undefined as TCTX;\n\n const queueRef = effect(() => {\n const nextInQueue = queue().at(0);\n if (!nextInQueue || next() !== null) return;\n queue.update((q) => q.slice(1));\n const [value, ictx] = nextInQueue;\n ctx = onMutate?.(value, ictx) as TCTX;\n next.set(value);\n });\n\n const req = computed(\n (): HttpResourceRequest | undefined => {\n const nr = next();\n if (!nr) return;\n\n return request(nr) ?? undefined;\n },\n {\n equal: requestEqual,\n },\n );\n\n const lastValue = linkedSignal<TMutation | null, TMutation | null>({\n source: next,\n computation: (next, prev) => {\n if (next === null && !!prev) return prev.value;\n return next;\n },\n });\n\n const lastValueRequest = computed(\n (): HttpResourceRequest | undefined => {\n const nr = lastValue();\n if (!nr) return;\n\n return request(nr) ?? undefined;\n },\n {\n equal: requestEqual,\n },\n );\n\n const cb = createCircuitBreaker(\n options?.circuitBreaker === true\n ? undefined\n : (options?.circuitBreaker ?? false),\n options?.injector,\n );\n\n const resource = queryResource<TResult, TRaw>(req, {\n ...rest,\n circuitBreaker: cb,\n defaultValue: null as unknown as TResult, // doesnt matter since .value is not accessible\n });\n\n const destroyRef = options.injector\n ? options.injector.get(DestroyRef)\n : inject(DestroyRef);\n\n const error$ = toObservable(resource.error);\n const value$ = toObservable(resource.value).pipe(catchError(() => of(null)));\n\n const statusSub = toObservable(resource.status)\n .pipe(\n combineLatestWith(error$, value$),\n map(([status, error, value]): StatusResult<TResult> | null => {\n if (status === 'error' && error) {\n return {\n status: 'error',\n error,\n };\n }\n\n if (status === 'resolved' && value !== null) {\n return {\n status: 'resolved',\n value,\n };\n }\n\n return null;\n }),\n filter((v) => v !== null),\n takeUntilDestroyed(destroyRef),\n )\n .subscribe((result) => {\n if (result.status === 'error') onError?.(result.error, ctx);\n else onSuccess?.(result.value, ctx);\n\n onSettled?.(ctx);\n ctx = undefined as TCTX;\n next.set(null);\n });\n\n const shouldQueue = options.queue ?? false;\n\n return {\n ...resource,\n destroy: () => {\n statusSub.unsubscribe();\n resource.destroy();\n queueRef.destroy();\n },\n mutate: (value, ictx) => {\n if (shouldQueue) {\n return queue.update((q) => [...q, [value, ictx]]);\n } else {\n ctx = onMutate?.(value, ictx) as TCTX;\n next.set(value);\n }\n },\n current: next,\n // redeclare disabled with last value so that it is not affected by the resource's internal disablement logic\n disabled: computed(() => cb.isOpen() || lastValueRequest() === undefined),\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmstack/resource",
3
- "version": "21.0.0",
3
+ "version": "21.0.2",
4
4
  "keywords": [
5
5
  "angular",
6
6
  "signals",
@@ -17,12 +17,12 @@
17
17
  },
18
18
  "homepage": "https://github.com/mihajm/mmstack/blob/master/packages/resource",
19
19
  "dependencies": {
20
- "@mmstack/primitives": "^20.0.0",
20
+ "@mmstack/primitives": "^21.0.0",
21
21
  "tslib": "^2.3.0"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "@angular/common": ">=21 <22",
25
- "@angular/core": ">=22 <22",
25
+ "@angular/core": ">=21 <22",
26
26
  "rxjs": "~7.8.2"
27
27
  },
28
28
  "sideEffects": false,