mobx-state-tree 5.1.7 → 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.
@@ -842,14 +842,21 @@
842
842
  };
843
843
  }
844
844
  /**
845
- * Returns a reflection of the model node, including name, properties, views, volatile and actions.
845
+ * Returns a reflection of the model node, including name, properties, views, volatile state,
846
+ * and actions. `flowActions` is also provided as a separate array of names for any action that
847
+ * came from a flow generator as well.
848
+ *
849
+ * In the case where a model has two actions: `doSomething` and `doSomethingWithFlow`, where
850
+ * `doSomethingWithFlow` is a flow generator, the `actions` array will contain both actions,
851
+ * i.e. ["doSomething", "doSomethingWithFlow"], and the `flowActions` array will contain only
852
+ * the flow action, i.e. ["doSomethingWithFlow"].
846
853
  *
847
854
  * @param target
848
855
  * @returns
849
856
  */
850
857
  function getMembers(target) {
851
858
  var type = getStateTreeNode(target).type;
852
- var reflected = __assign(__assign({}, getPropertyMembers(type)), { actions: [], volatile: [], views: [] });
859
+ var reflected = __assign(__assign({}, getPropertyMembers(type)), { actions: [], volatile: [], views: [], flowActions: [] });
853
860
  var props = Object.getOwnPropertyNames(target);
854
861
  props.forEach(function (key) {
855
862
  if (key in reflected.properties)
@@ -864,6 +871,8 @@
864
871
  }
865
872
  if (descriptor.value._isMSTAction === true)
866
873
  reflected.actions.push(key);
874
+ if (descriptor.value._isFlowAction === true)
875
+ reflected.flowActions.push(key);
867
876
  else if (mobx.isObservableProp(target, key))
868
877
  reflected.volatile.push(key);
869
878
  else
@@ -1590,9 +1599,10 @@
1590
1599
  enumerable: false,
1591
1600
  configurable: true,
1592
1601
  writable: true,
1593
- value: function () {
1602
+ value: function (fireHooks) {
1603
+ if (fireHooks === void 0) { fireHooks = true; }
1594
1604
  if (this._observableInstanceState === 0 /* UNINITIALIZED */) {
1595
- this.createObservableInstance();
1605
+ this.createObservableInstance(fireHooks);
1596
1606
  }
1597
1607
  }
1598
1608
  });
@@ -1600,8 +1610,9 @@
1600
1610
  enumerable: false,
1601
1611
  configurable: true,
1602
1612
  writable: true,
1603
- value: function () {
1604
- var e_1, _a;
1613
+ value: function (fireHooks) {
1614
+ var e_1, _a, e_2, _b;
1615
+ if (fireHooks === void 0) { fireHooks = true; }
1605
1616
  {
1606
1617
  if (this.state !== NodeLifeCycle.INITIALIZING) {
1607
1618
  // istanbul ignore next
@@ -1626,7 +1637,8 @@
1626
1637
  // initialize the uninitialized parent chain from parent to child
1627
1638
  for (var parentChain_1 = __values(parentChain), parentChain_1_1 = parentChain_1.next(); !parentChain_1_1.done; parentChain_1_1 = parentChain_1.next()) {
1628
1639
  var p = parentChain_1_1.value;
1629
- p.createObservableInstanceIfNeeded();
1640
+ // delay firing hooks until after all parents have been created
1641
+ p.createObservableInstanceIfNeeded(false);
1630
1642
  }
1631
1643
  }
1632
1644
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
@@ -1657,8 +1669,28 @@
1657
1669
  this._addSnapshotReaction();
1658
1670
  this._childNodes = EMPTY_OBJECT;
1659
1671
  this.state = NodeLifeCycle.CREATED;
1660
- this.fireHook(Hook.afterCreate);
1661
- this.finalizeCreation();
1672
+ if (fireHooks) {
1673
+ this.fireHook(Hook.afterCreate);
1674
+ // Note that the parent might not be finalized at this point
1675
+ // so afterAttach won't be called until later in that case
1676
+ this.finalizeCreation();
1677
+ try {
1678
+ // fire the hooks of the parents that we created
1679
+ for (var _c = __values(parentChain.reverse()), _d = _c.next(); !_d.done; _d = _c.next()) {
1680
+ var p = _d.value;
1681
+ p.fireHook(Hook.afterCreate);
1682
+ // This will call afterAttach on the child if necessary
1683
+ p.finalizeCreation();
1684
+ }
1685
+ }
1686
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
1687
+ finally {
1688
+ try {
1689
+ if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
1690
+ }
1691
+ finally { if (e_2) throw e_2.error; }
1692
+ }
1693
+ }
1662
1694
  }
1663
1695
  });
1664
1696
  Object.defineProperty(ObjectNode.prototype, "root", {
@@ -1957,19 +1989,19 @@
1957
1989
  value: function () {
1958
1990
  var _this = this;
1959
1991
  this.baseFinalizeCreation(function () {
1960
- var e_2, _a;
1992
+ var e_3, _a;
1961
1993
  try {
1962
1994
  for (var _b = __values(_this.getChildren()), _c = _b.next(); !_c.done; _c = _b.next()) {
1963
1995
  var child = _c.value;
1964
1996
  child.finalizeCreation();
1965
1997
  }
1966
1998
  }
1967
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
1999
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
1968
2000
  finally {
1969
2001
  try {
1970
2002
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1971
2003
  }
1972
- finally { if (e_2) throw e_2.error; }
2004
+ finally { if (e_3) throw e_3.error; }
1973
2005
  }
1974
2006
  _this.fireInternalHook(Hook.afterCreationFinalization);
1975
2007
  });
@@ -2293,6 +2325,9 @@
2293
2325
  TypeFlags[TypeFlags["Integer"] = 131072] = "Integer";
2294
2326
  TypeFlags[TypeFlags["Custom"] = 262144] = "Custom";
2295
2327
  TypeFlags[TypeFlags["SnapshotProcessor"] = 524288] = "SnapshotProcessor";
2328
+ TypeFlags[TypeFlags["Lazy"] = 1048576] = "Lazy";
2329
+ TypeFlags[TypeFlags["Finite"] = 2097152] = "Finite";
2330
+ TypeFlags[TypeFlags["Float"] = 4194304] = "Float";
2296
2331
  })(TypeFlags || (TypeFlags = {}));
2297
2332
  /**
2298
2333
  * @internal
@@ -3141,6 +3176,7 @@
3141
3176
  }, fn);
3142
3177
  };
3143
3178
  res._isMSTAction = true;
3179
+ res._isFlowAction = fn._isFlowAction;
3144
3180
  return res;
3145
3181
  }
3146
3182
  /**
@@ -3556,17 +3592,25 @@
3556
3592
  enumerable: false,
3557
3593
  configurable: true,
3558
3594
  writable: true,
3559
- value: function (node) {
3595
+ value: function (splitNode) {
3560
3596
  var _this = this;
3561
- var res = new IdentifierCache();
3562
- var basePath = node.path;
3597
+ var newCache = new IdentifierCache();
3598
+ // The slash is added here so we only match children of the splitNode. In version 5.1.8 and
3599
+ // earlier there was no trailing slash, so non children that started with the same path string
3600
+ // were being matched incorrectly.
3601
+ var basePath = splitNode.path + "/";
3563
3602
  mobx.entries(this.cache).forEach(function (_a) {
3564
3603
  var _b = __read(_a, 2), id = _b[0], nodes = _b[1];
3565
3604
  var modified = false;
3566
3605
  for (var i = nodes.length - 1; i >= 0; i--) {
3567
- if (nodes[i].path.indexOf(basePath) === 0) {
3568
- res.addNodeToCache(nodes[i], false); // no need to update lastUpdated since it is a whole new cache
3606
+ var node = nodes[i];
3607
+ if (node === splitNode || node.path.indexOf(basePath) === 0) {
3608
+ newCache.addNodeToCache(node, false); // no need to update lastUpdated since it is a whole new cache
3569
3609
  nodes.splice(i, 1);
3610
+ // remove empty sets from cache
3611
+ if (!nodes.length) {
3612
+ _this.cache.delete(id);
3613
+ }
3570
3614
  modified = true;
3571
3615
  }
3572
3616
  }
@@ -3574,7 +3618,7 @@
3574
3618
  _this.updateLastCacheModificationPerId(id);
3575
3619
  }
3576
3620
  });
3577
- return res;
3621
+ return newCache;
3578
3622
  }
3579
3623
  });
3580
3624
  Object.defineProperty(IdentifierCache.prototype, "has", {
@@ -3858,15 +3902,24 @@
3858
3902
  return _;
3859
3903
  }
3860
3904
  /**
3861
- * pollyfill (for IE) suggested in MDN:
3862
- * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
3863
3905
  * @internal
3864
3906
  * @hidden
3865
3907
  */
3866
- var isInteger = Number.isInteger ||
3867
- function (value) {
3868
- return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
3869
- };
3908
+ var isInteger = Number.isInteger;
3909
+ /**
3910
+ * @internal
3911
+ * @hidden
3912
+ */
3913
+ function isFloat(val) {
3914
+ return Number(val) === val && val % 1 !== 0;
3915
+ }
3916
+ /**
3917
+ * @internal
3918
+ * @hidden
3919
+ */
3920
+ function isFinite(val) {
3921
+ return Number.isFinite(val);
3922
+ }
3870
3923
  /**
3871
3924
  * @internal
3872
3925
  * @hidden
@@ -4388,7 +4441,7 @@
4388
4441
  var args = arguments;
4389
4442
  function wrap(fn, type, arg) {
4390
4443
  fn.$mst_middleware = spawner.$mst_middleware; // pick up any middleware attached to the flow
4391
- runWithActionContext(__assign(__assign({}, contextBase), { type: type, args: [arg] }), fn);
4444
+ return runWithActionContext(__assign(__assign({}, contextBase), { type: type, args: [arg] }), fn);
4392
4445
  }
4393
4446
  return new Promise(function (resolve, reject) {
4394
4447
  var gen;
@@ -4402,7 +4455,10 @@
4402
4455
  var ret;
4403
4456
  try {
4404
4457
  // prettier-ignore
4405
- wrap(function (r) { ret = gen.next(r); }, "flow_resume", res);
4458
+ var cancelError = wrap(function (r) { ret = gen.next(r); }, "flow_resume", res);
4459
+ if (cancelError instanceof Error) {
4460
+ ret = gen.throw(cancelError);
4461
+ }
4406
4462
  }
4407
4463
  catch (e) {
4408
4464
  // prettier-ignore
@@ -4446,6 +4502,7 @@
4446
4502
  }
4447
4503
  });
4448
4504
  };
4505
+ spawner._isFlowAction = true;
4449
4506
  return spawner;
4450
4507
  }
4451
4508
 
@@ -4859,8 +4916,8 @@
4859
4916
  })(MapIdentifierMode || (MapIdentifierMode = {}));
4860
4917
  var MSTMap = /** @class */ (function (_super) {
4861
4918
  __extends(MSTMap, _super);
4862
- function MSTMap(initialData) {
4863
- return _super.call(this, initialData, mobx.observable.ref.enhancer) || this;
4919
+ function MSTMap(initialData, name) {
4920
+ return _super.call(this, initialData, mobx.observable.ref.enhancer, name) || this;
4864
4921
  }
4865
4922
  Object.defineProperty(MSTMap.prototype, "get", {
4866
4923
  enumerable: false,
@@ -5048,7 +5105,7 @@
5048
5105
  configurable: true,
5049
5106
  writable: true,
5050
5107
  value: function (childNodes) {
5051
- return new MSTMap(childNodes);
5108
+ return new MSTMap(childNodes, this.describe());
5052
5109
  }
5053
5110
  });
5054
5111
  Object.defineProperty(MapType.prototype, "finalizeNewInstance", {
@@ -5390,7 +5447,8 @@
5390
5447
  configurable: true,
5391
5448
  writable: true,
5392
5449
  value: function (childNodes) {
5393
- return mobx.observable.array(convertChildNodesToArray(childNodes), mobxShallow);
5450
+ var options = __assign(__assign({}, mobxShallow), { name: this.describe() });
5451
+ return mobx.observable.array(convertChildNodesToArray(childNodes), options);
5394
5452
  }
5395
5453
  });
5396
5454
  Object.defineProperty(ArrayType.prototype, "finalizeNewInstance", {
@@ -5994,6 +6052,7 @@
5994
6052
  // while still allowing the middlewares to register them
5995
6053
  var middlewares = action2.$mst_middleware; // make sure middlewares are not lost
5996
6054
  var boundAction = action2.bind(actions);
6055
+ boundAction._isFlowAction = action2._isFlowAction || false;
5997
6056
  boundAction.$mst_middleware = middlewares;
5998
6057
  var actionInvoker = createActionInvoker(self, name, boundAction);
5999
6058
  actions[name] = actionInvoker;
@@ -6119,7 +6178,8 @@
6119
6178
  configurable: true,
6120
6179
  writable: true,
6121
6180
  value: function (childNodes) {
6122
- return mobx.observable.object(childNodes, EMPTY_OBJECT, mobxShallow);
6181
+ var options = __assign(__assign({}, mobxShallow), { name: this.describe() });
6182
+ return mobx.observable.object(childNodes, EMPTY_OBJECT, options);
6123
6183
  }
6124
6184
  });
6125
6185
  Object.defineProperty(ModelType.prototype, "finalizeNewInstance", {
@@ -6250,8 +6310,8 @@
6250
6310
  configurable: true,
6251
6311
  writable: true,
6252
6312
  value: function (node, snapshot) {
6313
+ typecheckInternal(this, snapshot);
6253
6314
  var preProcessedSnapshot = this.applySnapshotPreProcessor(snapshot);
6254
- typecheckInternal(this, preProcessedSnapshot);
6255
6315
  this.forAllProps(function (name) {
6256
6316
  node.storedValue[name] = preProcessedSnapshot[name];
6257
6317
  });
@@ -6353,6 +6413,9 @@
6353
6413
  for (var _i = 0; _i < arguments.length; _i++) {
6354
6414
  args[_i] = arguments[_i];
6355
6415
  }
6416
+ if (typeof args[0] !== "string" && args[1]) {
6417
+ throw fail$1("Model creation failed. First argument must be a string when two arguments are provided");
6418
+ }
6356
6419
  var name = typeof args[0] === "string" ? args.shift() : "AnonymousModel";
6357
6420
  var properties = args.shift() || {};
6358
6421
  return new ModelType({ name: name, properties: properties });
@@ -6506,7 +6569,6 @@
6506
6569
  var number = new CoreType("number", TypeFlags.Number, function (v) { return typeof v === "number"; });
6507
6570
  /**
6508
6571
  * `types.integer` - Creates a type that can only contain an integer value.
6509
- * This type is used for integer values by default
6510
6572
  *
6511
6573
  * Example:
6512
6574
  * ```ts
@@ -6518,6 +6580,32 @@
6518
6580
  */
6519
6581
  // tslint:disable-next-line:variable-name
6520
6582
  var integer = new CoreType("integer", TypeFlags.Integer, function (v) { return isInteger(v); });
6583
+ /**
6584
+ * `types.float` - Creates a type that can only contain an float value.
6585
+ *
6586
+ * Example:
6587
+ * ```ts
6588
+ * const Size = types.model({
6589
+ * width: types.float,
6590
+ * height: 10
6591
+ * })
6592
+ * ```
6593
+ */
6594
+ // tslint:disable-next-line:variable-name
6595
+ var float = new CoreType("float", TypeFlags.Float, function (v) { return isFloat(v); });
6596
+ /**
6597
+ * `types.finite` - Creates a type that can only contain an finite value.
6598
+ *
6599
+ * Example:
6600
+ * ```ts
6601
+ * const Size = types.model({
6602
+ * width: types.finite,
6603
+ * height: 10
6604
+ * })
6605
+ * ```
6606
+ */
6607
+ // tslint:disable-next-line:variable-name
6608
+ var finite = new CoreType("finite", TypeFlags.Finite, function (v) { return isFinite(v); });
6521
6609
  /**
6522
6610
  * `types.boolean` - Creates a type that can only contain a boolean value.
6523
6611
  * This type is used for boolean values by default
@@ -7057,7 +7145,7 @@
7057
7145
  writable: true,
7058
7146
  value: function (parent, subpath, environment, initialValue) {
7059
7147
  if (this.optionalValues.indexOf(initialValue) >= 0) {
7060
- var defaultInstanceOrSnapshot = this.getDefaultInstanceOrSnapshot();
7148
+ var defaultInstanceOrSnapshot = this.getDefaultInstanceOrSnapshot(parent);
7061
7149
  return this._subtype.instantiate(parent, subpath, environment, defaultInstanceOrSnapshot);
7062
7150
  }
7063
7151
  return this._subtype.instantiate(parent, subpath, environment, initialValue);
@@ -7070,16 +7158,16 @@
7070
7158
  value: function (current, newValue, parent, subpath) {
7071
7159
  return this._subtype.reconcile(current, this.optionalValues.indexOf(newValue) < 0 && this._subtype.is(newValue)
7072
7160
  ? newValue
7073
- : this.getDefaultInstanceOrSnapshot(), parent, subpath);
7161
+ : this.getDefaultInstanceOrSnapshot(parent), parent, subpath);
7074
7162
  }
7075
7163
  });
7076
7164
  Object.defineProperty(OptionalValue.prototype, "getDefaultInstanceOrSnapshot", {
7077
7165
  enumerable: false,
7078
7166
  configurable: true,
7079
7167
  writable: true,
7080
- value: function () {
7168
+ value: function (parent) {
7081
7169
  var defaultInstanceOrSnapshot = typeof this._defaultValue === "function"
7082
- ? this._defaultValue()
7170
+ ? this._defaultValue(parent)
7083
7171
  : this._defaultValue;
7084
7172
  // while static values are already snapshots and checked on types.optional
7085
7173
  // generator functions must always be rechecked just in case
@@ -7367,6 +7455,120 @@
7367
7455
  return isType(type) && (type.flags & TypeFlags.Late) > 0;
7368
7456
  }
7369
7457
 
7458
+ function lazy(name, options) {
7459
+ // TODO: fix this unknown casting to be stricter
7460
+ return new Lazy(name, options);
7461
+ }
7462
+ /**
7463
+ * @internal
7464
+ * @hidden
7465
+ */
7466
+ var Lazy = /** @class */ (function (_super) {
7467
+ __extends(Lazy, _super);
7468
+ function Lazy(name, options) {
7469
+ var _this = _super.call(this, name) || this;
7470
+ Object.defineProperty(_this, "options", {
7471
+ enumerable: true,
7472
+ configurable: true,
7473
+ writable: true,
7474
+ value: options
7475
+ });
7476
+ Object.defineProperty(_this, "flags", {
7477
+ enumerable: true,
7478
+ configurable: true,
7479
+ writable: true,
7480
+ value: TypeFlags.Lazy
7481
+ });
7482
+ Object.defineProperty(_this, "loadedType", {
7483
+ enumerable: true,
7484
+ configurable: true,
7485
+ writable: true,
7486
+ value: null
7487
+ });
7488
+ Object.defineProperty(_this, "pendingNodeList", {
7489
+ enumerable: true,
7490
+ configurable: true,
7491
+ writable: true,
7492
+ value: mobx.observable.array()
7493
+ });
7494
+ mobx.when(function () {
7495
+ return _this.pendingNodeList.length > 0 &&
7496
+ _this.pendingNodeList.some(function (node) {
7497
+ return node.isAlive &&
7498
+ _this.options.shouldLoadPredicate(node.parent ? node.parent.value : null);
7499
+ });
7500
+ }, function () {
7501
+ _this.options.loadType().then(mobx.action(function (type) {
7502
+ _this.loadedType = type;
7503
+ _this.pendingNodeList.forEach(function (node) {
7504
+ if (!node.parent)
7505
+ return;
7506
+ if (!_this.loadedType)
7507
+ return;
7508
+ node.parent.applyPatches([
7509
+ {
7510
+ op: "replace",
7511
+ path: "/" + node.subpath,
7512
+ value: node.snapshot
7513
+ }
7514
+ ]);
7515
+ });
7516
+ }));
7517
+ });
7518
+ return _this;
7519
+ }
7520
+ Object.defineProperty(Lazy.prototype, "describe", {
7521
+ enumerable: false,
7522
+ configurable: true,
7523
+ writable: true,
7524
+ value: function () {
7525
+ return "<lazy " + this.name + ">";
7526
+ }
7527
+ });
7528
+ Object.defineProperty(Lazy.prototype, "instantiate", {
7529
+ enumerable: false,
7530
+ configurable: true,
7531
+ writable: true,
7532
+ value: function (parent, subpath, environment, value) {
7533
+ var _this = this;
7534
+ if (this.loadedType) {
7535
+ return this.loadedType.instantiate(parent, subpath, environment, value);
7536
+ }
7537
+ var node = createScalarNode(this, parent, subpath, environment, deepFreeze(value));
7538
+ this.pendingNodeList.push(node);
7539
+ mobx.when(function () { return !node.isAlive; }, function () { return _this.pendingNodeList.splice(_this.pendingNodeList.indexOf(node), 1); });
7540
+ return node;
7541
+ }
7542
+ });
7543
+ Object.defineProperty(Lazy.prototype, "isValidSnapshot", {
7544
+ enumerable: false,
7545
+ configurable: true,
7546
+ writable: true,
7547
+ value: function (value, context) {
7548
+ if (this.loadedType) {
7549
+ return this.loadedType.validate(value, context);
7550
+ }
7551
+ if (!isSerializable(value)) {
7552
+ return typeCheckFailure(context, value, "Value is not serializable and cannot be lazy");
7553
+ }
7554
+ return typeCheckSuccess();
7555
+ }
7556
+ });
7557
+ Object.defineProperty(Lazy.prototype, "reconcile", {
7558
+ enumerable: false,
7559
+ configurable: true,
7560
+ writable: true,
7561
+ value: function (current, value, parent, subpath) {
7562
+ if (this.loadedType) {
7563
+ current.die();
7564
+ return this.loadedType.instantiate(parent, subpath, parent.environment, value);
7565
+ }
7566
+ return _super.prototype.reconcile.call(this, current, value, parent, subpath);
7567
+ }
7568
+ });
7569
+ return Lazy;
7570
+ }(SimpleType));
7571
+
7370
7572
  /**
7371
7573
  * @internal
7372
7574
  * @hidden
@@ -8305,6 +8507,8 @@
8305
8507
  boolean: boolean,
8306
8508
  number: number,
8307
8509
  integer: integer,
8510
+ float: float,
8511
+ finite: finite,
8308
8512
  Date: DatePrimitive,
8309
8513
  map: map,
8310
8514
  array: array,
@@ -8312,6 +8516,7 @@
8312
8516
  identifier: identifier,
8313
8517
  identifierNumber: identifierNumber,
8314
8518
  late: late,
8519
+ lazy: lazy,
8315
8520
  undefined: undefinedType,
8316
8521
  null: nullType,
8317
8522
  snapshotProcessor: snapshotProcessor