@ngxs/store 19.0.0-dev.master-ae76ef6 → 19.0.0-dev.master-c739a26

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,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, Injectable, DestroyRef, NgZone, Injector, runInInjectionContext, InjectionToken, ErrorHandler, ɵisPromise as _isPromise, computed, makeEnvironmentProviders, provideEnvironmentInitializer, NgModule, APP_BOOTSTRAP_LISTENER, ApplicationRef, PendingTasks, assertInInjectionContext, EnvironmentInjector, createEnvironmentInjector } from '@angular/core';
3
- import { config, Observable, Subject, of, forkJoin, map, shareReplay, filter, take, mergeMap, EMPTY, defaultIfEmpty, catchError, from, isObservable, takeUntil, finalize, distinctUntilChanged, startWith, skip, buffer, debounceTime } from 'rxjs';
3
+ import { config, Observable, Subject, of, forkJoin, map, shareReplay, filter, take, mergeMap, EMPTY, from, isObservable, defaultIfEmpty, takeUntil, finalize, catchError, distinctUntilChanged, startWith, skip, buffer, debounceTime } from 'rxjs';
4
4
  import { ɵwrapObserverCalls as _wrapObserverCalls, ɵOrderedSubject as _OrderedSubject, ɵStateStream as _StateStream, ɵhasOwnProperty as _hasOwnProperty, ɵmemoize as _memoize, ɵgetStoreMetadata as _getStoreMetadata, ɵgetSelectorMetadata as _getSelectorMetadata, ɵMETA_KEY as _META_KEY, ɵINITIAL_STATE_TOKEN as _INITIAL_STATE_TOKEN, ɵNgxsActionRegistry as _NgxsActionRegistry, ɵNgxsAppBootstrappedState as _NgxsAppBootstrappedState, ɵensureStoreMetadata as _ensureStoreMetadata, ɵMETA_OPTIONS_KEY as _META_OPTIONS_KEY, ɵensureSelectorMetadata as _ensureSelectorMetadata, ɵNGXS_STATE_CONTEXT_FACTORY as _NGXS_STATE_CONTEXT_FACTORY, ɵNGXS_STATE_FACTORY as _NGXS_STATE_FACTORY } from '@ngxs/store/internals';
5
5
  export { StateToken } from '@ngxs/store/internals';
6
6
  import { NGXS_PLUGINS, getActionTypeFromInstance, InitState, UpdateState, setValue, getValue, ɵisPluginClass as _isPluginClass } from '@ngxs/store/plugins';
@@ -921,89 +921,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
921
921
  args: [{ providedIn: 'root' }]
922
922
  }] });
923
923
 
924
- function simplePatch(value) {
925
- return (existingState) => {
926
- if (typeof ngDevMode !== 'undefined' && ngDevMode) {
927
- if (Array.isArray(value)) {
928
- throwPatchingArrayError();
929
- }
930
- else if (typeof value !== 'object') {
931
- throwPatchingPrimitiveError();
932
- }
933
- }
934
- const newState = { ...existingState };
935
- for (const key in value) {
936
- // deep clone for patch compatibility
937
- newState[key] = value[key];
938
- }
939
- return newState;
940
- };
941
- }
942
-
943
- /**
944
- * State Context factory class
945
- * @ignore
946
- */
947
- class StateContextFactory {
948
- constructor() {
949
- this._internalStateOperations = inject(InternalStateOperations);
950
- }
951
- /**
952
- * Create the state context
953
- */
954
- createStateContext(path) {
955
- const root = this._internalStateOperations.getRootStateOperations();
956
- return {
957
- getState() {
958
- const currentAppState = root.getState();
959
- return getState(currentAppState, path);
960
- },
961
- patchState(val) {
962
- const currentAppState = root.getState();
963
- const patchOperator = simplePatch(val);
964
- setStateFromOperator(root, currentAppState, patchOperator, path);
965
- },
966
- setState(val) {
967
- const currentAppState = root.getState();
968
- if (isStateOperator(val)) {
969
- setStateFromOperator(root, currentAppState, val, path);
970
- }
971
- else {
972
- setStateValue(root, currentAppState, val, path);
973
- }
974
- },
975
- dispatch(actions) {
976
- return root.dispatch(actions);
977
- }
978
- };
979
- }
980
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: StateContextFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
981
- /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: StateContextFactory, providedIn: 'root' }); }
982
- }
983
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: StateContextFactory, decorators: [{
984
- type: Injectable,
985
- args: [{ providedIn: 'root' }]
986
- }] });
987
- function setStateValue(root, currentAppState, newValue, path) {
988
- const newAppState = setValue(currentAppState, path, newValue);
989
- root.setState(newAppState);
990
- return newAppState;
991
- // In doing this refactoring I noticed that there is a 'bug' where the
992
- // application state is returned instead of this state slice.
993
- // This has worked this way since the beginning see:
994
- // https://github.com/ngxs/store/blame/324c667b4b7debd8eb979006c67ca0ae347d88cd/src/state-factory.ts
995
- // This needs to be fixed, but is a 'breaking' change.
996
- // I will do this fix in a subsequent PR and we can decide how to handle it.
997
- }
998
- function setStateFromOperator(root, currentAppState, stateOperator, path) {
999
- const local = getState(currentAppState, path);
1000
- const newValue = stateOperator(local);
1001
- return setStateValue(root, currentAppState, newValue, path);
1002
- }
1003
- function getState(currentAppState, path) {
1004
- return getValue(currentAppState, path);
1005
- }
1006
-
1007
924
  /**
1008
925
  * RxJS operator for selecting out specific actions.
1009
926
  *
@@ -1106,6 +1023,164 @@ function createAllowedStatusesMap(statuses) {
1106
1023
  }, {});
1107
1024
  }
1108
1025
 
1026
+ function simplePatch(value) {
1027
+ return (existingState) => {
1028
+ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
1029
+ if (Array.isArray(value)) {
1030
+ throwPatchingArrayError();
1031
+ }
1032
+ else if (typeof value !== 'object') {
1033
+ throwPatchingPrimitiveError();
1034
+ }
1035
+ }
1036
+ const newState = { ...existingState };
1037
+ for (const key in value) {
1038
+ // deep clone for patch compatibility
1039
+ newState[key] = value[key];
1040
+ }
1041
+ return newState;
1042
+ };
1043
+ }
1044
+
1045
+ /**
1046
+ * State Context factory class
1047
+ * @ignore
1048
+ */
1049
+ class StateContextFactory {
1050
+ constructor() {
1051
+ this._internalStateOperations = inject(InternalStateOperations);
1052
+ }
1053
+ /**
1054
+ * Create the state context
1055
+ */
1056
+ createStateContext(path) {
1057
+ const root = this._internalStateOperations.getRootStateOperations();
1058
+ return {
1059
+ getState() {
1060
+ const currentAppState = root.getState();
1061
+ return getState(currentAppState, path);
1062
+ },
1063
+ patchState(val) {
1064
+ const currentAppState = root.getState();
1065
+ const patchOperator = simplePatch(val);
1066
+ setStateFromOperator(root, currentAppState, patchOperator, path);
1067
+ },
1068
+ setState(val) {
1069
+ const currentAppState = root.getState();
1070
+ if (isStateOperator(val)) {
1071
+ setStateFromOperator(root, currentAppState, val, path);
1072
+ }
1073
+ else {
1074
+ setStateValue(root, currentAppState, val, path);
1075
+ }
1076
+ },
1077
+ dispatch(actions) {
1078
+ return root.dispatch(actions);
1079
+ }
1080
+ };
1081
+ }
1082
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: StateContextFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1083
+ /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: StateContextFactory, providedIn: 'root' }); }
1084
+ }
1085
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: StateContextFactory, decorators: [{
1086
+ type: Injectable,
1087
+ args: [{ providedIn: 'root' }]
1088
+ }] });
1089
+ function setStateValue(root, currentAppState, newValue, path) {
1090
+ const newAppState = setValue(currentAppState, path, newValue);
1091
+ root.setState(newAppState);
1092
+ return newAppState;
1093
+ // In doing this refactoring I noticed that there is a 'bug' where the
1094
+ // application state is returned instead of this state slice.
1095
+ // This has worked this way since the beginning see:
1096
+ // https://github.com/ngxs/store/blame/324c667b4b7debd8eb979006c67ca0ae347d88cd/src/state-factory.ts
1097
+ // This needs to be fixed, but is a 'breaking' change.
1098
+ // I will do this fix in a subsequent PR and we can decide how to handle it.
1099
+ }
1100
+ function setStateFromOperator(root, currentAppState, stateOperator, path) {
1101
+ const local = getState(currentAppState, path);
1102
+ const newValue = stateOperator(local);
1103
+ return setStateValue(root, currentAppState, newValue, path);
1104
+ }
1105
+ function getState(currentAppState, path) {
1106
+ return getValue(currentAppState, path);
1107
+ }
1108
+
1109
+ class InternalActionHandlerFactory {
1110
+ constructor() {
1111
+ this._actions = inject(InternalActions);
1112
+ this._stateContextFactory = inject(StateContextFactory);
1113
+ }
1114
+ createActionHandler(path, handlerFn, options) {
1115
+ const { dispatched$ } = this._actions;
1116
+ return (action) => {
1117
+ const stateContext = this._stateContextFactory.createStateContext(path);
1118
+ let result = handlerFn(stateContext, action);
1119
+ // We need to use `isPromise` instead of checking whether
1120
+ // `result instanceof Promise`. In zone.js patched environments, `global.Promise`
1121
+ // is the `ZoneAwarePromise`. Some APIs, which are likely not patched by zone.js
1122
+ // for certain reasons, might not work with `instanceof`. For instance, the dynamic
1123
+ // import returns a native promise (not a `ZoneAwarePromise`), causing this check to
1124
+ // be falsy.
1125
+ if (_isPromise(result)) {
1126
+ result = from(result);
1127
+ }
1128
+ if (isObservable(result)) {
1129
+ result = result.pipe(mergeMap(value => (_isPromise(value) || isObservable(value) ? value : of(value))),
1130
+ // If this observable has completed without emitting any values,
1131
+ // we wouldn't want to complete the entire chain of actions.
1132
+ // If any observable completes, then the action will be canceled.
1133
+ // For instance, if any action handler had a statement like
1134
+ // `handler(ctx) { return EMPTY; }`, then the action would be canceled.
1135
+ // See https://github.com/ngxs/store/issues/1568
1136
+ // Note that we actually don't care about the return type; we only care
1137
+ // about emission, and thus `undefined` is applicable by the framework.
1138
+ defaultIfEmpty(undefined));
1139
+ if (options.cancelUncompleted) {
1140
+ const canceled = dispatched$.pipe(ofActionDispatched(action));
1141
+ result = result.pipe(takeUntil(canceled));
1142
+ }
1143
+ result = result.pipe(
1144
+ // Note that we use the `finalize` operator only when the action handler
1145
+ // explicitly returns an observable (or a promise) to wait for. This means
1146
+ // the action handler is written in a "fire & wait" style. If the handler’s
1147
+ // result is unsubscribed (either because the observable has completed or
1148
+ // it was unsubscribed by `takeUntil` due to a new action being dispatched),
1149
+ // we prevent writing to the state context.
1150
+ finalize(() => {
1151
+ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
1152
+ function noopAndWarn() {
1153
+ console.warn(`"${action}" attempted to change the state, but the change was ignored because state updates are not allowed after the action handler has completed.`);
1154
+ }
1155
+ stateContext.setState = noopAndWarn;
1156
+ stateContext.patchState = noopAndWarn;
1157
+ }
1158
+ else {
1159
+ stateContext.setState = noop;
1160
+ stateContext.patchState = noop;
1161
+ }
1162
+ }));
1163
+ }
1164
+ else {
1165
+ // If the action handler is synchronous and returns nothing (`void`), we
1166
+ // still have to convert the result to a synchronous observable.
1167
+ result = of(undefined);
1168
+ }
1169
+ return result;
1170
+ };
1171
+ }
1172
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: InternalActionHandlerFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1173
+ /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: InternalActionHandlerFactory, providedIn: 'root' }); }
1174
+ }
1175
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: InternalActionHandlerFactory, decorators: [{
1176
+ type: Injectable,
1177
+ args: [{ providedIn: 'root' }]
1178
+ }] });
1179
+ // This is used to replace `setState` and `patchState` once the action
1180
+ // handler has been unsubscribed or completed, to prevent writing
1181
+ // to the state context.
1182
+ function noop() { }
1183
+
1109
1184
  function cloneDefaults(defaults) {
1110
1185
  let value = defaults === undefined ? {} : defaults;
1111
1186
  if (defaults) {
@@ -1133,7 +1208,7 @@ class StateFactory {
1133
1208
  constructor() {
1134
1209
  this._injector = inject(Injector);
1135
1210
  this._config = inject(NgxsConfig);
1136
- this._stateContextFactory = inject(StateContextFactory);
1211
+ this._actionHandlerFactory = inject(InternalActionHandlerFactory);
1137
1212
  this._actions = inject(InternalActions);
1138
1213
  this._actionResults = inject(InternalDispatchedActionResults);
1139
1214
  this._initialState = inject(_INITIAL_STATE_TOKEN, { optional: true });
@@ -1315,72 +1390,10 @@ class StateFactory {
1315
1390
  return this._statesByName[name] && valueIsBootstrappedInInitialState;
1316
1391
  }
1317
1392
  hydrateActionMetasMap({ path, actions, instance }) {
1318
- const { dispatched$ } = this._actions;
1319
1393
  for (const actionType of Object.keys(actions)) {
1320
1394
  const actionHandlers = actions[actionType].map(actionMeta => {
1321
- const cancelable = !!actionMeta.options.cancelUncompleted;
1322
- return (action) => {
1323
- const stateContext = this._stateContextFactory.createStateContext(path);
1324
- let result = instance[actionMeta.fn](stateContext, action);
1325
- // We need to use `isPromise` instead of checking whether
1326
- // `result instanceof Promise`. In zone.js patched environments, `global.Promise`
1327
- // is the `ZoneAwarePromise`. Some APIs, which are likely not patched by zone.js
1328
- // for certain reasons, might not work with `instanceof`. For instance, the dynamic
1329
- // import returns a native promise (not a `ZoneAwarePromise`), causing this check to
1330
- // be falsy.
1331
- if (_isPromise(result)) {
1332
- result = from(result);
1333
- }
1334
- if (isObservable(result)) {
1335
- result = result.pipe(mergeMap((value) => {
1336
- if (_isPromise(value) || isObservable(value)) {
1337
- return value;
1338
- }
1339
- else {
1340
- return of(value);
1341
- }
1342
- }),
1343
- // If this observable has completed without emitting any values,
1344
- // we wouldn't want to complete the entire chain of actions.
1345
- // If any observable completes, then the action will be canceled.
1346
- // For instance, if any action handler had a statement like
1347
- // `handler(ctx) { return EMPTY; }`, then the action would be canceled.
1348
- // See https://github.com/ngxs/store/issues/1568
1349
- // Note that we actually don't care about the return type; we only care
1350
- // about emission, and thus `undefined` is applicable by the framework.
1351
- defaultIfEmpty(undefined));
1352
- if (cancelable) {
1353
- const canceled = dispatched$.pipe(ofActionDispatched(action));
1354
- result = result.pipe(takeUntil(canceled));
1355
- }
1356
- result = result.pipe(
1357
- // Note that we use the `finalize` operator only when the action handler
1358
- // explicitly returns an observable (or a promise) to wait for. This means
1359
- // the action handler is written in a "fire & wait" style. If the handler’s
1360
- // result is unsubscribed (either because the observable has completed or
1361
- // it was unsubscribed by `takeUntil` due to a new action being dispatched),
1362
- // we prevent writing to the state context.
1363
- finalize(() => {
1364
- if (typeof ngDevMode !== 'undefined' && ngDevMode) {
1365
- function noopAndWarn() {
1366
- console.warn(`"${actionType}" attempted to change the state, but the change was ignored because state updates are not allowed after the action handler has completed.`);
1367
- }
1368
- stateContext.setState = noopAndWarn;
1369
- stateContext.patchState = noopAndWarn;
1370
- }
1371
- else {
1372
- stateContext.setState = noop;
1373
- stateContext.patchState = noop;
1374
- }
1375
- }));
1376
- }
1377
- else {
1378
- // If the action handler is synchronous and returns nothing (`void`), we
1379
- // still have to convert the result to a synchronous observable.
1380
- result = of(undefined);
1381
- }
1382
- return result;
1383
- };
1395
+ const handlerFn = (ctx, action) => instance[actionMeta.fn](ctx, action);
1396
+ return this._actionHandlerFactory.createActionHandler(path, handlerFn, actionMeta.options);
1384
1397
  });
1385
1398
  for (const actionHandler of actionHandlers) {
1386
1399
  this._actionRegistry.register(actionType, actionHandler);
@@ -1394,10 +1407,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1394
1407
  type: Injectable,
1395
1408
  args: [{ providedIn: 'root' }]
1396
1409
  }], ctorParameters: () => [] });
1397
- // This is used to replace `setState` and `patchState` once the action
1398
- // handler has been unsubscribed or completed, to prevent writing
1399
- // to the state context.
1400
- function noop() { }
1401
1410
 
1402
1411
  class Store {
1403
1412
  constructor() {
@@ -1952,6 +1961,23 @@ function Selector(selectors) {
1952
1961
  };
1953
1962
  }
1954
1963
 
1964
+ class ActionDirector {
1965
+ constructor() {
1966
+ this._registry = inject(_NgxsActionRegistry);
1967
+ this._actionHandlerFactory = inject(InternalActionHandlerFactory);
1968
+ }
1969
+ attachAction(stateToken, Action, handlerFn, options = {}) {
1970
+ const actionHandler = this._actionHandlerFactory.createActionHandler(stateToken.getName(), handlerFn, options);
1971
+ this._registry.register(Action.type, actionHandler);
1972
+ }
1973
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ActionDirector, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1974
+ /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ActionDirector, providedIn: 'root' }); }
1975
+ }
1976
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ActionDirector, decorators: [{
1977
+ type: Injectable,
1978
+ args: [{ providedIn: 'root' }]
1979
+ }] });
1980
+
1955
1981
  class NgxsDevelopmentModule {
1956
1982
  static forRoot(options) {
1957
1983
  return {
@@ -2344,5 +2370,5 @@ function ɵprovideNgxsInternalStateTokens() {
2344
2370
  * Generated bundle index. Do not edit.
2345
2371
  */
2346
2372
 
2347
- export { Action, ActionStatus, Actions, NgxsConfig, NgxsDevelopmentModule, NgxsModule, NgxsSimpleChange, NgxsUnhandledActionsLogger, NgxsUnhandledErrorHandler, Selector, SelectorOptions, State, Store, createDispatchMap, createModelSelector, createPickSelector, createPropertySelectors, createSelectMap, createSelector, dispatch, lazyProvider, ofAction, ofActionCanceled, ofActionCompleted, ofActionDispatched, ofActionErrored, ofActionSuccessful, provideStates, provideStore, select, withNgxsDevelopmentOptions, withNgxsPendingTasks, withNgxsPlugin, withNgxsPreboot, NgxsFeatureModule as ɵNgxsFeatureModule, NgxsRootModule as ɵNgxsRootModule, ɵprovideNgxsInternalStateTokens };
2373
+ export { Action, ActionDirector, ActionStatus, Actions, NgxsConfig, NgxsDevelopmentModule, NgxsModule, NgxsSimpleChange, NgxsUnhandledActionsLogger, NgxsUnhandledErrorHandler, Selector, SelectorOptions, State, Store, createDispatchMap, createModelSelector, createPickSelector, createPropertySelectors, createSelectMap, createSelector, dispatch, lazyProvider, ofAction, ofActionCanceled, ofActionCompleted, ofActionDispatched, ofActionErrored, ofActionSuccessful, provideStates, provideStore, select, withNgxsDevelopmentOptions, withNgxsPendingTasks, withNgxsPlugin, withNgxsPreboot, NgxsFeatureModule as ɵNgxsFeatureModule, NgxsRootModule as ɵNgxsRootModule, ɵprovideNgxsInternalStateTokens };
2348
2374
  //# sourceMappingURL=ngxs-store.mjs.map