@mmstack/resource 20.2.10 → 20.2.11

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.
@@ -1,8 +1,9 @@
1
- import { isDevMode, untracked, computed, InjectionToken, inject, signal, effect, Injector, linkedSignal, DestroyRef } from '@angular/core';
1
+ import * as i0 from '@angular/core';
2
+ import { isDevMode, untracked, computed, InjectionToken, inject, signal, effect, Injector, linkedSignal, Injectable, DestroyRef } from '@angular/core';
2
3
  import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
3
4
  import { of, tap, map, finalize, shareReplay, interval, firstValueFrom, catchError, combineLatestWith, filter } from 'rxjs';
4
5
  import { HttpHeaders, HttpResponse, HttpContextToken, HttpContext, HttpParams, httpResource, HttpClient } from '@angular/common/http';
5
- import { mutable, toWritable } from '@mmstack/primitives';
6
+ import { mutable, toWritable, sensor } from '@mmstack/primitives';
6
7
  import { v7 } from 'uuid';
7
8
  import { keys, hash, entries } from '@mmstack/object';
8
9
 
@@ -1173,6 +1174,21 @@ function retryOnError(res, opt) {
1173
1174
  };
1174
1175
  }
1175
1176
 
1177
+ class ResourceSensors {
1178
+ networkStatus = sensor('networkStatus');
1179
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ResourceSensors, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1180
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ResourceSensors, providedIn: 'root' });
1181
+ }
1182
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ResourceSensors, decorators: [{
1183
+ type: Injectable,
1184
+ args: [{
1185
+ providedIn: 'root',
1186
+ }]
1187
+ }] });
1188
+ function injectNetworkStatus() {
1189
+ return inject(ResourceSensors).networkStatus;
1190
+ }
1191
+
1176
1192
  function toResourceObject(res) {
1177
1193
  return {
1178
1194
  asReadonly: () => res.asReadonly(),
@@ -1222,16 +1238,24 @@ function queryResource(request, options) {
1222
1238
  const cb = createCircuitBreaker(options?.circuitBreaker === true
1223
1239
  ? undefined
1224
1240
  : (options?.circuitBreaker ?? false), options?.injector);
1241
+ const networkAvailable = injectNetworkStatus();
1242
+ const eq = options?.triggerOnSameRequest
1243
+ ? undefined
1244
+ : createEqualRequest(options?.equal);
1225
1245
  const stableRequest = computed(() => {
1226
- if (cb.isOpen())
1246
+ if (!networkAvailable() || cb.isOpen())
1227
1247
  return undefined;
1228
1248
  return request() ?? undefined;
1229
- }, ...(ngDevMode ? [{ debugName: "stableRequest", equal: options?.triggerOnSameRequest
1230
- ? undefined
1231
- : createEqualRequest(options?.equal) }] : [{
1232
- equal: options?.triggerOnSameRequest
1233
- ? undefined
1234
- : createEqualRequest(options?.equal),
1249
+ }, ...(ngDevMode ? [{ debugName: "stableRequest", equal: (a, b) => {
1250
+ if (eq)
1251
+ return eq(a, b);
1252
+ return a === b;
1253
+ } }] : [{
1254
+ equal: (a, b) => {
1255
+ if (eq)
1256
+ return eq(a, b);
1257
+ return a === b;
1258
+ },
1235
1259
  }]));
1236
1260
  const hashFn = typeof options?.cache === 'object'
1237
1261
  ? (options.cache.hash ?? urlWithParams)
@@ -1301,6 +1325,7 @@ function queryResource(request, options) {
1301
1325
  resource = persistResourceValues(resource, options?.keepPrevious, options?.equal);
1302
1326
  const value = options?.cache
1303
1327
  ? toWritable(computed(() => {
1328
+ resource.value();
1304
1329
  return cacheEntry()?.value ?? resource.value();
1305
1330
  }), resource.value.set, resource.value.update)
1306
1331
  : resource.value;
@@ -1447,6 +1472,17 @@ function mutationResource(request, options = {}) {
1447
1472
  return eq(a, b);
1448
1473
  },
1449
1474
  }]));
1475
+ const queue = signal([], ...(ngDevMode ? [{ debugName: "queue" }] : []));
1476
+ let ctx = undefined;
1477
+ const queueRef = effect(() => {
1478
+ const nextInQueue = queue().at(0);
1479
+ if (!nextInQueue || next() !== null)
1480
+ return;
1481
+ queue.update((q) => q.slice(1));
1482
+ const [value, ictx] = nextInQueue;
1483
+ ctx = onMutate?.(value, ictx);
1484
+ next.set(value);
1485
+ }, ...(ngDevMode ? [{ debugName: "queueRef" }] : []));
1450
1486
  const req = computed(() => {
1451
1487
  const nr = next();
1452
1488
  if (!nr)
@@ -1479,7 +1515,6 @@ function mutationResource(request, options = {}) {
1479
1515
  circuitBreaker: cb,
1480
1516
  defaultValue: null, // doesnt matter since .value is not accessible
1481
1517
  });
1482
- let ctx = undefined;
1483
1518
  const destroyRef = options.injector
1484
1519
  ? options.injector.get(DestroyRef)
1485
1520
  : inject(DestroyRef);
@@ -1510,15 +1545,22 @@ function mutationResource(request, options = {}) {
1510
1545
  ctx = undefined;
1511
1546
  next.set(null);
1512
1547
  });
1548
+ const shouldQueue = options.queue ?? false;
1513
1549
  return {
1514
1550
  ...resource,
1515
1551
  destroy: () => {
1516
1552
  statusSub.unsubscribe();
1517
1553
  resource.destroy();
1554
+ queueRef.destroy();
1518
1555
  },
1519
1556
  mutate: (value, ictx) => {
1520
- ctx = onMutate?.(value, ictx);
1521
- next.set(value);
1557
+ if (shouldQueue) {
1558
+ return queue.update((q) => [...q, [value, ictx]]);
1559
+ }
1560
+ else {
1561
+ ctx = onMutate?.(value, ictx);
1562
+ next.set(value);
1563
+ }
1522
1564
  },
1523
1565
  current: next,
1524
1566
  // redeclare disabled with last value so that it is not affected by the resource's internal disablement logic