mobx-state-tree 7.3.1 → 7.4.0

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.
@@ -6029,6 +6029,7 @@ var ArrayType = /** @class */ (function (_super) {
6029
6029
  configurable: true,
6030
6030
  writable: true,
6031
6031
  value: function (node, snapshot) {
6032
+ var e_1, _a;
6032
6033
  if (!isArray(snapshot)) {
6033
6034
  typecheckInternal(this, snapshot);
6034
6035
  return;
@@ -6057,24 +6058,32 @@ var ArrayType = /** @class */ (function (_super) {
6057
6058
  applyDirectSnapshotsInRange(childNodes, snapshot, firstChangedIndex);
6058
6059
  return;
6059
6060
  }
6060
- var oldEnd = oldLength - 1;
6061
- var newEnd = newLength - 1;
6062
- while (oldEnd >= firstChangedIndex &&
6063
- newEnd >= firstChangedIndex &&
6064
- childNodes[oldEnd].snapshot === snapshot[newEnd]) {
6065
- oldEnd--;
6066
- newEnd--;
6067
- }
6068
- // Trim the unchanged suffix too, so we only replace the minimal changed window.
6069
- var replacedCount = oldEnd >= firstChangedIndex ? oldEnd - firstChangedIndex + 1 : 0;
6070
- var replacementSnapshots = newEnd >= firstChangedIndex
6071
- ? snapshot.slice(firstChangedIndex, newEnd + 1)
6072
- : EMPTY_ARRAY;
6073
- if (replacedCount === 1 && replacementSnapshots.length === 1) {
6074
- target[firstChangedIndex] = replacementSnapshots[0];
6075
- return;
6061
+ // The lengths match, so only the differing entries have to change. Collect them
6062
+ // before touching the array, because assigning to one entry invalidates the
6063
+ // snapshots of the others and their identity can no longer be compared.
6064
+ var changedIndexes = [];
6065
+ for (var i = firstChangedIndex; i < oldLength; i++) {
6066
+ if (childNodes[i].snapshot !== snapshot[i]) {
6067
+ changedIndexes.push(i);
6068
+ }
6069
+ }
6070
+ try {
6071
+ // Assign the changed entries individually rather than splicing across the
6072
+ // untouched entries between them: a single assignment reconciles exactly one
6073
+ // child, which keeps the cost proportional to the number of changes instead of
6074
+ // the distance between the first and the last of them.
6075
+ for (var changedIndexes_1 = __values(changedIndexes), changedIndexes_1_1 = changedIndexes_1.next(); !changedIndexes_1_1.done; changedIndexes_1_1 = changedIndexes_1.next()) {
6076
+ var index = changedIndexes_1_1.value;
6077
+ target[index] = snapshot[index];
6078
+ }
6079
+ }
6080
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
6081
+ finally {
6082
+ try {
6083
+ if (changedIndexes_1_1 && !changedIndexes_1_1.done && (_a = changedIndexes_1.return)) _a.call(changedIndexes_1);
6084
+ }
6085
+ finally { if (e_1) throw e_1.error; }
6076
6086
  }
6077
- target.splice.apply(target, __spreadArray([firstChangedIndex, replacedCount], __read(replacementSnapshots), false));
6078
6087
  }
6079
6088
  });
6080
6089
  Object.defineProperty(ArrayType.prototype, "getChildType", {
@@ -6155,9 +6164,17 @@ function findFirstChangedIndex(childNodes, snapshot, length) {
6155
6164
  }
6156
6165
  function canApplyDirectSnapshotsInRange(childType, childNodes, snapshot, startIndex) {
6157
6166
  for (var i = startIndex; i < childNodes.length; i++) {
6158
- if (childNodes[i].snapshot === snapshot[i])
6167
+ var childNode = childNodes[i];
6168
+ if (childNode.snapshot === snapshot[i])
6159
6169
  continue;
6160
- if (!canApplyDirectSnapshot(childType, childNodes[i], snapshot[i])) {
6170
+ if (!canApplyDirectSnapshot(childType, childNode, snapshot[i])) {
6171
+ return false;
6172
+ }
6173
+ // Array reconciliation only treats two snapshots as the same child when they carry
6174
+ // a matching identifier (see `areSame`). Identifier-less children are replaced
6175
+ // rather than updated in place, so they must not take the direct-apply path or
6176
+ // lifecycle hooks such as afterCreate would never run for the new child.
6177
+ if (!childNode.identifierAttribute || childNode.identifier === null) {
6161
6178
  return false;
6162
6179
  }
6163
6180
  }
@@ -7442,13 +7459,14 @@ function isRefinementType(type) {
7442
7459
  }
7443
7460
 
7444
7461
  /**
7445
- * `types.enumeration` - Can be used to create an string based enumeration.
7446
- * (note: this methods is just sugar for a union of string literals)
7462
+ * `types.enumeration` - Can be used to create a string or number based enumeration.
7463
+ * (note: this methods is just sugar for a union of string or number literals)
7447
7464
  *
7448
7465
  * Example:
7449
7466
  * ```ts
7450
7467
  * const TrafficLight = types.model({
7451
- * color: types.enumeration("Color", ["Red", "Orange", "Green"])
7468
+ * color: types.enumeration("Color", ["Red", "Orange", "Green"]),
7469
+ * speedLimit: types.enumeration("SpeedLimit", [30, 50])
7452
7470
  * })
7453
7471
  * ```
7454
7472
  *
@@ -7461,10 +7479,10 @@ function enumeration(name, options) {
7461
7479
  // check all options
7462
7480
  if (devMode()) {
7463
7481
  realOptions.forEach(function (option, i) {
7464
- assertIsString(option, i + 1);
7482
+ assertArg(option, function (o) { return typeof o === "string" || typeof o === "number"; }, "string or number", i + 1);
7465
7483
  });
7466
7484
  }
7467
- var type = union.apply(void 0, __spreadArray([], __read(realOptions.map(function (option) { return literal("" + option); })), false));
7485
+ var type = union.apply(void 0, __spreadArray([], __read(realOptions.map(function (option) { return literal(option); })), false));
7468
7486
  if (typeof name === "string")
7469
7487
  type.name = name;
7470
7488
  return type;
@@ -6011,6 +6011,7 @@
6011
6011
  configurable: true,
6012
6012
  writable: true,
6013
6013
  value: function (node, snapshot) {
6014
+ var e_1, _a;
6014
6015
  if (!isArray(snapshot)) {
6015
6016
  typecheckInternal(this, snapshot);
6016
6017
  return;
@@ -6039,24 +6040,32 @@
6039
6040
  applyDirectSnapshotsInRange(childNodes, snapshot, firstChangedIndex);
6040
6041
  return;
6041
6042
  }
6042
- var oldEnd = oldLength - 1;
6043
- var newEnd = newLength - 1;
6044
- while (oldEnd >= firstChangedIndex &&
6045
- newEnd >= firstChangedIndex &&
6046
- childNodes[oldEnd].snapshot === snapshot[newEnd]) {
6047
- oldEnd--;
6048
- newEnd--;
6049
- }
6050
- // Trim the unchanged suffix too, so we only replace the minimal changed window.
6051
- var replacedCount = oldEnd >= firstChangedIndex ? oldEnd - firstChangedIndex + 1 : 0;
6052
- var replacementSnapshots = newEnd >= firstChangedIndex
6053
- ? snapshot.slice(firstChangedIndex, newEnd + 1)
6054
- : EMPTY_ARRAY;
6055
- if (replacedCount === 1 && replacementSnapshots.length === 1) {
6056
- target[firstChangedIndex] = replacementSnapshots[0];
6057
- return;
6043
+ // The lengths match, so only the differing entries have to change. Collect them
6044
+ // before touching the array, because assigning to one entry invalidates the
6045
+ // snapshots of the others and their identity can no longer be compared.
6046
+ var changedIndexes = [];
6047
+ for (var i = firstChangedIndex; i < oldLength; i++) {
6048
+ if (childNodes[i].snapshot !== snapshot[i]) {
6049
+ changedIndexes.push(i);
6050
+ }
6051
+ }
6052
+ try {
6053
+ // Assign the changed entries individually rather than splicing across the
6054
+ // untouched entries between them: a single assignment reconciles exactly one
6055
+ // child, which keeps the cost proportional to the number of changes instead of
6056
+ // the distance between the first and the last of them.
6057
+ for (var changedIndexes_1 = __values(changedIndexes), changedIndexes_1_1 = changedIndexes_1.next(); !changedIndexes_1_1.done; changedIndexes_1_1 = changedIndexes_1.next()) {
6058
+ var index = changedIndexes_1_1.value;
6059
+ target[index] = snapshot[index];
6060
+ }
6061
+ }
6062
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
6063
+ finally {
6064
+ try {
6065
+ if (changedIndexes_1_1 && !changedIndexes_1_1.done && (_a = changedIndexes_1.return)) _a.call(changedIndexes_1);
6066
+ }
6067
+ finally { if (e_1) throw e_1.error; }
6058
6068
  }
6059
- target.splice.apply(target, __spreadArray([firstChangedIndex, replacedCount], __read(replacementSnapshots), false));
6060
6069
  }
6061
6070
  });
6062
6071
  Object.defineProperty(ArrayType.prototype, "getChildType", {
@@ -6137,9 +6146,17 @@
6137
6146
  }
6138
6147
  function canApplyDirectSnapshotsInRange(childType, childNodes, snapshot, startIndex) {
6139
6148
  for (var i = startIndex; i < childNodes.length; i++) {
6140
- if (childNodes[i].snapshot === snapshot[i])
6149
+ var childNode = childNodes[i];
6150
+ if (childNode.snapshot === snapshot[i])
6141
6151
  continue;
6142
- if (!canApplyDirectSnapshot(childType, childNodes[i], snapshot[i])) {
6152
+ if (!canApplyDirectSnapshot(childType, childNode, snapshot[i])) {
6153
+ return false;
6154
+ }
6155
+ // Array reconciliation only treats two snapshots as the same child when they carry
6156
+ // a matching identifier (see `areSame`). Identifier-less children are replaced
6157
+ // rather than updated in place, so they must not take the direct-apply path or
6158
+ // lifecycle hooks such as afterCreate would never run for the new child.
6159
+ if (!childNode.identifierAttribute || childNode.identifier === null) {
6143
6160
  return false;
6144
6161
  }
6145
6162
  }
@@ -7424,13 +7441,14 @@
7424
7441
  }
7425
7442
 
7426
7443
  /**
7427
- * `types.enumeration` - Can be used to create an string based enumeration.
7428
- * (note: this methods is just sugar for a union of string literals)
7444
+ * `types.enumeration` - Can be used to create a string or number based enumeration.
7445
+ * (note: this methods is just sugar for a union of string or number literals)
7429
7446
  *
7430
7447
  * Example:
7431
7448
  * ```ts
7432
7449
  * const TrafficLight = types.model({
7433
- * color: types.enumeration("Color", ["Red", "Orange", "Green"])
7450
+ * color: types.enumeration("Color", ["Red", "Orange", "Green"]),
7451
+ * speedLimit: types.enumeration("SpeedLimit", [30, 50])
7434
7452
  * })
7435
7453
  * ```
7436
7454
  *
@@ -7443,10 +7461,10 @@
7443
7461
  // check all options
7444
7462
  {
7445
7463
  realOptions.forEach(function (option, i) {
7446
- assertIsString(option, i + 1);
7464
+ assertArg(option, function (o) { return typeof o === "string" || typeof o === "number"; }, "string or number", i + 1);
7447
7465
  });
7448
7466
  }
7449
- var type = union.apply(void 0, __spreadArray([], __read(realOptions.map(function (option) { return literal("" + option); })), false));
7467
+ var type = union.apply(void 0, __spreadArray([], __read(realOptions.map(function (option) { return literal(option); })), false));
7450
7468
  if (typeof name === "string")
7451
7469
  type.name = name;
7452
7470
  return type;