@angular-architects/ngrx-toolkit 20.5.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.
- package/fesm2022/angular-architects-ngrx-toolkit-redux-connector.mjs +3 -3
- package/fesm2022/angular-architects-ngrx-toolkit-redux-connector.mjs.map +1 -1
- package/fesm2022/angular-architects-ngrx-toolkit.mjs +334 -184
- package/fesm2022/angular-architects-ngrx-toolkit.mjs.map +1 -1
- package/package.json +8 -8
- package/{redux-connector/index.d.ts → types/angular-architects-ngrx-toolkit-redux-connector.d.ts} +2 -3
- package/{index.d.ts → types/angular-architects-ngrx-toolkit.d.ts} +97 -54
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, InjectionToken, signal, effect, inject, PLATFORM_ID, NgZone, computed, isSignal,
|
|
3
|
-
import { watchState, getState, signalStoreFeature, withMethods, withHooks, patchState as patchState$1, withState, withComputed,
|
|
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 {
|
|
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: "
|
|
96
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
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: "
|
|
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({
|
|
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: "
|
|
222
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
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: "
|
|
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: "
|
|
392
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
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: "
|
|
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
|
-
|
|
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
|
-
}),
|
|
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 = () => (
|
|
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: "
|
|
1459
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
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: "
|
|
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: "
|
|
1543
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
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: "
|
|
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: "
|
|
1563
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
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: "
|
|
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
|
-
|
|
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(() => ({
|
|
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]
|
|
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
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
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
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
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(() =>
|
|
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
|
|
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
|
|
2134
|
-
|
|
2135
|
-
|
|
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
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
return ids.map((id) =>
|
|
2151
|
-
}
|
|
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
|