mobx-state-tree 7.0.2 → 7.1.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.
- package/dist/core/mst-operations.d.ts +1 -1
- package/dist/core/type/type.d.ts +3 -1
- package/dist/mobx-state-tree.js +195 -20
- package/dist/mobx-state-tree.min.js +1 -1
- package/dist/mobx-state-tree.module.js +195 -20
- package/dist/mobx-state-tree.umd.js +195 -20
- package/dist/mobx-state-tree.umd.min.js +1 -1
- package/dist/types/complex-types/model.d.ts +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/primitives.d.ts +15 -1
- package/dist/types/utility-types/snapshotProcessor.d.ts +2 -0
- package/package.json +2 -2
|
@@ -340,7 +340,7 @@ export declare function isAlive(target: IAnyStateTreeNode): boolean;
|
|
|
340
340
|
export declare function addDisposer(target: IAnyStateTreeNode, disposer: IDisposer): IDisposer;
|
|
341
341
|
/**
|
|
342
342
|
* Returns the environment of the current state tree, or throws. For more info on environments,
|
|
343
|
-
* see [Dependency injection](
|
|
343
|
+
* see [Dependency injection](/concepts/dependency-injection)
|
|
344
344
|
*
|
|
345
345
|
* Please note that in child nodes access to the root is only possible
|
|
346
346
|
* once the `afterAttach` hook has fired
|
package/dist/core/type/type.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IValidationContext, IValidationResult, IStateTreeNode, ModelPrimitive } from "../../internal";
|
|
1
|
+
import { IValidationContext, IValidationResult, IStateTreeNode, ObjectNode, ModelPrimitive, AnyNode } from "../../internal";
|
|
2
2
|
import type { WritableKeys } from "ts-essentials";
|
|
3
3
|
/**
|
|
4
4
|
* A state tree node value.
|
|
@@ -154,6 +154,8 @@ export type SnapshotOut<T> = T extends {
|
|
|
154
154
|
* ```
|
|
155
155
|
*/
|
|
156
156
|
export type SnapshotOrInstance<T> = SnapshotIn<T> | Instance<T>;
|
|
157
|
+
export declare function canApplyDirectSnapshot(childType: IAnyType, childNode: AnyNode, newValue: any): childNode is ObjectNode<any, any, any>;
|
|
158
|
+
export declare function resolveDirectApplyType(type: IAnyType): IAnyType;
|
|
157
159
|
/**
|
|
158
160
|
* Returns if a given value represents a type.
|
|
159
161
|
*
|
package/dist/mobx-state-tree.js
CHANGED
|
@@ -795,7 +795,7 @@ function addDisposer(target, disposer) {
|
|
|
795
795
|
}
|
|
796
796
|
/**
|
|
797
797
|
* Returns the environment of the current state tree, or throws. For more info on environments,
|
|
798
|
-
* see [Dependency injection](
|
|
798
|
+
* see [Dependency injection](/concepts/dependency-injection)
|
|
799
799
|
*
|
|
800
800
|
* Please note that in child nodes access to the root is only possible
|
|
801
801
|
* once the `afterAttach` hook has fired
|
|
@@ -2169,6 +2169,17 @@ var ObjectNode = /** @class */ (function (_super) {
|
|
|
2169
2169
|
return this._internalEventsRegister(InternalEvents.Patch, handler);
|
|
2170
2170
|
}
|
|
2171
2171
|
});
|
|
2172
|
+
Object.defineProperty(ObjectNode.prototype, "hasPatchSubscribers", {
|
|
2173
|
+
enumerable: false,
|
|
2174
|
+
configurable: true,
|
|
2175
|
+
writable: true,
|
|
2176
|
+
value: function () {
|
|
2177
|
+
if (this._internalEventsHasSubscribers(InternalEvents.Patch)) {
|
|
2178
|
+
return true;
|
|
2179
|
+
}
|
|
2180
|
+
return this.parent ? this.parent.hasPatchSubscribers() : false;
|
|
2181
|
+
}
|
|
2182
|
+
});
|
|
2172
2183
|
Object.defineProperty(ObjectNode.prototype, "emitPatch", {
|
|
2173
2184
|
enumerable: false,
|
|
2174
2185
|
configurable: true,
|
|
@@ -2381,6 +2392,7 @@ var TypeFlags;
|
|
|
2381
2392
|
TypeFlags[TypeFlags["Lazy"] = 1048576] = "Lazy";
|
|
2382
2393
|
TypeFlags[TypeFlags["Finite"] = 2097152] = "Finite";
|
|
2383
2394
|
TypeFlags[TypeFlags["Float"] = 4194304] = "Float";
|
|
2395
|
+
TypeFlags[TypeFlags["BigInt"] = 8388608] = "BigInt";
|
|
2384
2396
|
})(TypeFlags || (TypeFlags = {}));
|
|
2385
2397
|
/**
|
|
2386
2398
|
* @internal
|
|
@@ -2697,6 +2709,38 @@ var SimpleType = /** @class */ (function (_super) {
|
|
|
2697
2709
|
});
|
|
2698
2710
|
return SimpleType;
|
|
2699
2711
|
}(BaseType));
|
|
2712
|
+
function canApplyDirectSnapshot(childType, childNode, newValue) {
|
|
2713
|
+
var reconciliationType = childNode.getReconciliationType();
|
|
2714
|
+
var expectedReconciliationType = resolveDirectApplyType(childType);
|
|
2715
|
+
// Only types that reconcile as the same transparent-wrapper-adjusted type can safely reuse
|
|
2716
|
+
// the existing child node. Wrappers with their own validation or snapshot semantics
|
|
2717
|
+
// intentionally keep a distinct reconciliation type so they fall back to the validated path.
|
|
2718
|
+
var hasMatchingReconciliationType = reconciliationType === expectedReconciliationType;
|
|
2719
|
+
return (childNode instanceof ObjectNode &&
|
|
2720
|
+
hasMatchingReconciliationType &&
|
|
2721
|
+
reconciliationType instanceof ComplexType &&
|
|
2722
|
+
isMutable(newValue) &&
|
|
2723
|
+
!isStateTreeNode(newValue) &&
|
|
2724
|
+
reconciliationType.isMatchingSnapshotId(childNode, newValue));
|
|
2725
|
+
}
|
|
2726
|
+
function resolveDirectApplyType(type) {
|
|
2727
|
+
var subTypes = type.getSubTypes();
|
|
2728
|
+
if (!subTypes ||
|
|
2729
|
+
Array.isArray(subTypes) ||
|
|
2730
|
+
subTypes === cannotDetermineSubtype ||
|
|
2731
|
+
!canUnwrapDirectApplyType(type)) {
|
|
2732
|
+
return type;
|
|
2733
|
+
}
|
|
2734
|
+
// Only unwrap wrappers that are transparent for direct apply. Wrappers with their own
|
|
2735
|
+
// validation or snapshot processing must keep their wrapper identity here.
|
|
2736
|
+
return resolveDirectApplyType(subTypes);
|
|
2737
|
+
}
|
|
2738
|
+
function canUnwrapDirectApplyType(type) {
|
|
2739
|
+
var transparentWrapperFlags = TypeFlags.Optional | TypeFlags.Late;
|
|
2740
|
+
var nonTransparentWrapperFlags = TypeFlags.Refinement | TypeFlags.SnapshotProcessor | TypeFlags.Union;
|
|
2741
|
+
return ((type.flags & transparentWrapperFlags) > 0 &&
|
|
2742
|
+
(type.flags & nonTransparentWrapperFlags) === 0);
|
|
2743
|
+
}
|
|
2700
2744
|
/**
|
|
2701
2745
|
* Returns if a given value represents a type.
|
|
2702
2746
|
*
|
|
@@ -4046,6 +4090,7 @@ function isPrimitive(value, includeDate) {
|
|
|
4046
4090
|
typeof value === "string" ||
|
|
4047
4091
|
typeof value === "number" ||
|
|
4048
4092
|
typeof value === "boolean" ||
|
|
4093
|
+
typeof value === "bigint" ||
|
|
4049
4094
|
(includeDate && value instanceof Date));
|
|
4050
4095
|
}
|
|
4051
4096
|
/**
|
|
@@ -4930,6 +4975,8 @@ function proxyNodeTypeMethods(nodeType, snapshotProcessorType) {
|
|
|
4930
4975
|
/**
|
|
4931
4976
|
* `types.snapshotProcessor` - Runs a pre/post snapshot processor before/after serializing a given type.
|
|
4932
4977
|
*
|
|
4978
|
+
* [See known issue with `applySnapshot` and `preProcessSnapshot`](https://github.com/mobxjs/mobx-state-tree/issues/1317)
|
|
4979
|
+
*
|
|
4933
4980
|
* Example:
|
|
4934
4981
|
* ```ts
|
|
4935
4982
|
* const Todo1 = types.model({ text: types.string })
|
|
@@ -5380,23 +5427,33 @@ var MapType = /** @class */ (function (_super) {
|
|
|
5380
5427
|
configurable: true,
|
|
5381
5428
|
writable: true,
|
|
5382
5429
|
value: function (node, snapshot) {
|
|
5383
|
-
|
|
5430
|
+
if (!isPlainObject(snapshot)) {
|
|
5431
|
+
typecheckInternal(this, snapshot);
|
|
5432
|
+
return;
|
|
5433
|
+
}
|
|
5384
5434
|
var target = node.storedValue;
|
|
5385
|
-
var
|
|
5435
|
+
var childType = this.getChildType();
|
|
5386
5436
|
Array.from(target.keys()).forEach(function (key) {
|
|
5387
|
-
|
|
5388
|
-
});
|
|
5389
|
-
if (snapshot) {
|
|
5390
|
-
// Don't use target.replace, as it will throw away all existing items first
|
|
5391
|
-
for (var key in snapshot) {
|
|
5392
|
-
target.set(key, snapshot[key]);
|
|
5393
|
-
currentKeys["" + key] = true;
|
|
5394
|
-
}
|
|
5395
|
-
}
|
|
5396
|
-
Object.keys(currentKeys).forEach(function (key) {
|
|
5397
|
-
if (currentKeys[key] === false)
|
|
5437
|
+
if (!Object.prototype.hasOwnProperty.call(snapshot, key)) {
|
|
5398
5438
|
target.delete(key);
|
|
5439
|
+
return;
|
|
5440
|
+
}
|
|
5441
|
+
var childNode = node.getChildNode(key);
|
|
5442
|
+
var newValue = snapshot[key];
|
|
5443
|
+
if (childNode.snapshot === newValue)
|
|
5444
|
+
return;
|
|
5445
|
+
if (canApplyDirectSnapshot(childType, childNode, newValue)) {
|
|
5446
|
+
childNode.applySnapshot(newValue);
|
|
5447
|
+
}
|
|
5448
|
+
else {
|
|
5449
|
+
target.set(key, newValue);
|
|
5450
|
+
}
|
|
5399
5451
|
});
|
|
5452
|
+
for (var key in snapshot) {
|
|
5453
|
+
if (!Object.prototype.hasOwnProperty.call(snapshot, key) || target.has(key))
|
|
5454
|
+
continue;
|
|
5455
|
+
target.set(key, snapshot[key]);
|
|
5456
|
+
}
|
|
5400
5457
|
}
|
|
5401
5458
|
});
|
|
5402
5459
|
Object.defineProperty(MapType.prototype, "getChildType", {
|
|
@@ -5722,9 +5779,52 @@ var ArrayType = /** @class */ (function (_super) {
|
|
|
5722
5779
|
configurable: true,
|
|
5723
5780
|
writable: true,
|
|
5724
5781
|
value: function (node, snapshot) {
|
|
5725
|
-
|
|
5782
|
+
if (!isArray(snapshot)) {
|
|
5783
|
+
typecheckInternal(this, snapshot);
|
|
5784
|
+
return;
|
|
5785
|
+
}
|
|
5726
5786
|
var target = node.storedValue;
|
|
5727
|
-
|
|
5787
|
+
var childNodes = node.getChildren();
|
|
5788
|
+
var oldLength = childNodes.length;
|
|
5789
|
+
var newLength = snapshot.length;
|
|
5790
|
+
var childType = this.getChildType();
|
|
5791
|
+
var minLength = Math.min(oldLength, newLength);
|
|
5792
|
+
var firstChangedIndex = findFirstChangedIndex(childNodes, snapshot, minLength);
|
|
5793
|
+
// If all array items are the same and the length did not change, there is nothing to do.
|
|
5794
|
+
if (firstChangedIndex === oldLength && firstChangedIndex === newLength) {
|
|
5795
|
+
return;
|
|
5796
|
+
}
|
|
5797
|
+
// Preserve the old "always replace" behavior for length changes and when patches are being
|
|
5798
|
+
// observed, since those cases are more sensitive to patch shape (for example, splice
|
|
5799
|
+
// would otherwise emit add/remove patch sequences) and benchmark variance.
|
|
5800
|
+
if (oldLength !== newLength || node.hasPatchSubscribers()) {
|
|
5801
|
+
target.replace(snapshot);
|
|
5802
|
+
return;
|
|
5803
|
+
}
|
|
5804
|
+
// When every changed entry can reuse its existing child node, update them in place
|
|
5805
|
+
// instead of going through array replacement/splice.
|
|
5806
|
+
if (canApplyDirectSnapshotsInRange(childType, childNodes, snapshot, firstChangedIndex)) {
|
|
5807
|
+
applyDirectSnapshotsInRange(childNodes, snapshot, firstChangedIndex);
|
|
5808
|
+
return;
|
|
5809
|
+
}
|
|
5810
|
+
var oldEnd = oldLength - 1;
|
|
5811
|
+
var newEnd = newLength - 1;
|
|
5812
|
+
while (oldEnd >= firstChangedIndex &&
|
|
5813
|
+
newEnd >= firstChangedIndex &&
|
|
5814
|
+
childNodes[oldEnd].snapshot === snapshot[newEnd]) {
|
|
5815
|
+
oldEnd--;
|
|
5816
|
+
newEnd--;
|
|
5817
|
+
}
|
|
5818
|
+
// Trim the unchanged suffix too, so we only replace the minimal changed window.
|
|
5819
|
+
var replacedCount = oldEnd >= firstChangedIndex ? oldEnd - firstChangedIndex + 1 : 0;
|
|
5820
|
+
var replacementSnapshots = newEnd >= firstChangedIndex
|
|
5821
|
+
? snapshot.slice(firstChangedIndex, newEnd + 1)
|
|
5822
|
+
: EMPTY_ARRAY;
|
|
5823
|
+
if (replacedCount === 1 && replacementSnapshots.length === 1) {
|
|
5824
|
+
target[firstChangedIndex] = replacementSnapshots[0];
|
|
5825
|
+
return;
|
|
5826
|
+
}
|
|
5827
|
+
target.splice.apply(target, __spreadArray([firstChangedIndex, replacedCount], __read(replacementSnapshots), false));
|
|
5728
5828
|
}
|
|
5729
5829
|
});
|
|
5730
5830
|
Object.defineProperty(ArrayType.prototype, "getChildType", {
|
|
@@ -5796,6 +5896,31 @@ function array(subtype) {
|
|
|
5796
5896
|
assertIsType(subtype, 1);
|
|
5797
5897
|
return new ArrayType("".concat(subtype.name, "[]"), subtype);
|
|
5798
5898
|
}
|
|
5899
|
+
function findFirstChangedIndex(childNodes, snapshot, length) {
|
|
5900
|
+
var index = 0;
|
|
5901
|
+
while (index < length && childNodes[index].snapshot === snapshot[index]) {
|
|
5902
|
+
index++;
|
|
5903
|
+
}
|
|
5904
|
+
return index;
|
|
5905
|
+
}
|
|
5906
|
+
function canApplyDirectSnapshotsInRange(childType, childNodes, snapshot, startIndex) {
|
|
5907
|
+
for (var i = startIndex; i < childNodes.length; i++) {
|
|
5908
|
+
if (childNodes[i].snapshot === snapshot[i])
|
|
5909
|
+
continue;
|
|
5910
|
+
if (!canApplyDirectSnapshot(childType, childNodes[i], snapshot[i])) {
|
|
5911
|
+
return false;
|
|
5912
|
+
}
|
|
5913
|
+
}
|
|
5914
|
+
return true;
|
|
5915
|
+
}
|
|
5916
|
+
function applyDirectSnapshotsInRange(childNodes, snapshot, startIndex) {
|
|
5917
|
+
for (var i = startIndex; i < childNodes.length; i++) {
|
|
5918
|
+
var childNode = childNodes[i];
|
|
5919
|
+
if (childNode.snapshot === snapshot[i])
|
|
5920
|
+
continue;
|
|
5921
|
+
childNode.applySnapshot(snapshot[i]);
|
|
5922
|
+
}
|
|
5923
|
+
}
|
|
5799
5924
|
function reconcileArrayChildren(parent, childType, oldNodes, newValues, newPaths) {
|
|
5800
5925
|
var nothingChanged = true;
|
|
5801
5926
|
for (var i = 0;; i++) {
|
|
@@ -6441,10 +6566,25 @@ var ModelType = /** @class */ (function (_super) {
|
|
|
6441
6566
|
configurable: true,
|
|
6442
6567
|
writable: true,
|
|
6443
6568
|
value: function (node, snapshot) {
|
|
6444
|
-
typecheckInternal(this, snapshot);
|
|
6445
6569
|
var preProcessedSnapshot = this.applySnapshotPreProcessor(snapshot);
|
|
6446
|
-
|
|
6447
|
-
|
|
6570
|
+
var isPreProcessedSnapshotNonPlain = !isPlainObject(preProcessedSnapshot);
|
|
6571
|
+
// Fast-path plain-object snapshots, but still validate when preprocessing is required
|
|
6572
|
+
// or when preprocessing produces an invalid model snapshot.
|
|
6573
|
+
if (!isPlainObject(snapshot) || isPreProcessedSnapshotNonPlain) {
|
|
6574
|
+
typecheckInternal(this, snapshot);
|
|
6575
|
+
if (isPreProcessedSnapshotNonPlain)
|
|
6576
|
+
return;
|
|
6577
|
+
}
|
|
6578
|
+
this.forAllProps(function (name, childType) {
|
|
6579
|
+
var childNode = node.getChildNode(name);
|
|
6580
|
+
var newValue = preProcessedSnapshot[name];
|
|
6581
|
+
if (childNode.snapshot === newValue)
|
|
6582
|
+
return;
|
|
6583
|
+
if (canApplyDirectSnapshot(childType, childNode, newValue)) {
|
|
6584
|
+
childNode.applySnapshot(newValue);
|
|
6585
|
+
return;
|
|
6586
|
+
}
|
|
6587
|
+
node.storedValue[name] = newValue;
|
|
6448
6588
|
});
|
|
6449
6589
|
}
|
|
6450
6590
|
});
|
|
@@ -6735,6 +6875,37 @@ var float = new CoreType("float", TypeFlags.Float, function (v) { return isFloat
|
|
|
6735
6875
|
*/
|
|
6736
6876
|
// tslint:disable-next-line:variable-name
|
|
6737
6877
|
var finite = new CoreType("finite", TypeFlags.Finite, function (v) { return isFinite(v); });
|
|
6878
|
+
var _BigIntPrimitive = new CoreType("bigint", TypeFlags.BigInt, function (v) {
|
|
6879
|
+
if (typeof v === "bigint") {
|
|
6880
|
+
return true;
|
|
6881
|
+
}
|
|
6882
|
+
if (typeof v === "string" || typeof v === "number") {
|
|
6883
|
+
try {
|
|
6884
|
+
// BigInt primitive constructor verifies whether the value is a valid integer
|
|
6885
|
+
BigInt(v);
|
|
6886
|
+
return true;
|
|
6887
|
+
}
|
|
6888
|
+
catch (_a) { }
|
|
6889
|
+
}
|
|
6890
|
+
return false;
|
|
6891
|
+
}, function (v) { return (typeof v === "bigint" ? v : BigInt(v)); });
|
|
6892
|
+
_BigIntPrimitive.getSnapshot = function (node) {
|
|
6893
|
+
return String(node.storedValue);
|
|
6894
|
+
};
|
|
6895
|
+
/**
|
|
6896
|
+
* `types.bigint` - Creates a type that can only contain a bigint value.
|
|
6897
|
+
* Snapshots serialize to string (JSON-safe) and deserialize from string, number or bigint.
|
|
6898
|
+
*
|
|
6899
|
+
* Example:
|
|
6900
|
+
* ```ts
|
|
6901
|
+
* const BigId = types.model({
|
|
6902
|
+
* id: types.identifier,
|
|
6903
|
+
* value: types.bigint
|
|
6904
|
+
* })
|
|
6905
|
+
* getSnapshot(store).value // "0" (string, JSON-safe)
|
|
6906
|
+
* ```
|
|
6907
|
+
*/
|
|
6908
|
+
var bigint = _BigIntPrimitive;
|
|
6738
6909
|
/**
|
|
6739
6910
|
* `types.boolean` - Creates a type that can only contain a boolean value.
|
|
6740
6911
|
* This type is used for boolean values by default
|
|
@@ -6786,6 +6957,8 @@ function getPrimitiveFactoryFromValue(value) {
|
|
|
6786
6957
|
return number; // In the future, isInteger(value) ? integer : number would be interesting, but would be too breaking for now
|
|
6787
6958
|
case "boolean":
|
|
6788
6959
|
return boolean;
|
|
6960
|
+
case "bigint":
|
|
6961
|
+
return bigint;
|
|
6789
6962
|
case "object":
|
|
6790
6963
|
if (value instanceof Date)
|
|
6791
6964
|
return DatePrimitive;
|
|
@@ -6805,7 +6978,8 @@ function isPrimitiveType(type) {
|
|
|
6805
6978
|
TypeFlags.Number |
|
|
6806
6979
|
TypeFlags.Integer |
|
|
6807
6980
|
TypeFlags.Boolean |
|
|
6808
|
-
TypeFlags.Date
|
|
6981
|
+
TypeFlags.Date |
|
|
6982
|
+
TypeFlags.BigInt)) >
|
|
6809
6983
|
0);
|
|
6810
6984
|
}
|
|
6811
6985
|
|
|
@@ -8636,6 +8810,7 @@ var types = {
|
|
|
8636
8810
|
integer: integer,
|
|
8637
8811
|
float: float,
|
|
8638
8812
|
finite: finite,
|
|
8813
|
+
bigint: bigint,
|
|
8639
8814
|
Date: DatePrimitive,
|
|
8640
8815
|
map: map,
|
|
8641
8816
|
array: array,
|