mobx-state-tree 5.1.8 → 5.2.0-alpha.1

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,4 +1,4 @@
1
- import { isComputedProp, isObservableProp, createAtom, action, computed, _allowStateChangesInsideComputed, reaction, runInAction, observable, values, entries, _getGlobalState, isObservableArray, isObservableObject, defineProperty as defineProperty$1, ObservableMap, _interceptReads, intercept, observe, _getAdministration, set, makeObservable, getAtom } from 'mobx';
1
+ import { isComputedProp, isObservableProp, createAtom, action, computed, _allowStateChangesInsideComputed, reaction, runInAction, observable, values, entries, _getGlobalState, isObservableArray, isObservableObject, defineProperty as defineProperty$1, ObservableMap, _interceptReads, intercept, observe, _getAdministration, set, makeObservable, getAtom, when } from 'mobx';
2
2
 
3
3
  var livelinessChecking = "warn";
4
4
  /**
@@ -838,14 +838,21 @@ function getPropertyMembers(typeOrNode) {
838
838
  };
839
839
  }
840
840
  /**
841
- * Returns a reflection of the model node, including name, properties, views, volatile and actions.
841
+ * Returns a reflection of the model node, including name, properties, views, volatile state,
842
+ * and actions. `flowActions` is also provided as a separate array of names for any action that
843
+ * came from a flow generator as well.
844
+ *
845
+ * In the case where a model has two actions: `doSomething` and `doSomethingWithFlow`, where
846
+ * `doSomethingWithFlow` is a flow generator, the `actions` array will contain both actions,
847
+ * i.e. ["doSomething", "doSomethingWithFlow"], and the `flowActions` array will contain only
848
+ * the flow action, i.e. ["doSomethingWithFlow"].
842
849
  *
843
850
  * @param target
844
851
  * @returns
845
852
  */
846
853
  function getMembers(target) {
847
854
  var type = getStateTreeNode(target).type;
848
- var reflected = __assign(__assign({}, getPropertyMembers(type)), { actions: [], volatile: [], views: [] });
855
+ var reflected = __assign(__assign({}, getPropertyMembers(type)), { actions: [], volatile: [], views: [], flowActions: [] });
849
856
  var props = Object.getOwnPropertyNames(target);
850
857
  props.forEach(function (key) {
851
858
  if (key in reflected.properties)
@@ -860,6 +867,8 @@ function getMembers(target) {
860
867
  }
861
868
  if (descriptor.value._isMSTAction === true)
862
869
  reflected.actions.push(key);
870
+ if (descriptor.value._isFlowAction === true)
871
+ reflected.flowActions.push(key);
863
872
  else if (isObservableProp(target, key))
864
873
  reflected.volatile.push(key);
865
874
  else
@@ -1586,9 +1595,10 @@ var ObjectNode = /** @class */ (function (_super) {
1586
1595
  enumerable: false,
1587
1596
  configurable: true,
1588
1597
  writable: true,
1589
- value: function () {
1598
+ value: function (fireHooks) {
1599
+ if (fireHooks === void 0) { fireHooks = true; }
1590
1600
  if (this._observableInstanceState === 0 /* UNINITIALIZED */) {
1591
- this.createObservableInstance();
1601
+ this.createObservableInstance(fireHooks);
1592
1602
  }
1593
1603
  }
1594
1604
  });
@@ -1596,8 +1606,9 @@ var ObjectNode = /** @class */ (function (_super) {
1596
1606
  enumerable: false,
1597
1607
  configurable: true,
1598
1608
  writable: true,
1599
- value: function () {
1600
- var e_1, _a;
1609
+ value: function (fireHooks) {
1610
+ var e_1, _a, e_2, _b;
1611
+ if (fireHooks === void 0) { fireHooks = true; }
1601
1612
  if (devMode()) {
1602
1613
  if (this.state !== NodeLifeCycle.INITIALIZING) {
1603
1614
  // istanbul ignore next
@@ -1622,7 +1633,8 @@ var ObjectNode = /** @class */ (function (_super) {
1622
1633
  // initialize the uninitialized parent chain from parent to child
1623
1634
  for (var parentChain_1 = __values(parentChain), parentChain_1_1 = parentChain_1.next(); !parentChain_1_1.done; parentChain_1_1 = parentChain_1.next()) {
1624
1635
  var p = parentChain_1_1.value;
1625
- p.createObservableInstanceIfNeeded();
1636
+ // delay firing hooks until after all parents have been created
1637
+ p.createObservableInstanceIfNeeded(false);
1626
1638
  }
1627
1639
  }
1628
1640
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
@@ -1653,8 +1665,28 @@ var ObjectNode = /** @class */ (function (_super) {
1653
1665
  this._addSnapshotReaction();
1654
1666
  this._childNodes = EMPTY_OBJECT;
1655
1667
  this.state = NodeLifeCycle.CREATED;
1656
- this.fireHook(Hook.afterCreate);
1657
- this.finalizeCreation();
1668
+ if (fireHooks) {
1669
+ this.fireHook(Hook.afterCreate);
1670
+ // Note that the parent might not be finalized at this point
1671
+ // so afterAttach won't be called until later in that case
1672
+ this.finalizeCreation();
1673
+ try {
1674
+ // fire the hooks of the parents that we created
1675
+ for (var _c = __values(parentChain.reverse()), _d = _c.next(); !_d.done; _d = _c.next()) {
1676
+ var p = _d.value;
1677
+ p.fireHook(Hook.afterCreate);
1678
+ // This will call afterAttach on the child if necessary
1679
+ p.finalizeCreation();
1680
+ }
1681
+ }
1682
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
1683
+ finally {
1684
+ try {
1685
+ if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
1686
+ }
1687
+ finally { if (e_2) throw e_2.error; }
1688
+ }
1689
+ }
1658
1690
  }
1659
1691
  });
1660
1692
  Object.defineProperty(ObjectNode.prototype, "root", {
@@ -1953,19 +1985,19 @@ var ObjectNode = /** @class */ (function (_super) {
1953
1985
  value: function () {
1954
1986
  var _this = this;
1955
1987
  this.baseFinalizeCreation(function () {
1956
- var e_2, _a;
1988
+ var e_3, _a;
1957
1989
  try {
1958
1990
  for (var _b = __values(_this.getChildren()), _c = _b.next(); !_c.done; _c = _b.next()) {
1959
1991
  var child = _c.value;
1960
1992
  child.finalizeCreation();
1961
1993
  }
1962
1994
  }
1963
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
1995
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
1964
1996
  finally {
1965
1997
  try {
1966
1998
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1967
1999
  }
1968
- finally { if (e_2) throw e_2.error; }
2000
+ finally { if (e_3) throw e_3.error; }
1969
2001
  }
1970
2002
  _this.fireInternalHook(Hook.afterCreationFinalization);
1971
2003
  });
@@ -2289,6 +2321,9 @@ var TypeFlags;
2289
2321
  TypeFlags[TypeFlags["Integer"] = 131072] = "Integer";
2290
2322
  TypeFlags[TypeFlags["Custom"] = 262144] = "Custom";
2291
2323
  TypeFlags[TypeFlags["SnapshotProcessor"] = 524288] = "SnapshotProcessor";
2324
+ TypeFlags[TypeFlags["Lazy"] = 1048576] = "Lazy";
2325
+ TypeFlags[TypeFlags["Finite"] = 2097152] = "Finite";
2326
+ TypeFlags[TypeFlags["Float"] = 4194304] = "Float";
2292
2327
  })(TypeFlags || (TypeFlags = {}));
2293
2328
  /**
2294
2329
  * @internal
@@ -3137,6 +3172,7 @@ function createActionInvoker(target, name, fn) {
3137
3172
  }, fn);
3138
3173
  };
3139
3174
  res._isMSTAction = true;
3175
+ res._isFlowAction = fn._isFlowAction;
3140
3176
  return res;
3141
3177
  }
3142
3178
  /**
@@ -3552,17 +3588,25 @@ var IdentifierCache = /** @class */ (function () {
3552
3588
  enumerable: false,
3553
3589
  configurable: true,
3554
3590
  writable: true,
3555
- value: function (node) {
3591
+ value: function (splitNode) {
3556
3592
  var _this = this;
3557
- var res = new IdentifierCache();
3558
- var basePath = node.path;
3593
+ var newCache = new IdentifierCache();
3594
+ // The slash is added here so we only match children of the splitNode. In version 5.1.8 and
3595
+ // earlier there was no trailing slash, so non children that started with the same path string
3596
+ // were being matched incorrectly.
3597
+ var basePath = splitNode.path + "/";
3559
3598
  entries(this.cache).forEach(function (_a) {
3560
3599
  var _b = __read(_a, 2), id = _b[0], nodes = _b[1];
3561
3600
  var modified = false;
3562
3601
  for (var i = nodes.length - 1; i >= 0; i--) {
3563
- if (nodes[i].path.indexOf(basePath) === 0) {
3564
- res.addNodeToCache(nodes[i], false); // no need to update lastUpdated since it is a whole new cache
3602
+ var node = nodes[i];
3603
+ if (node === splitNode || node.path.indexOf(basePath) === 0) {
3604
+ newCache.addNodeToCache(node, false); // no need to update lastUpdated since it is a whole new cache
3565
3605
  nodes.splice(i, 1);
3606
+ // remove empty sets from cache
3607
+ if (!nodes.length) {
3608
+ _this.cache.delete(id);
3609
+ }
3566
3610
  modified = true;
3567
3611
  }
3568
3612
  }
@@ -3570,7 +3614,7 @@ var IdentifierCache = /** @class */ (function () {
3570
3614
  _this.updateLastCacheModificationPerId(id);
3571
3615
  }
3572
3616
  });
3573
- return res;
3617
+ return newCache;
3574
3618
  }
3575
3619
  });
3576
3620
  Object.defineProperty(IdentifierCache.prototype, "has", {
@@ -3854,15 +3898,24 @@ function identity(_) {
3854
3898
  return _;
3855
3899
  }
3856
3900
  /**
3857
- * pollyfill (for IE) suggested in MDN:
3858
- * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
3859
3901
  * @internal
3860
3902
  * @hidden
3861
3903
  */
3862
- var isInteger = Number.isInteger ||
3863
- function (value) {
3864
- return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
3865
- };
3904
+ var isInteger = Number.isInteger;
3905
+ /**
3906
+ * @internal
3907
+ * @hidden
3908
+ */
3909
+ function isFloat(val) {
3910
+ return Number(val) === val && val % 1 !== 0;
3911
+ }
3912
+ /**
3913
+ * @internal
3914
+ * @hidden
3915
+ */
3916
+ function isFinite(val) {
3917
+ return Number.isFinite(val);
3918
+ }
3866
3919
  /**
3867
3920
  * @internal
3868
3921
  * @hidden
@@ -4467,6 +4520,7 @@ function createFlowSpawner(name, generator) {
4467
4520
  }
4468
4521
  });
4469
4522
  };
4523
+ spawner._isFlowAction = true;
4470
4524
  return spawner;
4471
4525
  }
4472
4526
 
@@ -4880,8 +4934,8 @@ var MapIdentifierMode;
4880
4934
  })(MapIdentifierMode || (MapIdentifierMode = {}));
4881
4935
  var MSTMap = /** @class */ (function (_super) {
4882
4936
  __extends(MSTMap, _super);
4883
- function MSTMap(initialData) {
4884
- return _super.call(this, initialData, observable.ref.enhancer) || this;
4937
+ function MSTMap(initialData, name) {
4938
+ return _super.call(this, initialData, observable.ref.enhancer, name) || this;
4885
4939
  }
4886
4940
  Object.defineProperty(MSTMap.prototype, "get", {
4887
4941
  enumerable: false,
@@ -5069,7 +5123,7 @@ var MapType = /** @class */ (function (_super) {
5069
5123
  configurable: true,
5070
5124
  writable: true,
5071
5125
  value: function (childNodes) {
5072
- return new MSTMap(childNodes);
5126
+ return new MSTMap(childNodes, this.describe());
5073
5127
  }
5074
5128
  });
5075
5129
  Object.defineProperty(MapType.prototype, "finalizeNewInstance", {
@@ -5411,7 +5465,8 @@ var ArrayType = /** @class */ (function (_super) {
5411
5465
  configurable: true,
5412
5466
  writable: true,
5413
5467
  value: function (childNodes) {
5414
- return observable.array(convertChildNodesToArray(childNodes), mobxShallow);
5468
+ var options = __assign(__assign({}, mobxShallow), { name: this.describe() });
5469
+ return observable.array(convertChildNodesToArray(childNodes), options);
5415
5470
  }
5416
5471
  });
5417
5472
  Object.defineProperty(ArrayType.prototype, "finalizeNewInstance", {
@@ -6015,6 +6070,7 @@ var ModelType = /** @class */ (function (_super) {
6015
6070
  // while still allowing the middlewares to register them
6016
6071
  var middlewares = action2.$mst_middleware; // make sure middlewares are not lost
6017
6072
  var boundAction = action2.bind(actions);
6073
+ boundAction._isFlowAction = action2._isFlowAction || false;
6018
6074
  boundAction.$mst_middleware = middlewares;
6019
6075
  var actionInvoker = createActionInvoker(self, name, boundAction);
6020
6076
  actions[name] = actionInvoker;
@@ -6140,7 +6196,8 @@ var ModelType = /** @class */ (function (_super) {
6140
6196
  configurable: true,
6141
6197
  writable: true,
6142
6198
  value: function (childNodes) {
6143
- return observable.object(childNodes, EMPTY_OBJECT, mobxShallow);
6199
+ var options = __assign(__assign({}, mobxShallow), { name: this.describe() });
6200
+ return observable.object(childNodes, EMPTY_OBJECT, options);
6144
6201
  }
6145
6202
  });
6146
6203
  Object.defineProperty(ModelType.prototype, "finalizeNewInstance", {
@@ -6374,6 +6431,9 @@ function model() {
6374
6431
  for (var _i = 0; _i < arguments.length; _i++) {
6375
6432
  args[_i] = arguments[_i];
6376
6433
  }
6434
+ if (devMode() && typeof args[0] !== "string" && args[1]) {
6435
+ throw fail$1("Model creation failed. First argument must be a string when two arguments are provided");
6436
+ }
6377
6437
  var name = typeof args[0] === "string" ? args.shift() : "AnonymousModel";
6378
6438
  var properties = args.shift() || {};
6379
6439
  return new ModelType({ name: name, properties: properties });
@@ -6527,7 +6587,6 @@ var string = new CoreType("string", TypeFlags.String, function (v) { return type
6527
6587
  var number = new CoreType("number", TypeFlags.Number, function (v) { return typeof v === "number"; });
6528
6588
  /**
6529
6589
  * `types.integer` - Creates a type that can only contain an integer value.
6530
- * This type is used for integer values by default
6531
6590
  *
6532
6591
  * Example:
6533
6592
  * ```ts
@@ -6539,6 +6598,32 @@ var number = new CoreType("number", TypeFlags.Number, function (v) { return type
6539
6598
  */
6540
6599
  // tslint:disable-next-line:variable-name
6541
6600
  var integer = new CoreType("integer", TypeFlags.Integer, function (v) { return isInteger(v); });
6601
+ /**
6602
+ * `types.float` - Creates a type that can only contain an float value.
6603
+ *
6604
+ * Example:
6605
+ * ```ts
6606
+ * const Size = types.model({
6607
+ * width: types.float,
6608
+ * height: 10
6609
+ * })
6610
+ * ```
6611
+ */
6612
+ // tslint:disable-next-line:variable-name
6613
+ var float = new CoreType("float", TypeFlags.Float, function (v) { return isFloat(v); });
6614
+ /**
6615
+ * `types.finite` - Creates a type that can only contain an finite value.
6616
+ *
6617
+ * Example:
6618
+ * ```ts
6619
+ * const Size = types.model({
6620
+ * width: types.finite,
6621
+ * height: 10
6622
+ * })
6623
+ * ```
6624
+ */
6625
+ // tslint:disable-next-line:variable-name
6626
+ var finite = new CoreType("finite", TypeFlags.Finite, function (v) { return isFinite(v); });
6542
6627
  /**
6543
6628
  * `types.boolean` - Creates a type that can only contain a boolean value.
6544
6629
  * This type is used for boolean values by default
@@ -7078,7 +7163,7 @@ var OptionalValue = /** @class */ (function (_super) {
7078
7163
  writable: true,
7079
7164
  value: function (parent, subpath, environment, initialValue) {
7080
7165
  if (this.optionalValues.indexOf(initialValue) >= 0) {
7081
- var defaultInstanceOrSnapshot = this.getDefaultInstanceOrSnapshot();
7166
+ var defaultInstanceOrSnapshot = this.getDefaultInstanceOrSnapshot(parent);
7082
7167
  return this._subtype.instantiate(parent, subpath, environment, defaultInstanceOrSnapshot);
7083
7168
  }
7084
7169
  return this._subtype.instantiate(parent, subpath, environment, initialValue);
@@ -7091,16 +7176,16 @@ var OptionalValue = /** @class */ (function (_super) {
7091
7176
  value: function (current, newValue, parent, subpath) {
7092
7177
  return this._subtype.reconcile(current, this.optionalValues.indexOf(newValue) < 0 && this._subtype.is(newValue)
7093
7178
  ? newValue
7094
- : this.getDefaultInstanceOrSnapshot(), parent, subpath);
7179
+ : this.getDefaultInstanceOrSnapshot(parent), parent, subpath);
7095
7180
  }
7096
7181
  });
7097
7182
  Object.defineProperty(OptionalValue.prototype, "getDefaultInstanceOrSnapshot", {
7098
7183
  enumerable: false,
7099
7184
  configurable: true,
7100
7185
  writable: true,
7101
- value: function () {
7186
+ value: function (parent) {
7102
7187
  var defaultInstanceOrSnapshot = typeof this._defaultValue === "function"
7103
- ? this._defaultValue()
7188
+ ? this._defaultValue(parent)
7104
7189
  : this._defaultValue;
7105
7190
  // while static values are already snapshots and checked on types.optional
7106
7191
  // generator functions must always be rechecked just in case
@@ -7388,6 +7473,120 @@ function isLateType(type) {
7388
7473
  return isType(type) && (type.flags & TypeFlags.Late) > 0;
7389
7474
  }
7390
7475
 
7476
+ function lazy(name, options) {
7477
+ // TODO: fix this unknown casting to be stricter
7478
+ return new Lazy(name, options);
7479
+ }
7480
+ /**
7481
+ * @internal
7482
+ * @hidden
7483
+ */
7484
+ var Lazy = /** @class */ (function (_super) {
7485
+ __extends(Lazy, _super);
7486
+ function Lazy(name, options) {
7487
+ var _this = _super.call(this, name) || this;
7488
+ Object.defineProperty(_this, "options", {
7489
+ enumerable: true,
7490
+ configurable: true,
7491
+ writable: true,
7492
+ value: options
7493
+ });
7494
+ Object.defineProperty(_this, "flags", {
7495
+ enumerable: true,
7496
+ configurable: true,
7497
+ writable: true,
7498
+ value: TypeFlags.Lazy
7499
+ });
7500
+ Object.defineProperty(_this, "loadedType", {
7501
+ enumerable: true,
7502
+ configurable: true,
7503
+ writable: true,
7504
+ value: null
7505
+ });
7506
+ Object.defineProperty(_this, "pendingNodeList", {
7507
+ enumerable: true,
7508
+ configurable: true,
7509
+ writable: true,
7510
+ value: observable.array()
7511
+ });
7512
+ when(function () {
7513
+ return _this.pendingNodeList.length > 0 &&
7514
+ _this.pendingNodeList.some(function (node) {
7515
+ return node.isAlive &&
7516
+ _this.options.shouldLoadPredicate(node.parent ? node.parent.value : null);
7517
+ });
7518
+ }, function () {
7519
+ _this.options.loadType().then(action(function (type) {
7520
+ _this.loadedType = type;
7521
+ _this.pendingNodeList.forEach(function (node) {
7522
+ if (!node.parent)
7523
+ return;
7524
+ if (!_this.loadedType)
7525
+ return;
7526
+ node.parent.applyPatches([
7527
+ {
7528
+ op: "replace",
7529
+ path: "/" + node.subpath,
7530
+ value: node.snapshot
7531
+ }
7532
+ ]);
7533
+ });
7534
+ }));
7535
+ });
7536
+ return _this;
7537
+ }
7538
+ Object.defineProperty(Lazy.prototype, "describe", {
7539
+ enumerable: false,
7540
+ configurable: true,
7541
+ writable: true,
7542
+ value: function () {
7543
+ return "<lazy " + this.name + ">";
7544
+ }
7545
+ });
7546
+ Object.defineProperty(Lazy.prototype, "instantiate", {
7547
+ enumerable: false,
7548
+ configurable: true,
7549
+ writable: true,
7550
+ value: function (parent, subpath, environment, value) {
7551
+ var _this = this;
7552
+ if (this.loadedType) {
7553
+ return this.loadedType.instantiate(parent, subpath, environment, value);
7554
+ }
7555
+ var node = createScalarNode(this, parent, subpath, environment, deepFreeze(value));
7556
+ this.pendingNodeList.push(node);
7557
+ when(function () { return !node.isAlive; }, function () { return _this.pendingNodeList.splice(_this.pendingNodeList.indexOf(node), 1); });
7558
+ return node;
7559
+ }
7560
+ });
7561
+ Object.defineProperty(Lazy.prototype, "isValidSnapshot", {
7562
+ enumerable: false,
7563
+ configurable: true,
7564
+ writable: true,
7565
+ value: function (value, context) {
7566
+ if (this.loadedType) {
7567
+ return this.loadedType.validate(value, context);
7568
+ }
7569
+ if (!isSerializable(value)) {
7570
+ return typeCheckFailure(context, value, "Value is not serializable and cannot be lazy");
7571
+ }
7572
+ return typeCheckSuccess();
7573
+ }
7574
+ });
7575
+ Object.defineProperty(Lazy.prototype, "reconcile", {
7576
+ enumerable: false,
7577
+ configurable: true,
7578
+ writable: true,
7579
+ value: function (current, value, parent, subpath) {
7580
+ if (this.loadedType) {
7581
+ current.die();
7582
+ return this.loadedType.instantiate(parent, subpath, parent.environment, value);
7583
+ }
7584
+ return _super.prototype.reconcile.call(this, current, value, parent, subpath);
7585
+ }
7586
+ });
7587
+ return Lazy;
7588
+ }(SimpleType));
7589
+
7391
7590
  /**
7392
7591
  * @internal
7393
7592
  * @hidden
@@ -8326,6 +8525,8 @@ var types = {
8326
8525
  boolean: boolean,
8327
8526
  number: number,
8328
8527
  integer: integer,
8528
+ float: float,
8529
+ finite: finite,
8329
8530
  Date: DatePrimitive,
8330
8531
  map: map,
8331
8532
  array: array,
@@ -8333,6 +8534,7 @@ var types = {
8333
8534
  identifier: identifier,
8334
8535
  identifierNumber: identifierNumber,
8335
8536
  late: late,
8537
+ lazy: lazy,
8336
8538
  undefined: undefinedType,
8337
8539
  null: nullType,
8338
8540
  snapshotProcessor: snapshotProcessor