@ngxs/store 18.1.1-dev.master-76347ef → 18.1.1-dev.master-e935e57
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/esm2022/src/internal/lifecycle-state-manager.mjs +2 -2
- package/esm2022/src/internal/state-context-factory.mjs +6 -6
- package/esm2022/src/internal/state-factory.mjs +78 -48
- package/fesm2022/ngxs-store.mjs +83 -53
- package/fesm2022/ngxs-store.mjs.map +1 -1
- package/package.json +7 -7
- package/src/internal/state-context-factory.d.ts +1 -2
- package/src/internal/state-factory.d.ts +10 -2
package/fesm2022/ngxs-store.mjs
CHANGED
|
@@ -1025,25 +1025,25 @@ class StateContextFactory {
|
|
|
1025
1025
|
/**
|
|
1026
1026
|
* Create the state context
|
|
1027
1027
|
*/
|
|
1028
|
-
createStateContext(
|
|
1028
|
+
createStateContext(path) {
|
|
1029
1029
|
const root = this._internalStateOperations.getRootStateOperations();
|
|
1030
1030
|
return {
|
|
1031
1031
|
getState() {
|
|
1032
1032
|
const currentAppState = root.getState();
|
|
1033
|
-
return getState(currentAppState,
|
|
1033
|
+
return getState(currentAppState, path);
|
|
1034
1034
|
},
|
|
1035
1035
|
patchState(val) {
|
|
1036
1036
|
const currentAppState = root.getState();
|
|
1037
1037
|
const patchOperator = simplePatch(val);
|
|
1038
|
-
setStateFromOperator(root, currentAppState, patchOperator,
|
|
1038
|
+
setStateFromOperator(root, currentAppState, patchOperator, path);
|
|
1039
1039
|
},
|
|
1040
1040
|
setState(val) {
|
|
1041
1041
|
const currentAppState = root.getState();
|
|
1042
1042
|
if (isStateOperator(val)) {
|
|
1043
|
-
setStateFromOperator(root, currentAppState, val,
|
|
1043
|
+
setStateFromOperator(root, currentAppState, val, path);
|
|
1044
1044
|
}
|
|
1045
1045
|
else {
|
|
1046
|
-
setStateValue(root, currentAppState, val,
|
|
1046
|
+
setStateValue(root, currentAppState, val, path);
|
|
1047
1047
|
}
|
|
1048
1048
|
},
|
|
1049
1049
|
dispatch(actions) {
|
|
@@ -1237,6 +1237,12 @@ class StateFactory {
|
|
|
1237
1237
|
this._actionsSubscription = null;
|
|
1238
1238
|
this._propGetter = inject(ɵPROP_GETTER);
|
|
1239
1239
|
this._ngxsUnhandledErrorHandler = null;
|
|
1240
|
+
// Instead of going over the states list every time an action is dispatched,
|
|
1241
|
+
// we are constructing a map of action types to lists of action metadata.
|
|
1242
|
+
// If the `@@Init` action is handled in two different states, the action
|
|
1243
|
+
// metadata list will contain two objects that have the state `instance` and
|
|
1244
|
+
// method names to be used as action handlers (decorated with `@Action(InitState)`).
|
|
1245
|
+
this._actionTypeToMetasMap = new Map();
|
|
1240
1246
|
this._states = [];
|
|
1241
1247
|
this._statesByName = {};
|
|
1242
1248
|
this._statePaths = {};
|
|
@@ -1277,6 +1283,11 @@ class StateFactory {
|
|
|
1277
1283
|
return context;
|
|
1278
1284
|
});
|
|
1279
1285
|
}
|
|
1286
|
+
get actionTypeToMetasMap() {
|
|
1287
|
+
return this._parentFactory
|
|
1288
|
+
? this._parentFactory.actionTypeToMetasMap
|
|
1289
|
+
: this._actionTypeToMetasMap;
|
|
1290
|
+
}
|
|
1280
1291
|
get states() {
|
|
1281
1292
|
return this._parentFactory ? this._parentFactory.states : this._states;
|
|
1282
1293
|
}
|
|
@@ -1331,6 +1342,7 @@ class StateFactory {
|
|
|
1331
1342
|
bootstrappedStores.push(stateMap);
|
|
1332
1343
|
}
|
|
1333
1344
|
this.states.push(stateMap);
|
|
1345
|
+
this.hydrateActionMetasMap(stateMap);
|
|
1334
1346
|
}
|
|
1335
1347
|
return bootstrappedStores;
|
|
1336
1348
|
}
|
|
@@ -1377,55 +1389,53 @@ class StateFactory {
|
|
|
1377
1389
|
// Determines whether the dispatched action has been handled, this is assigned
|
|
1378
1390
|
// to `true` within the below `for` loop if any `actionMetas` has been found.
|
|
1379
1391
|
let actionHasBeenHandled = false;
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
// action will be canceled.
|
|
1401
|
-
// For instance if any action handler would've had such statement:
|
|
1402
|
-
// `handler(ctx) { return EMPTY; }`
|
|
1403
|
-
// then the action will be canceled.
|
|
1404
|
-
// See https://github.com/ngxs/store/issues/1568
|
|
1405
|
-
result = result.pipe(mergeMap((value) => {
|
|
1406
|
-
if (_isPromise(value)) {
|
|
1407
|
-
return from(value);
|
|
1408
|
-
}
|
|
1409
|
-
if (isObservable(value)) {
|
|
1410
|
-
return value;
|
|
1411
|
-
}
|
|
1412
|
-
return of(value);
|
|
1413
|
-
}), defaultIfEmpty({}));
|
|
1414
|
-
if (actionMeta.options.cancelUncompleted) {
|
|
1415
|
-
// todo: ofActionDispatched should be used with action class
|
|
1416
|
-
result = result.pipe(takeUntil(dispatched$.pipe(ofActionDispatched(action))));
|
|
1392
|
+
const actionMetas = this.actionTypeToMetasMap.get(type);
|
|
1393
|
+
if (actionMetas) {
|
|
1394
|
+
for (const actionMeta of actionMetas) {
|
|
1395
|
+
const stateContext = this._stateContextFactory.createStateContext(actionMeta.path);
|
|
1396
|
+
let result;
|
|
1397
|
+
try {
|
|
1398
|
+
result = actionMeta.instance[actionMeta.fn](stateContext, action);
|
|
1399
|
+
// We need to use `isPromise` instead of checking whether
|
|
1400
|
+
// `result instanceof Promise`. In zone.js patched environments, `global.Promise`
|
|
1401
|
+
// is the `ZoneAwarePromise`. Some APIs, which are likely not patched by zone.js
|
|
1402
|
+
// for certain reasons, might not work with `instanceof`. For instance, the dynamic
|
|
1403
|
+
// import returns a native promise (not a `ZoneAwarePromise`), causing this check to
|
|
1404
|
+
// be falsy.
|
|
1405
|
+
if (_isPromise(result)) {
|
|
1406
|
+
result = from(result);
|
|
1407
|
+
}
|
|
1408
|
+
if (isObservable(result)) {
|
|
1409
|
+
result = result.pipe(mergeMap((value) => {
|
|
1410
|
+
if (_isPromise(value)) {
|
|
1411
|
+
return from(value);
|
|
1417
1412
|
}
|
|
1413
|
+
if (isObservable(value)) {
|
|
1414
|
+
return value;
|
|
1415
|
+
}
|
|
1416
|
+
return of(value);
|
|
1417
|
+
}),
|
|
1418
|
+
// If this observable has completed without emitting any values,
|
|
1419
|
+
// we wouldn't want to complete the entire chain of actions.
|
|
1420
|
+
// If any observable completes, then the action will be canceled.
|
|
1421
|
+
// For instance, if any action handler had a statement like
|
|
1422
|
+
// `handler(ctx) { return EMPTY; }`, then the action would be canceled.
|
|
1423
|
+
// See https://github.com/ngxs/store/issues/1568
|
|
1424
|
+
defaultIfEmpty({}));
|
|
1425
|
+
if (actionMeta.options.cancelUncompleted) {
|
|
1426
|
+
// todo: ofActionDispatched should be used with action class
|
|
1427
|
+
result = result.pipe(takeUntil(dispatched$.pipe(ofActionDispatched(action))));
|
|
1418
1428
|
}
|
|
1419
|
-
else {
|
|
1420
|
-
result = of({}).pipe(shareReplay());
|
|
1421
|
-
}
|
|
1422
|
-
results.push(result);
|
|
1423
1429
|
}
|
|
1424
|
-
|
|
1425
|
-
|
|
1430
|
+
else {
|
|
1431
|
+
result = of({}).pipe(shareReplay());
|
|
1426
1432
|
}
|
|
1427
|
-
actionHasBeenHandled = true;
|
|
1428
1433
|
}
|
|
1434
|
+
catch (e) {
|
|
1435
|
+
result = throwError(e);
|
|
1436
|
+
}
|
|
1437
|
+
results.push(result);
|
|
1438
|
+
actionHasBeenHandled = true;
|
|
1429
1439
|
}
|
|
1430
1440
|
}
|
|
1431
1441
|
// The `NgxsUnhandledActionsLogger` is a tree-shakable class which functions
|
|
@@ -1435,9 +1445,7 @@ class StateFactory {
|
|
|
1435
1445
|
// The `NgxsUnhandledActionsLogger` will not be resolved by the injector if the
|
|
1436
1446
|
// `NgxsDevelopmentModule` is not provided. It's enough to check whether the `injector.get`
|
|
1437
1447
|
// didn't return `null` so we may ensure the module has been imported.
|
|
1438
|
-
|
|
1439
|
-
unhandledActionsLogger.warn(action);
|
|
1440
|
-
}
|
|
1448
|
+
unhandledActionsLogger?.warn(action);
|
|
1441
1449
|
}
|
|
1442
1450
|
if (!results.length) {
|
|
1443
1451
|
results.push(of({}));
|
|
@@ -1473,6 +1481,28 @@ class StateFactory {
|
|
|
1473
1481
|
// its lifecycle is in 'bootstrapped' state.
|
|
1474
1482
|
return this.statesByName[name] && valueIsBootstrappedInInitialState;
|
|
1475
1483
|
}
|
|
1484
|
+
hydrateActionMetasMap({ path, actions, instance }) {
|
|
1485
|
+
const actionTypeToMetasMap = this.actionTypeToMetasMap;
|
|
1486
|
+
for (const actionType of Object.keys(actions)) {
|
|
1487
|
+
// Initialize the map entry if it does not already exist for that
|
|
1488
|
+
// action type. Note that action types may overlap between states,
|
|
1489
|
+
// as the same action can be handled by different states.
|
|
1490
|
+
if (!actionTypeToMetasMap.has(actionType)) {
|
|
1491
|
+
actionTypeToMetasMap.set(actionType, []);
|
|
1492
|
+
}
|
|
1493
|
+
const extendedActionMetas = actionTypeToMetasMap.get(actionType);
|
|
1494
|
+
extendedActionMetas.push(
|
|
1495
|
+
// This involves combining each individual action metadata with
|
|
1496
|
+
// the state instance and the path—essentially everything needed
|
|
1497
|
+
// to invoke an action. This eliminates the need to loop over states
|
|
1498
|
+
// every time an action is dispatched.
|
|
1499
|
+
...actions[actionType].map(actionMeta => ({
|
|
1500
|
+
...actionMeta,
|
|
1501
|
+
path,
|
|
1502
|
+
instance
|
|
1503
|
+
})));
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1476
1506
|
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: StateFactory, deps: [{ token: i0.Injector }, { token: NgxsConfig }, { token: StateFactory, optional: true, skipSelf: true }, { token: InternalActions }, { token: InternalDispatchedActionResults }, { token: StateContextFactory }, { token: _INITIAL_STATE_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1477
1507
|
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: StateFactory }); }
|
|
1478
1508
|
}
|
|
@@ -1705,7 +1735,7 @@ class LifecycleStateManager {
|
|
|
1705
1735
|
}
|
|
1706
1736
|
}
|
|
1707
1737
|
_getStateContext(mappedStore) {
|
|
1708
|
-
return this._stateContextFactory.createStateContext(mappedStore);
|
|
1738
|
+
return this._stateContextFactory.createStateContext(mappedStore.path);
|
|
1709
1739
|
}
|
|
1710
1740
|
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: LifecycleStateManager, deps: [{ token: Store }, { token: InternalStateOperations }, { token: StateContextFactory }, { token: i1.ɵNgxsAppBootstrappedState }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1711
1741
|
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: LifecycleStateManager, providedIn: 'root' }); }
|