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.
@@ -6033,6 +6033,7 @@ var ArrayType = /** @class */ (function (_super) {
6033
6033
  configurable: true,
6034
6034
  writable: true,
6035
6035
  value: function (node, snapshot) {
6036
+ var e_1, _a;
6036
6037
  if (!isArray(snapshot)) {
6037
6038
  typecheckInternal(this, snapshot);
6038
6039
  return;
@@ -6061,24 +6062,32 @@ var ArrayType = /** @class */ (function (_super) {
6061
6062
  applyDirectSnapshotsInRange(childNodes, snapshot, firstChangedIndex);
6062
6063
  return;
6063
6064
  }
6064
- var oldEnd = oldLength - 1;
6065
- var newEnd = newLength - 1;
6066
- while (oldEnd >= firstChangedIndex &&
6067
- newEnd >= firstChangedIndex &&
6068
- childNodes[oldEnd].snapshot === snapshot[newEnd]) {
6069
- oldEnd--;
6070
- newEnd--;
6071
- }
6072
- // Trim the unchanged suffix too, so we only replace the minimal changed window.
6073
- var replacedCount = oldEnd >= firstChangedIndex ? oldEnd - firstChangedIndex + 1 : 0;
6074
- var replacementSnapshots = newEnd >= firstChangedIndex
6075
- ? snapshot.slice(firstChangedIndex, newEnd + 1)
6076
- : EMPTY_ARRAY;
6077
- if (replacedCount === 1 && replacementSnapshots.length === 1) {
6078
- target[firstChangedIndex] = replacementSnapshots[0];
6079
- return;
6065
+ // The lengths match, so only the differing entries have to change. Collect them
6066
+ // before touching the array, because assigning to one entry invalidates the
6067
+ // snapshots of the others and their identity can no longer be compared.
6068
+ var changedIndexes = [];
6069
+ for (var i = firstChangedIndex; i < oldLength; i++) {
6070
+ if (childNodes[i].snapshot !== snapshot[i]) {
6071
+ changedIndexes.push(i);
6072
+ }
6073
+ }
6074
+ try {
6075
+ // Assign the changed entries individually rather than splicing across the
6076
+ // untouched entries between them: a single assignment reconciles exactly one
6077
+ // child, which keeps the cost proportional to the number of changes instead of
6078
+ // the distance between the first and the last of them.
6079
+ for (var changedIndexes_1 = __values(changedIndexes), changedIndexes_1_1 = changedIndexes_1.next(); !changedIndexes_1_1.done; changedIndexes_1_1 = changedIndexes_1.next()) {
6080
+ var index = changedIndexes_1_1.value;
6081
+ target[index] = snapshot[index];
6082
+ }
6083
+ }
6084
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
6085
+ finally {
6086
+ try {
6087
+ if (changedIndexes_1_1 && !changedIndexes_1_1.done && (_a = changedIndexes_1.return)) _a.call(changedIndexes_1);
6088
+ }
6089
+ finally { if (e_1) throw e_1.error; }
6080
6090
  }
6081
- target.splice.apply(target, __spreadArray([firstChangedIndex, replacedCount], __read(replacementSnapshots), false));
6082
6091
  }
6083
6092
  });
6084
6093
  Object.defineProperty(ArrayType.prototype, "getChildType", {
@@ -6159,9 +6168,17 @@ function findFirstChangedIndex(childNodes, snapshot, length) {
6159
6168
  }
6160
6169
  function canApplyDirectSnapshotsInRange(childType, childNodes, snapshot, startIndex) {
6161
6170
  for (var i = startIndex; i < childNodes.length; i++) {
6162
- if (childNodes[i].snapshot === snapshot[i])
6171
+ var childNode = childNodes[i];
6172
+ if (childNode.snapshot === snapshot[i])
6163
6173
  continue;
6164
- if (!canApplyDirectSnapshot(childType, childNodes[i], snapshot[i])) {
6174
+ if (!canApplyDirectSnapshot(childType, childNode, snapshot[i])) {
6175
+ return false;
6176
+ }
6177
+ // Array reconciliation only treats two snapshots as the same child when they carry
6178
+ // a matching identifier (see `areSame`). Identifier-less children are replaced
6179
+ // rather than updated in place, so they must not take the direct-apply path or
6180
+ // lifecycle hooks such as afterCreate would never run for the new child.
6181
+ if (!childNode.identifierAttribute || childNode.identifier === null) {
6165
6182
  return false;
6166
6183
  }
6167
6184
  }
@@ -7446,13 +7463,14 @@ function isRefinementType(type) {
7446
7463
  }
7447
7464
 
7448
7465
  /**
7449
- * `types.enumeration` - Can be used to create an string based enumeration.
7450
- * (note: this methods is just sugar for a union of string literals)
7466
+ * `types.enumeration` - Can be used to create a string or number based enumeration.
7467
+ * (note: this methods is just sugar for a union of string or number literals)
7451
7468
  *
7452
7469
  * Example:
7453
7470
  * ```ts
7454
7471
  * const TrafficLight = types.model({
7455
- * color: types.enumeration("Color", ["Red", "Orange", "Green"])
7472
+ * color: types.enumeration("Color", ["Red", "Orange", "Green"]),
7473
+ * speedLimit: types.enumeration("SpeedLimit", [30, 50])
7456
7474
  * })
7457
7475
  * ```
7458
7476
  *
@@ -7465,10 +7483,10 @@ function enumeration(name, options) {
7465
7483
  // check all options
7466
7484
  if (devMode()) {
7467
7485
  realOptions.forEach(function (option, i) {
7468
- assertIsString(option, i + 1);
7486
+ assertArg(option, function (o) { return typeof o === "string" || typeof o === "number"; }, "string or number", i + 1);
7469
7487
  });
7470
7488
  }
7471
- var type = union.apply(void 0, __spreadArray([], __read(realOptions.map(function (option) { return literal("" + option); })), false));
7489
+ var type = union.apply(void 0, __spreadArray([], __read(realOptions.map(function (option) { return literal(option); })), false));
7472
7490
  if (typeof name === "string")
7473
7491
  type.name = name;
7474
7492
  return type;