@ngxs/store 3.7.6-dev.master-f2e2560 → 3.7.6-dev.master-daef739

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.
Files changed (32) hide show
  1. package/bundles/ngxs-store.umd.js +148 -97
  2. package/bundles/ngxs-store.umd.js.map +1 -1
  3. package/esm2015/src/actions-stream.js +3 -37
  4. package/esm2015/src/decorators/selector/selector.js +2 -5
  5. package/esm2015/src/decorators/selector-options.js +2 -2
  6. package/esm2015/src/internal/custom-rxjs-subjects.js +81 -0
  7. package/esm2015/src/internal/state-stream.js +3 -3
  8. package/esm2015/src/public_api.js +2 -3
  9. package/esm2015/src/selectors/create-model-selector.js +2 -2
  10. package/esm2015/src/selectors/create-pick-selector.js +2 -2
  11. package/esm2015/src/selectors/create-property-selectors.js +2 -2
  12. package/esm2015/src/selectors/create-selector.js +9 -0
  13. package/esm2015/src/selectors/index.js +2 -1
  14. package/esm2015/src/selectors/selector-metadata.js +30 -0
  15. package/esm2015/src/selectors/selector-models.js +2 -0
  16. package/esm2015/src/selectors/selector-utils.js +74 -0
  17. package/esm2015/src/store.js +5 -5
  18. package/fesm2015/ngxs-store.js +118 -74
  19. package/fesm2015/ngxs-store.js.map +1 -1
  20. package/package.json +1 -1
  21. package/src/actions-stream.d.ts +2 -21
  22. package/src/decorators/selector/selector.d.ts +7 -2
  23. package/src/internal/custom-rxjs-subjects.d.ts +37 -0
  24. package/src/internal/state-stream.d.ts +2 -2
  25. package/src/public_api.d.ts +1 -2
  26. package/src/selectors/create-selector.d.ts +19 -0
  27. package/src/selectors/index.d.ts +1 -0
  28. package/src/selectors/selector-metadata.d.ts +7 -0
  29. package/src/selectors/selector-models.d.ts +10 -0
  30. package/src/selectors/selector-utils.d.ts +9 -0
  31. package/esm2015/src/utils/selector-utils.js +0 -108
  32. package/src/utils/selector-utils.d.ts +0 -23
@@ -1169,29 +1169,47 @@
1169
1169
  };
1170
1170
  }
1171
1171
 
1172
- var InternalNgxsExecutionStrategy = /** @class */ (function () {
1173
- function InternalNgxsExecutionStrategy(_executionStrategy) {
1174
- this._executionStrategy = _executionStrategy;
1175
- }
1176
- InternalNgxsExecutionStrategy.prototype.enter = function (func) {
1177
- return this._executionStrategy.enter(func);
1178
- };
1179
- InternalNgxsExecutionStrategy.prototype.leave = function (func) {
1180
- return this._executionStrategy.leave(func);
1172
+ /**
1173
+ * This wraps the provided function, and will enforce the following:
1174
+ * - The calls will execute in the order that they are made
1175
+ * - A call will only be initiated when the previous call has completed
1176
+ * - If there is a call currently executing then the new call will be added
1177
+ * to the queue and the function will return immediately
1178
+ *
1179
+ * NOTE: The following assumptions about the operation must hold true:
1180
+ * - The operation is synchronous in nature
1181
+ * - If any asynchronous side effects of the call exist, it should not
1182
+ * have any bearing on the correctness of the next call in the queue
1183
+ * - The operation has a void return
1184
+ * - The caller should not assume that the call has completed upon
1185
+ * return of the function
1186
+ * - The caller can assume that all the queued calls will complete
1187
+ * within the current microtask
1188
+ * - The only way that a call will encounter another call in the queue
1189
+ * would be if the call at the front of the queue initiated this call
1190
+ * as part of its synchronous execution
1191
+ */
1192
+ function orderedQueueOperation(operation) {
1193
+ var callsQueue = [];
1194
+ var busyPushingNext = false;
1195
+ return function callOperation() {
1196
+ var args = [];
1197
+ for (var _i = 0; _i < arguments.length; _i++) {
1198
+ args[_i] = arguments[_i];
1199
+ }
1200
+ if (busyPushingNext) {
1201
+ callsQueue.unshift(args);
1202
+ return;
1203
+ }
1204
+ busyPushingNext = true;
1205
+ operation.apply(void 0, __spreadArray([], __read(args)));
1206
+ while (callsQueue.length > 0) {
1207
+ var nextCallArgs = callsQueue.pop();
1208
+ nextCallArgs && operation.apply(void 0, __spreadArray([], __read(nextCallArgs)));
1209
+ }
1210
+ busyPushingNext = false;
1181
1211
  };
1182
- return InternalNgxsExecutionStrategy;
1183
- }());
1184
- /** @nocollapse */ InternalNgxsExecutionStrategy.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0__namespace, type: InternalNgxsExecutionStrategy, deps: [{ token: NGXS_EXECUTION_STRATEGY }], target: i0__namespace.ɵɵFactoryTarget.Injectable });
1185
- /** @nocollapse */ InternalNgxsExecutionStrategy.ɵprov = i0__namespace.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0__namespace, type: InternalNgxsExecutionStrategy });
1186
- i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0__namespace, type: InternalNgxsExecutionStrategy, decorators: [{
1187
- type: i0.Injectable
1188
- }], ctorParameters: function () {
1189
- return [{ type: undefined, decorators: [{
1190
- type: i0.Inject,
1191
- args: [NGXS_EXECUTION_STRATEGY]
1192
- }] }];
1193
- } });
1194
-
1212
+ }
1195
1213
  /**
1196
1214
  * Custom Subject that ensures that subscribers are notified of values in the order that they arrived.
1197
1215
  * A standard Subject does not have this guarantee.
@@ -1211,25 +1229,59 @@
1211
1229
  __extends(OrderedSubject, _super);
1212
1230
  function OrderedSubject() {
1213
1231
  var _this = _super.apply(this, __spreadArray([], __read(arguments))) || this;
1214
- _this._itemQueue = [];
1215
- _this._busyPushingNext = false;
1232
+ _this.next = orderedQueueOperation(function (value) { return _super.prototype.next.call(_this, value); });
1216
1233
  return _this;
1217
1234
  }
1218
- OrderedSubject.prototype.next = function (value) {
1219
- if (this._busyPushingNext) {
1220
- this._itemQueue.unshift(value);
1221
- return;
1222
- }
1223
- this._busyPushingNext = true;
1224
- _super.prototype.next.call(this, value);
1225
- while (this._itemQueue.length > 0) {
1226
- var nextValue = this._itemQueue.pop();
1227
- _super.prototype.next.call(this, nextValue);
1228
- }
1229
- this._busyPushingNext = false;
1230
- };
1231
1235
  return OrderedSubject;
1232
1236
  }(rxjs.Subject));
1237
+ /**
1238
+ * Custom BehaviorSubject that ensures that subscribers are notified of values in the order that they arrived.
1239
+ * A standard BehaviorSubject does not have this guarantee.
1240
+ * For example, given the following code:
1241
+ * ```typescript
1242
+ * const subject = new BehaviorSubject<string>();
1243
+ subject.subscribe(value => {
1244
+ if (value === 'start') subject.next('end');
1245
+ });
1246
+ subject.subscribe(value => { });
1247
+ subject.next('start');
1248
+ * ```
1249
+ * When `subject` is a standard `BehaviorSubject<T>` the second subscriber would recieve `end` and then `start`.
1250
+ * When `subject` is a `OrderedBehaviorSubject<T>` the second subscriber would recieve `start` and then `end`.
1251
+ */
1252
+ var OrderedBehaviorSubject = /** @class */ (function (_super) {
1253
+ __extends(OrderedBehaviorSubject, _super);
1254
+ function OrderedBehaviorSubject() {
1255
+ var _this = _super.apply(this, __spreadArray([], __read(arguments))) || this;
1256
+ _this.next = orderedQueueOperation(function (value) { return _super.prototype.next.call(_this, value); });
1257
+ return _this;
1258
+ }
1259
+ return OrderedBehaviorSubject;
1260
+ }(rxjs.BehaviorSubject));
1261
+
1262
+ var InternalNgxsExecutionStrategy = /** @class */ (function () {
1263
+ function InternalNgxsExecutionStrategy(_executionStrategy) {
1264
+ this._executionStrategy = _executionStrategy;
1265
+ }
1266
+ InternalNgxsExecutionStrategy.prototype.enter = function (func) {
1267
+ return this._executionStrategy.enter(func);
1268
+ };
1269
+ InternalNgxsExecutionStrategy.prototype.leave = function (func) {
1270
+ return this._executionStrategy.leave(func);
1271
+ };
1272
+ return InternalNgxsExecutionStrategy;
1273
+ }());
1274
+ /** @nocollapse */ InternalNgxsExecutionStrategy.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0__namespace, type: InternalNgxsExecutionStrategy, deps: [{ token: NGXS_EXECUTION_STRATEGY }], target: i0__namespace.ɵɵFactoryTarget.Injectable });
1275
+ /** @nocollapse */ InternalNgxsExecutionStrategy.ɵprov = i0__namespace.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0__namespace, type: InternalNgxsExecutionStrategy });
1276
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0__namespace, type: InternalNgxsExecutionStrategy, decorators: [{
1277
+ type: i0.Injectable
1278
+ }], ctorParameters: function () {
1279
+ return [{ type: undefined, decorators: [{
1280
+ type: i0.Inject,
1281
+ args: [NGXS_EXECUTION_STRATEGY]
1282
+ }] }];
1283
+ } });
1284
+
1233
1285
  /**
1234
1286
  * Internal Action stream that is emitted anytime an action is dispatched.
1235
1287
  */
@@ -1436,7 +1488,7 @@
1436
1488
  this.complete();
1437
1489
  };
1438
1490
  return StateStream;
1439
- }(rxjs.BehaviorSubject));
1491
+ }(OrderedBehaviorSubject));
1440
1492
  /** @nocollapse */ StateStream.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0__namespace, type: StateStream, deps: [], target: i0__namespace.ɵɵFactoryTarget.Injectable });
1441
1493
  /** @nocollapse */ StateStream.ɵprov = i0__namespace.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0__namespace, type: StateStream });
1442
1494
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0__namespace, type: StateStream, decorators: [{
@@ -2032,41 +2084,8 @@
2032
2084
  }] }];
2033
2085
  } });
2034
2086
 
2035
- var SELECTOR_OPTIONS_META_KEY = 'NGXS_SELECTOR_OPTIONS_META';
2036
- var selectorOptionsMetaAccessor = {
2037
- getOptions: function (target) {
2038
- return (target && target[SELECTOR_OPTIONS_META_KEY]) || {};
2039
- },
2040
- defineOptions: function (target, options) {
2041
- if (!target)
2042
- return;
2043
- target[SELECTOR_OPTIONS_META_KEY] = options;
2044
- }
2045
- };
2046
- /**
2047
- * Function for creating a selector
2048
- * @param selectors The selectors to use to create the arguments of this function
2049
- * @param originalFn The original function being made into a selector
2050
- * @param creationMetadata
2051
- */
2052
- function createSelector(selectors, originalFn, creationMetadata) {
2053
- var containerClass = creationMetadata && creationMetadata.containerClass;
2054
- var wrappedFn = function wrappedSelectorFn() {
2055
- var args = [];
2056
- for (var _i = 0; _i < arguments.length; _i++) {
2057
- args[_i] = arguments[_i];
2058
- }
2059
- var returnValue = originalFn.apply(containerClass, args);
2060
- if (returnValue instanceof Function) {
2061
- var innerMemoizedFn = i5.memoize.apply(null, [returnValue]);
2062
- return innerMemoizedFn;
2063
- }
2064
- return returnValue;
2065
- };
2066
- var memoizedFn = i5.memoize(wrappedFn);
2067
- Object.setPrototypeOf(memoizedFn, originalFn);
2068
- var selectorMetaData = setupSelectorMetadata(originalFn, creationMetadata);
2069
- var makeRootSelector = function (context) {
2087
+ function createRootSelectorFactory(selectorMetaData, selectors, memoizedSelectorFn) {
2088
+ return function (context) {
2070
2089
  var _a = getRuntimeSelectorInfo(context, selectorMetaData, selectors), argumentSelectorFunctions = _a.argumentSelectorFunctions, selectorOptions = _a.selectorOptions;
2071
2090
  return function selectFromRoot(rootState) {
2072
2091
  // Determine arguments from the app state using the selectors
@@ -2075,7 +2094,7 @@
2075
2094
  // state that doesn't exist, it will throw a TypeError.
2076
2095
  // since this is quite usual behaviour, we simply return undefined if so.
2077
2096
  try {
2078
- return memoizedFn.apply(void 0, __spreadArray([], __read(results)));
2097
+ return memoizedSelectorFn.apply(void 0, __spreadArray([], __read(results)));
2079
2098
  }
2080
2099
  catch (ex) {
2081
2100
  if (ex instanceof TypeError && selectorOptions.suppressErrors) {
@@ -2085,22 +2104,24 @@
2085
2104
  }
2086
2105
  };
2087
2106
  };
2088
- selectorMetaData.makeRootSelector = makeRootSelector;
2089
- return memoizedFn;
2090
2107
  }
2091
- function setupSelectorMetadata(originalFn, creationMetadata) {
2092
- var selectorMetaData = ensureSelectorMetadata$1(originalFn);
2093
- selectorMetaData.originalFn = originalFn;
2094
- var getExplicitSelectorOptions = function () { return ({}); };
2095
- if (creationMetadata) {
2096
- selectorMetaData.containerClass = creationMetadata.containerClass;
2097
- selectorMetaData.selectorName = creationMetadata.selectorName;
2098
- getExplicitSelectorOptions =
2099
- creationMetadata.getSelectorOptions || getExplicitSelectorOptions;
2100
- }
2101
- var selectorMetaDataClone = Object.assign({}, selectorMetaData);
2102
- selectorMetaData.getSelectorOptions = function () { return getLocalSelectorOptions(selectorMetaDataClone, getExplicitSelectorOptions()); };
2103
- return selectorMetaData;
2108
+ function createMemoizedSelectorFn(originalFn, creationMetadata) {
2109
+ var containerClass = creationMetadata && creationMetadata.containerClass;
2110
+ var wrappedFn = function wrappedSelectorFn() {
2111
+ var args = [];
2112
+ for (var _i = 0; _i < arguments.length; _i++) {
2113
+ args[_i] = arguments[_i];
2114
+ }
2115
+ var returnValue = originalFn.apply(containerClass, args);
2116
+ if (returnValue instanceof Function) {
2117
+ var innerMemoizedFn = i5.memoize.apply(null, [returnValue]);
2118
+ return innerMemoizedFn;
2119
+ }
2120
+ return returnValue;
2121
+ };
2122
+ var memoizedFn = i5.memoize(wrappedFn);
2123
+ Object.setPrototypeOf(memoizedFn, originalFn);
2124
+ return memoizedFn;
2104
2125
  }
2105
2126
  function getRuntimeSelectorInfo(context, selectorMetaData, selectors) {
2106
2127
  if (selectors === void 0) { selectors = []; }
@@ -2113,12 +2134,9 @@
2113
2134
  });
2114
2135
  return {
2115
2136
  selectorOptions: selectorOptions,
2116
- argumentSelectorFunctions: argumentSelectorFunctions
2137
+ argumentSelectorFunctions: argumentSelectorFunctions,
2117
2138
  };
2118
2139
  }
2119
- function getLocalSelectorOptions(selectorMetaData, explicitOptions) {
2120
- return Object.assign(Object.assign(Object.assign(Object.assign({}, (selectorOptionsMetaAccessor.getOptions(selectorMetaData.containerClass) || {})), (selectorOptionsMetaAccessor.getOptions(selectorMetaData.originalFn) || {})), (selectorMetaData.getSelectorOptions() || {})), explicitOptions);
2121
- }
2122
2140
  function getSelectorsToApply(selectors, selectorOptions, containerClass) {
2123
2141
  if (selectors === void 0) { selectors = []; }
2124
2142
  var selectorsToApply = [];
@@ -2157,7 +2175,7 @@
2157
2175
  * because state is being changed actually within the `<root>` zone, see `InternalDispatcher#dispatchSingle`.
2158
2176
  * All selects would use this stream, and it would call leave only once for any state change across all active selectors.
2159
2177
  */
2160
- this._selectableStateStream = this._stateStream.pipe(operators.observeOn(rxjs.queueScheduler), leaveNgxs(this._internalExecutionStrategy), operators.shareReplay({ bufferSize: 1, refCount: true }));
2178
+ this._selectableStateStream = this._stateStream.pipe(leaveNgxs(this._internalExecutionStrategy), operators.shareReplay({ bufferSize: 1, refCount: true }));
2161
2179
  this.initStateStream(initialStateValue);
2162
2180
  }
2163
2181
  /**
@@ -2662,6 +2680,35 @@
2662
2680
  };
2663
2681
  }
2664
2682
 
2683
+ var SELECTOR_OPTIONS_META_KEY = 'NGXS_SELECTOR_OPTIONS_META';
2684
+ var selectorOptionsMetaAccessor = {
2685
+ getOptions: function (target) {
2686
+ return (target && target[SELECTOR_OPTIONS_META_KEY]) || {};
2687
+ },
2688
+ defineOptions: function (target, options) {
2689
+ if (!target)
2690
+ return;
2691
+ target[SELECTOR_OPTIONS_META_KEY] = options;
2692
+ },
2693
+ };
2694
+ function setupSelectorMetadata(originalFn, creationMetadata) {
2695
+ var selectorMetaData = ensureSelectorMetadata$1(originalFn);
2696
+ selectorMetaData.originalFn = originalFn;
2697
+ var getExplicitSelectorOptions = function () { return ({}); };
2698
+ if (creationMetadata) {
2699
+ selectorMetaData.containerClass = creationMetadata.containerClass;
2700
+ selectorMetaData.selectorName = creationMetadata.selectorName || null;
2701
+ getExplicitSelectorOptions =
2702
+ creationMetadata.getSelectorOptions || getExplicitSelectorOptions;
2703
+ }
2704
+ var selectorMetaDataClone = Object.assign({}, selectorMetaData);
2705
+ selectorMetaData.getSelectorOptions = function () { return getLocalSelectorOptions(selectorMetaDataClone, getExplicitSelectorOptions()); };
2706
+ return selectorMetaData;
2707
+ }
2708
+ function getLocalSelectorOptions(selectorMetaData, explicitOptions) {
2709
+ return Object.assign(Object.assign(Object.assign(Object.assign({}, (selectorOptionsMetaAccessor.getOptions(selectorMetaData.containerClass) || {})), (selectorOptionsMetaAccessor.getOptions(selectorMetaData.originalFn) || {})), (selectorMetaData.getSelectorOptions() || {})), explicitOptions);
2710
+ }
2711
+
2665
2712
  /**
2666
2713
  * Decorator for setting selector options at a method or class level.
2667
2714
  */
@@ -2695,9 +2742,13 @@
2695
2742
  return getSelectorMetadata$1(target);
2696
2743
  }
2697
2744
 
2698
- /**
2699
- * Decorator for memoizing a state selector.
2700
- */
2745
+ function createSelector(selectors, projector, creationMetadata) {
2746
+ var memoizedFn = createMemoizedSelectorFn(projector, creationMetadata);
2747
+ var selectorMetaData = setupSelectorMetadata(projector, creationMetadata);
2748
+ selectorMetaData.makeRootSelector = createRootSelectorFactory(selectorMetaData, selectors, memoizedFn);
2749
+ return memoizedFn;
2750
+ }
2751
+
2701
2752
  function Selector(selectors) {
2702
2753
  return function (target, key, descriptor) {
2703
2754
  descriptor || (descriptor = Object.getOwnPropertyDescriptor(target, key));