@angular-architects/ngrx-toolkit 20.6.0 → 21.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, InjectionToken, signal, effect, inject, PLATFORM_ID, NgZone, computed, isSignal, untracked, isDevMode as isDevMode$1, DestroyRef, linkedSignal } from '@angular/core';
3
- import { watchState, getState, signalStoreFeature, withMethods, withHooks, patchState as patchState$1, withState, withComputed, withProps, withLinkedState } from '@ngrx/signals';
2
+ import { Injectable, InjectionToken, signal, effect, inject, PLATFORM_ID, NgZone, untracked, computed, isSignal, isDevMode as isDevMode$1, DestroyRef, linkedSignal } from '@angular/core';
3
+ import { watchState, getState, signalStoreFeature, withMethods, withProps, withHooks, patchState as patchState$1, type, withState, withComputed, withLinkedState } from '@ngrx/signals';
4
4
  import { isPlatformBrowser, isPlatformServer } from '@angular/common';
5
- import { Subject, switchMap, mergeMap, concatMap, exhaustMap, defer, tap, catchError, EMPTY, finalize, filter, map } from 'rxjs';
5
+ import { withEventHandlers, ReducerEvents } from '@ngrx/signals/events';
6
+ import { tap } from 'rxjs/operators';
7
+ import { Subject, switchMap, mergeMap, concatMap, exhaustMap, defer, tap as tap$1, catchError, EMPTY, finalize, filter, map } from 'rxjs';
6
8
  import { removeEntity, setAllEntities, updateEntity, addEntity } from '@ngrx/signals/entities';
7
9
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
10
  import { HttpClient, HttpEventType, HttpResponse } from '@angular/common/http';
@@ -92,14 +94,15 @@ class GlitchTrackerService {
92
94
  this.#callback({ [id]: getState(this.#stores[id].store) });
93
95
  }
94
96
  }
95
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: GlitchTrackerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
96
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: GlitchTrackerService, providedIn: 'root' }); }
97
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GlitchTrackerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
98
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GlitchTrackerService, providedIn: 'root' }); }
97
99
  }
98
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: GlitchTrackerService, decorators: [{
100
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GlitchTrackerService, decorators: [{
99
101
  type: Injectable,
100
102
  args: [{ providedIn: 'root' }]
101
103
  }] });
102
104
 
105
+ const GLITCH_TRACKING_FEATURE = 'GLITCH_TRACKING_FEATURE';
103
106
  /**
104
107
  * It tracks all state changes of the State, including intermediary updates
105
108
  * that are typically suppressed by Angular's glitch-free mechanism.
@@ -130,7 +133,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
130
133
  * Without `withGlitchTracking`, the DevTools would only show the final value of 3.
131
134
  */
132
135
  function withGlitchTracking() {
133
- return createDevtoolsFeature({ tracker: GlitchTrackerService });
136
+ return createDevtoolsFeature({
137
+ name: GLITCH_TRACKING_FEATURE,
138
+ tracker: GlitchTrackerService,
139
+ });
134
140
  }
135
141
 
136
142
  /**
@@ -218,10 +224,10 @@ class DefaultTracker {
218
224
  });
219
225
  }
220
226
  }
221
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: DefaultTracker, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
222
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: DefaultTracker, providedIn: 'root' }); }
227
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DefaultTracker, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
228
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DefaultTracker, providedIn: 'root' }); }
223
229
  }
224
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: DefaultTracker, decorators: [{
230
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DefaultTracker, decorators: [{
225
231
  type: Injectable,
226
232
  args: [{ providedIn: 'root' }]
227
233
  }] });
@@ -388,17 +394,18 @@ Enable automatic indexing via withDevTools('${storeName}', { indexNames: true })
388
394
  }, {});
389
395
  this.#trackers.forEach((tracker) => tracker.notifyRenamedStore(id));
390
396
  }
391
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: DevtoolsSyncer, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
392
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: DevtoolsSyncer, providedIn: 'root' }); }
397
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DevtoolsSyncer, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
398
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DevtoolsSyncer, providedIn: 'root' }); }
393
399
  }
394
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: DevtoolsSyncer, decorators: [{
400
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DevtoolsSyncer, decorators: [{
395
401
  type: Injectable,
396
402
  args: [{ providedIn: 'root' }]
397
403
  }], ctorParameters: () => [] });
398
404
 
399
405
  const renameDevtoolsMethodName = '___renameDevtoolsName';
400
406
  const uniqueDevtoolsId = '___uniqueDevtoolsId';
401
- const EXISTING_NAMES = new InjectionToken('Array contain existing names for the signal stores', { factory: () => [], providedIn: 'root' });
407
+ // Used to declare the existence of the devtools extension
408
+ const DEVTOOL_FEATURE_NAMES = Symbol('DEVTOOL_PROP');
402
409
  /**
403
410
  * Adds this store as a feature state to the Redux DevTools.
404
411
  *
@@ -423,12 +430,13 @@ function withDevtools(name, ...features) {
423
430
  },
424
431
  [uniqueDevtoolsId]: () => id,
425
432
  };
426
- }), withHooks((store) => {
433
+ }), withProps(() => ({
434
+ [DEVTOOL_FEATURE_NAMES]: features.filter(Boolean).map((f) => f.name),
435
+ })), withHooks((store) => {
427
436
  const syncer = inject(DevtoolsSyncer);
428
437
  const id = String(store[uniqueDevtoolsId]());
429
438
  return {
430
439
  onInit() {
431
- const id = String(store[uniqueDevtoolsId]());
432
440
  const finalOptions = {
433
441
  indexNames: !features.some((f) => f.indexNames === false),
434
442
  map: features.find((f) => f.map)?.map ?? ((state) => state),
@@ -477,7 +485,31 @@ function updateState(stateSource, action, ...updaters) {
477
485
  /**
478
486
  * Stub for DevTools integration. Can be used to disable DevTools in production.
479
487
  */
480
- const withDevToolsStub = () => (store) => store;
488
+ const withDevToolsStub = () => signalStoreFeature(withProps(() => ({
489
+ [DEVTOOL_FEATURE_NAMES]: [GLITCH_TRACKING_FEATURE],
490
+ })));
491
+
492
+ function withTrackedReducer(
493
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
494
+ ...caseReducers) {
495
+ return signalStoreFeature({
496
+ state: type(),
497
+ }, withEventHandlers((store, events = inject(ReducerEvents)) => caseReducers.map((caseReducer) => events.on(...caseReducer.events).pipe(tap((event) => {
498
+ const state = untracked(() => getState(store));
499
+ const result = caseReducer.reducer(event, state);
500
+ const updaters = Array.isArray(result) ? result : [result];
501
+ updateState(store, event.type, ...updaters);
502
+ })))), withHooks((store) => ({
503
+ onInit() {
504
+ if (!(DEVTOOL_FEATURE_NAMES in store)) {
505
+ throw new Error(`In order to use withTrackedReducer, you must first enable the devtools feature via withDevtools('[your store name]', withGlitchTracking())`);
506
+ }
507
+ if (!store[DEVTOOL_FEATURE_NAMES].includes(GLITCH_TRACKING_FEATURE)) {
508
+ throw new Error(`In order to use withTrackedReducer, you must first enable the glitch tracking devtools feature via withDevtools('[your store name]', withGlitchTracking())`);
509
+ }
510
+ },
511
+ })));
512
+ }
481
513
 
482
514
  function assertActionFnSpecs(obj) {
483
515
  if (!obj || typeof obj !== 'object') {
@@ -677,6 +709,24 @@ function withRedux(redux) {
677
709
  };
678
710
  }
679
711
 
712
+ function clearUndoRedo(store, opts) {
713
+ if (canClearUndoRedo(store)) {
714
+ store.__clearUndoRedo__(opts);
715
+ }
716
+ else {
717
+ throw new Error('Cannot clear undoRedo, since store is not configured with withUndoRedo()');
718
+ }
719
+ }
720
+ function canClearUndoRedo(store) {
721
+ if ('__clearUndoRedo__' in store &&
722
+ typeof store.__clearUndoRedo__ === 'function') {
723
+ return true;
724
+ }
725
+ else {
726
+ return false;
727
+ }
728
+ }
729
+
680
730
  function deriveCallStateKeys(collection) {
681
731
  return {
682
732
  callStateKey: collection ? `${collection}CallState` : 'callState',
@@ -978,6 +1028,129 @@ function withDataService(options) {
978
1028
  }));
979
1029
  }
980
1030
 
1031
+ const defaultOptions$1 = {
1032
+ maxStackSize: 100,
1033
+ keys: [],
1034
+ skip: 0,
1035
+ };
1036
+ function getUndoRedoKeys(collections) {
1037
+ if (collections) {
1038
+ return collections.flatMap((c) => [
1039
+ `${c}EntityMap`,
1040
+ `${c}Ids`,
1041
+ `selected${capitalize(c)}Ids`,
1042
+ `${c}Filter`,
1043
+ ]);
1044
+ }
1045
+ return ['entityMap', 'ids', 'selectedIds', 'filter'];
1046
+ }
1047
+ function withUndoRedo(options) {
1048
+ let lastRecord = null;
1049
+ let skipOnce = false;
1050
+ const normalized = {
1051
+ ...defaultOptions$1,
1052
+ ...options,
1053
+ };
1054
+ //
1055
+ // Design Decision: This feature has its own
1056
+ // internal state.
1057
+ //
1058
+ const undoStack = [];
1059
+ const redoStack = [];
1060
+ const canUndo = signal(false, ...(ngDevMode ? [{ debugName: "canUndo" }] : []));
1061
+ const canRedo = signal(false, ...(ngDevMode ? [{ debugName: "canRedo" }] : []));
1062
+ const updateInternal = () => {
1063
+ canUndo.set(undoStack.length !== 0);
1064
+ canRedo.set(redoStack.length !== 0);
1065
+ };
1066
+ const keys = [...getUndoRedoKeys(normalized.collections), ...normalized.keys];
1067
+ return signalStoreFeature(withComputed(() => ({
1068
+ canUndo: canUndo.asReadonly(),
1069
+ canRedo: canRedo.asReadonly(),
1070
+ })), withMethods((store) => ({
1071
+ undo() {
1072
+ const item = undoStack.pop();
1073
+ if (item && lastRecord) {
1074
+ redoStack.push(lastRecord);
1075
+ }
1076
+ if (item) {
1077
+ skipOnce = true;
1078
+ patchState$1(store, item);
1079
+ lastRecord = item;
1080
+ }
1081
+ updateInternal();
1082
+ },
1083
+ redo() {
1084
+ const item = redoStack.pop();
1085
+ if (item && lastRecord) {
1086
+ undoStack.push(lastRecord);
1087
+ }
1088
+ if (item) {
1089
+ skipOnce = true;
1090
+ patchState$1(store, item);
1091
+ lastRecord = item;
1092
+ }
1093
+ updateInternal();
1094
+ },
1095
+ __clearUndoRedo__(opts) {
1096
+ undoStack.splice(0);
1097
+ redoStack.splice(0);
1098
+ if (opts) {
1099
+ lastRecord = opts.lastRecord;
1100
+ }
1101
+ updateInternal();
1102
+ },
1103
+ })), withMethods((store) => ({
1104
+ /** @deprecated Use {@link clearUndoRedo} instead. */
1105
+ clearStack() {
1106
+ store.__clearUndoRedo__();
1107
+ },
1108
+ })), withHooks({
1109
+ onInit(store) {
1110
+ watchState(store, () => {
1111
+ const cand = keys.reduce((acc, key) => {
1112
+ const s = store[key];
1113
+ if (s && isSignal(s)) {
1114
+ return {
1115
+ ...acc,
1116
+ [key]: s(),
1117
+ };
1118
+ }
1119
+ return acc;
1120
+ }, {});
1121
+ if (normalized.skip > 0) {
1122
+ normalized.skip--;
1123
+ return;
1124
+ }
1125
+ if (skipOnce) {
1126
+ skipOnce = false;
1127
+ return;
1128
+ }
1129
+ //
1130
+ // Deep Comparison to prevent duplicated entries
1131
+ // on the stack. This can e.g. happen after an undo
1132
+ // if the component sends back the undone filter
1133
+ // to the store.
1134
+ //
1135
+ if (JSON.stringify(cand) === JSON.stringify(lastRecord)) {
1136
+ return;
1137
+ }
1138
+ // Clear redoStack after recorded action
1139
+ redoStack.splice(0);
1140
+ if (lastRecord) {
1141
+ undoStack.push(lastRecord);
1142
+ }
1143
+ if (redoStack.length > normalized.maxStackSize) {
1144
+ undoStack.unshift();
1145
+ }
1146
+ lastRecord = cand;
1147
+ // Don't propogate current reactive context
1148
+ untracked(() => updateInternal());
1149
+ });
1150
+ },
1151
+ }));
1152
+ }
1153
+
981
1154
  /** With pagination comes in two flavors the first one is local pagination or in memory pagination. For example we have 2000 items which we want
982
1155
  * to display in a table and the response payload is small enough to be stored in the memory. But we can not display all 2000 items at once
983
1156
  * so we need to paginate the data. The second flavor is server side pagination where the response payload is too large to be stored in the memory
@@ -1174,122 +1347,6 @@ function setResetState(store, state) {
1174
1347
  store.__setResetState__(state);
1175
1348
  }
1176
1349
 
1177
- const defaultOptions = {
1178
- maxStackSize: 100,
1179
- keys: [],
1180
- skip: 0,
1181
- };
1182
- function getUndoRedoKeys(collections) {
1183
- if (collections) {
1184
- return collections.flatMap((c) => [
1185
- `${c}EntityMap`,
1186
- `${c}Ids`,
1187
- `selected${capitalize(c)}Ids`,
1188
- `${c}Filter`,
1189
- ]);
1190
- }
1191
- return ['entityMap', 'ids', 'selectedIds', 'filter'];
1192
- }
1193
- function withUndoRedo(options) {
1194
- let previous = null;
1195
- let skipOnce = false;
1196
- const normalized = {
1197
- ...defaultOptions,
1198
- ...options,
1199
- };
1200
- //
1201
- // Design Decision: This feature has its own
1202
- // internal state.
1203
- //
1204
- const undoStack = [];
1205
- const redoStack = [];
1206
- const canUndo = signal(false, ...(ngDevMode ? [{ debugName: "canUndo" }] : []));
1207
- const canRedo = signal(false, ...(ngDevMode ? [{ debugName: "canRedo" }] : []));
1208
- const updateInternal = () => {
1209
- canUndo.set(undoStack.length !== 0);
1210
- canRedo.set(redoStack.length !== 0);
1211
- };
1212
- const keys = [...getUndoRedoKeys(normalized.collections), ...normalized.keys];
1213
- return signalStoreFeature(withComputed(() => ({
1214
- canUndo: canUndo.asReadonly(),
1215
- canRedo: canRedo.asReadonly(),
1216
- })), withMethods((store) => ({
1217
- undo() {
1218
- const item = undoStack.pop();
1219
- if (item && previous) {
1220
- redoStack.push(previous);
1221
- }
1222
- if (item) {
1223
- skipOnce = true;
1224
- patchState$1(store, item);
1225
- previous = item;
1226
- }
1227
- updateInternal();
1228
- },
1229
- redo() {
1230
- const item = redoStack.pop();
1231
- if (item && previous) {
1232
- undoStack.push(previous);
1233
- }
1234
- if (item) {
1235
- skipOnce = true;
1236
- patchState$1(store, item);
1237
- previous = item;
1238
- }
1239
- updateInternal();
1240
- },
1241
- clearStack() {
1242
- undoStack.splice(0);
1243
- redoStack.splice(0);
1244
- previous = null;
1245
- updateInternal();
1246
- },
1247
- })), withHooks({
1248
- onInit(store) {
1249
- watchState(store, () => {
1250
- const cand = keys.reduce((acc, key) => {
1251
- const s = store[key];
1252
- if (s && isSignal(s)) {
1253
- return {
1254
- ...acc,
1255
- [key]: s(),
1256
- };
1257
- }
1258
- return acc;
1259
- }, {});
1260
- if (normalized.skip > 0) {
1261
- normalized.skip--;
1262
- return;
1263
- }
1264
- if (skipOnce) {
1265
- skipOnce = false;
1266
- return;
1267
- }
1268
- //
1269
- // Deep Comparison to prevent duplicated entries
1270
- // on the stack. This can e.g. happen after an undo
1271
- // if the component sends back the undone filter
1272
- // to the store.
1273
- //
1274
- if (JSON.stringify(cand) === JSON.stringify(previous)) {
1275
- return;
1276
- }
1277
- // Clear redoStack after recorded action
1278
- redoStack.splice(0);
1279
- if (previous) {
1280
- undoStack.push(previous);
1281
- }
1282
- if (redoStack.length > normalized.maxStackSize) {
1283
- undoStack.unshift();
1284
- }
1285
- previous = cand;
1286
- // Don't propogate current reactive context
1287
- untracked(() => updateInternal());
1288
- });
1289
- },
1290
- }));
1291
- }
1292
-
1293
1350
  /**
1294
1351
  * Deep freezes a state object along its properties with primitive values
1295
1352
  * on the first level.
@@ -1455,10 +1512,10 @@ class IndexedDBService {
1455
1512
  };
1456
1513
  });
1457
1514
  }
1458
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: IndexedDBService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1459
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: IndexedDBService, providedIn: 'root' }); }
1515
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IndexedDBService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1516
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IndexedDBService, providedIn: 'root' }); }
1460
1517
  }
1461
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: IndexedDBService, decorators: [{
1518
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IndexedDBService, decorators: [{
1462
1519
  type: Injectable,
1463
1520
  args: [{ providedIn: 'root' }]
1464
1521
  }] });
@@ -1539,10 +1596,10 @@ class LocalStorageService {
1539
1596
  clear(key) {
1540
1597
  return localStorage.removeItem(key);
1541
1598
  }
1542
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LocalStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1543
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LocalStorageService, providedIn: 'root' }); }
1599
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LocalStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1600
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LocalStorageService, providedIn: 'root' }); }
1544
1601
  }
1545
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LocalStorageService, decorators: [{
1602
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LocalStorageService, decorators: [{
1546
1603
  type: Injectable,
1547
1604
  args: [{
1548
1605
  providedIn: 'root',
@@ -1559,10 +1616,10 @@ class SessionStorageService {
1559
1616
  clear(key) {
1560
1617
  return sessionStorage.removeItem(key);
1561
1618
  }
1562
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SessionStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1563
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SessionStorageService, providedIn: 'root' }); }
1619
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SessionStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1620
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SessionStorageService, providedIn: 'root' }); }
1564
1621
  }
1565
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SessionStorageService, decorators: [{
1622
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SessionStorageService, decorators: [{
1566
1623
  type: Injectable,
1567
1624
  args: [{
1568
1625
  providedIn: 'root',
@@ -1910,7 +1967,7 @@ function rxMutation(optionsOrOperation) {
1910
1967
  .pipe(flatteningOp.rxJsOperator((input) => defer(() => {
1911
1968
  callCount.update((c) => c + 1);
1912
1969
  idle.set(false);
1913
- return options.operation(input.param).pipe(tap((result) => {
1970
+ return options.operation(input.param).pipe(tap$1((result) => {
1914
1971
  options.onSuccess?.(result, input.param);
1915
1972
  innerStatus = 'success';
1916
1973
  errorSignal.set(undefined);
@@ -1970,7 +2027,14 @@ function rxMutation(optionsOrOperation) {
1970
2027
  }
1971
2028
 
1972
2029
  //** Types for `withResource` */
1973
- function withResource(resourceFactory) {
2030
+ const defaultOptions = {
2031
+ errorHandling: 'undefined value',
2032
+ };
2033
+ function withResource(resourceFactory, resourceOptions) {
2034
+ const options = {
2035
+ ...defaultOptions,
2036
+ ...(resourceOptions || {}),
2037
+ };
1974
2038
  return (store) => {
1975
2039
  const resourceOrDictionary = resourceFactory({
1976
2040
  ...store.stateSignals,
@@ -1978,18 +2042,20 @@ function withResource(resourceFactory) {
1978
2042
  ...store.methods,
1979
2043
  });
1980
2044
  if (isResourceRef(resourceOrDictionary)) {
1981
- return createUnnamedResource(resourceOrDictionary)(store);
2045
+ return createUnnamedResource(resourceOrDictionary, options.errorHandling)(store);
1982
2046
  }
1983
2047
  else {
1984
- return createNamedResource(resourceOrDictionary)(store);
2048
+ return createNamedResource(resourceOrDictionary, options.errorHandling)(store);
1985
2049
  }
1986
2050
  };
1987
2051
  }
1988
- function createUnnamedResource(resource) {
2052
+ function createUnnamedResource(resource, errorHandling) {
1989
2053
  function hasValue() {
1990
2054
  return resource.hasValue();
1991
2055
  }
1992
- return signalStoreFeature(withLinkedState(() => ({ value: resource.value })), withProps(() => ({
2056
+ return signalStoreFeature(withLinkedState(() => ({
2057
+ value: valueSignalForErrorHandling(resource, errorHandling),
2058
+ })), withProps(() => ({
1993
2059
  status: resource.status,
1994
2060
  error: resource.error,
1995
2061
  isLoading: resource.isLoading,
@@ -1998,11 +2064,11 @@ function createUnnamedResource(resource) {
1998
2064
  _reload: () => resource.reload(),
1999
2065
  })));
2000
2066
  }
2001
- function createNamedResource(dictionary) {
2067
+ function createNamedResource(dictionary, errorHandling) {
2002
2068
  const keys = Object.keys(dictionary);
2003
2069
  const state = keys.reduce((state, resourceName) => ({
2004
2070
  ...state,
2005
- [`${resourceName}Value`]: dictionary[resourceName].value,
2071
+ [`${resourceName}Value`]: valueSignalForErrorHandling(dictionary[resourceName], errorHandling),
2006
2072
  }), {});
2007
2073
  const props = keys.reduce((props, resourceName) => ({
2008
2074
  ...props,
@@ -2067,6 +2133,65 @@ function mapToResource(store, name) {
2067
2133
  hasValue,
2068
2134
  };
2069
2135
  }
2136
+ function valueSignalForErrorHandling(res, errorHandling) {
2137
+ const originalSignal = res.value;
2138
+ switch (errorHandling) {
2139
+ case 'native':
2140
+ return originalSignal;
2141
+ case 'undefined value': {
2142
+ return new Proxy(originalSignal, {
2143
+ apply(target) {
2144
+ const status = untracked(() => res.status());
2145
+ try {
2146
+ // Always call the underlying signal to ensure reactivity.
2147
+ const value = target();
2148
+ if (status === 'error') {
2149
+ return undefined;
2150
+ }
2151
+ return value;
2152
+ }
2153
+ catch (error) {
2154
+ if (status === 'error') {
2155
+ return undefined;
2156
+ }
2157
+ throw error;
2158
+ }
2159
+ },
2160
+ });
2161
+ }
2162
+ case 'previous value': {
2163
+ let previousValue = undefined;
2164
+ let hasPreviousValue = false;
2165
+ return new Proxy(originalSignal, {
2166
+ apply(target) {
2167
+ const status = untracked(() => res.status());
2168
+ try {
2169
+ // Always call the underlying signal to ensure reactivity.
2170
+ const value = target();
2171
+ if (status === 'error') {
2172
+ if (!hasPreviousValue) {
2173
+ throw new Error('Impossible state: previous value is not available -> resource was initialized with error');
2174
+ }
2175
+ return previousValue;
2176
+ }
2177
+ previousValue = value;
2178
+ hasPreviousValue = true;
2179
+ return value;
2180
+ }
2181
+ catch (error) {
2182
+ if (status === 'error') {
2183
+ if (!hasPreviousValue) {
2184
+ throw new Error('Impossible state: previous value is not available -> resource was initialized with error');
2185
+ }
2186
+ return previousValue;
2187
+ }
2188
+ throw error;
2189
+ }
2190
+ },
2191
+ });
2192
+ }
2193
+ }
2194
+ }
2070
2195
 
2071
2196
  function withEntityResources(entityResourceFactory) {
2072
2197
  return (store) => {
@@ -2081,38 +2206,67 @@ function withEntityResources(entityResourceFactory) {
2081
2206
  return createNamedEntityResources(resourceOrDict)(store);
2082
2207
  };
2083
2208
  }
2209
+ /**
2210
+ * We cannot use the value of `resource` directly, but
2211
+ * have to use the one created through {@link withResource}
2212
+ * because {@link withResource} creates a Proxy around the resource value
2213
+ * to avoid the error throwing behavior of the Resource API.
2214
+ */
2084
2215
  function createUnnamedEntityResource(resource) {
2085
- const { idsLinked, entityMapLinked, entitiesSignal } = createEntityDerivations(resource.value);
2086
- return signalStoreFeature(withResource(() => resource), withLinkedState(() => ({
2087
- entityMap: entityMapLinked,
2088
- ids: idsLinked,
2089
- })), withComputed(() => ({
2090
- entities: entitiesSignal,
2216
+ return signalStoreFeature(withResource(() => resource), withLinkedState(({ value }) => {
2217
+ const { ids, entityMap } = createEntityDerivations(value);
2218
+ return {
2219
+ entityMap,
2220
+ ids,
2221
+ };
2222
+ }), withComputed(({ ids, entityMap }) => ({
2223
+ entities: createComputedEntities(ids, entityMap),
2091
2224
  })));
2092
2225
  }
2226
+ /**
2227
+ * See {@link createUnnamedEntityResource} for why we cannot use the value of `resource` directly.
2228
+ */
2093
2229
  function createNamedEntityResources(dictionary) {
2094
2230
  const keys = Object.keys(dictionary);
2095
- const linkedState = {};
2096
- const computedProps = {};
2097
- keys.forEach((name) => {
2098
- const ref = dictionary[name];
2099
- const { idsLinked, entityMapLinked, entitiesSignal } = createEntityDerivations(ref.value);
2100
- linkedState[`${String(name)}EntityMap`] = entityMapLinked;
2101
- linkedState[`${String(name)}Ids`] = idsLinked;
2102
- computedProps[`${String(name)}Entities`] = entitiesSignal;
2231
+ const stateFactories = keys.map((name) => {
2232
+ return (store) => {
2233
+ const resourceValue = store[`${name}Value`];
2234
+ if (!isSignal(resourceValue)) {
2235
+ throw new Error(`Resource's value ${name}Value does not exist`);
2236
+ }
2237
+ const { ids, entityMap } = createEntityDerivations(resourceValue);
2238
+ return {
2239
+ [`${name}EntityMap`]: entityMap,
2240
+ [`${name}Ids`]: ids,
2241
+ };
2242
+ };
2243
+ });
2244
+ const computedFactories = keys.map((name) => {
2245
+ return (store) => {
2246
+ const ids = store[`${name}Ids`];
2247
+ const entityMap = store[`${name}EntityMap`];
2248
+ if (!isSignal(ids)) {
2249
+ throw new Error(`Entity Resource's ids ${name}Ids does not exist`);
2250
+ }
2251
+ if (!isSignal(entityMap)) {
2252
+ throw new Error(`Entity Resource's entityMap ${name}EntityMap does not exist`);
2253
+ }
2254
+ return {
2255
+ [`${name}Entities`]: createComputedEntities(ids, entityMap),
2256
+ };
2257
+ };
2103
2258
  });
2104
- return signalStoreFeature(withResource(() => dictionary), withLinkedState(() => linkedState), withComputed(() => computedProps));
2259
+ return signalStoreFeature(withResource(() => dictionary), withLinkedState((store) => stateFactories.reduce((acc, factory) => ({ ...acc, ...factory(store) }), {})), withComputed((store) => computedFactories.reduce((acc, factory) => ({ ...acc, ...factory(store) }), {})));
2105
2260
  }
2106
2261
  /**
2107
2262
  * @internal
2108
2263
  * @description
2109
2264
  *
2110
- * Creates the three entity-related signals (`ids`, `entityMap`, `entities`) from
2265
+ * Creates the two entity-related state properties (`ids`, `entityMap`) from
2111
2266
  * a single source signal of entities. This mirrors the public contract of
2112
2267
  * `withEntities()`:
2113
2268
  * - `ids`: derived list of entity ids
2114
2269
  * - `entityMap`: map of id -> entity
2115
- * - `entities`: projection of `ids` through `entityMap`
2116
2270
  *
2117
2271
  * Implementation details:
2118
2272
  * - Uses `withLinkedState` + `linkedSignal` for `ids` and `entityMap` so they are
@@ -2130,26 +2284,22 @@ function createNamedEntityResources(dictionary) {
2130
2284
  * and avoids imperative syncing code.
2131
2285
  */
2132
2286
  function createEntityDerivations(source) {
2133
- const idsLinked = linkedSignal({
2134
- source,
2135
- computation: (list) => (list ?? []).map((e) => e.id),
2136
- });
2137
- const entityMapLinked = linkedSignal({
2138
- source,
2287
+ const ids = linkedSignal({ ...(ngDevMode ? { debugName: "ids" } : {}), source,
2288
+ computation: (list) => (list ?? []).map((e) => e.id) });
2289
+ const entityMap = linkedSignal({ ...(ngDevMode ? { debugName: "entityMap" } : {}), source,
2139
2290
  computation: (list) => {
2140
2291
  const map = {};
2141
2292
  for (const item of list ?? []) {
2142
2293
  map[item.id] = item;
2143
2294
  }
2144
2295
  return map;
2145
- },
2146
- });
2147
- const entitiesSignal = computed(() => {
2148
- const ids = idsLinked();
2149
- const map = entityMapLinked();
2150
- return ids.map((id) => map[id]);
2151
- }, ...(ngDevMode ? [{ debugName: "entitiesSignal" }] : []));
2152
- return { idsLinked, entityMapLinked, entitiesSignal };
2296
+ } });
2297
+ return { ids, entityMap };
2298
+ }
2299
+ function createComputedEntities(ids, entityMap) {
2300
+ return () => {
2301
+ return ids().map((id) => entityMap()[id]);
2302
+ };
2153
2303
  }
2154
2304
 
2155
2305
  function withMutations(mutationsFactory) {
@@ -2264,14 +2414,14 @@ function httpMutation(optionsOrRequest) {
2264
2414
  observe: 'events',
2265
2415
  responseType: 'json',
2266
2416
  })
2267
- .pipe(tap((response) => {
2417
+ .pipe(tap$1((response) => {
2268
2418
  if (response.type === HttpEventType.UploadProgress) {
2269
2419
  uploadProgress.set(response);
2270
2420
  }
2271
2421
  else if (response.type === HttpEventType.DownloadProgress) {
2272
2422
  downloadProgress.set(response);
2273
2423
  }
2274
- }), filter((event) => event instanceof HttpResponse), tap((response) => {
2424
+ }), filter((event) => event instanceof HttpResponse), tap$1((response) => {
2275
2425
  headers.set(response.headers);
2276
2426
  statusCode.set(response.status.toString());
2277
2427
  }), map((event) => parse(event.body)));
@@ -2289,5 +2439,5 @@ function httpMutation(optionsOrRequest) {
2289
2439
  * Generated bundle index. Do not edit.
2290
2440
  */
2291
2441
 
2292
- export { capitalize, concatOp, createEffects, createPageArray, createReducer, deriveCallStateKeys, emptyFeature, exhaustOp, firstPage, getCallStateKeys, getCollectionArray, getDataServiceKeys, getUndoRedoKeys, gotoPage, httpMutation, mapToResource, mergeOp, nextPage, noPayload, patchState, payload, previousPage, provideDevtoolsConfig, renameDevtoolsName, rxMutation, setError, setLoaded, setLoading, setMaxPageNavigationArrayItems, setPageSize, setResetState, switchOp, updateState, withCallState, withConditional, withDataService, withDevToolsStub, withDevtools, withDisabledNameIndices, withEntityResources, withFeatureFactory, withGlitchTracking, withImmutableState, withIndexedDB, withIndexedDB as withIndexeddb, withLocalStorage, withMapper, withMutations, withPagination, withRedux, withReset, withResource, withSessionStorage, withStorageSync, withUndoRedo };
2442
+ export { capitalize, clearUndoRedo, concatOp, createEffects, createPageArray, createReducer, deriveCallStateKeys, emptyFeature, exhaustOp, firstPage, getCallStateKeys, getCollectionArray, getDataServiceKeys, getUndoRedoKeys, gotoPage, httpMutation, mapToResource, mergeOp, nextPage, noPayload, patchState, payload, previousPage, provideDevtoolsConfig, renameDevtoolsName, rxMutation, setError, setLoaded, setLoading, setMaxPageNavigationArrayItems, setPageSize, setResetState, switchOp, updateState, withCallState, withConditional, withDataService, withDevToolsStub, withDevtools, withDisabledNameIndices, withEntityResources, withFeatureFactory, withGlitchTracking, withImmutableState, withIndexedDB, withIndexedDB as withIndexeddb, withLocalStorage, withMapper, withMutations, withPagination, withRedux, withReset, withResource, withSessionStorage, withStorageSync, withTrackedReducer, withUndoRedo };
2293
2443
  //# sourceMappingURL=angular-architects-ngrx-toolkit.mjs.map