@jbrowse/mobx-state-tree 6.5.2 → 6.6.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/CHANGELOG.md +23 -0
- package/dist/index.d.ts +151 -116
- package/dist/mobx-state-tree.cjs +272 -318
- package/dist/mobx-state-tree.cjs.map +1 -1
- package/dist/mobx-state-tree.mjs +269 -320
- package/dist/mobx-state-tree.mjs.map +1 -1
- package/package.json +1 -1
package/dist/mobx-state-tree.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isComputedProp, isObservableProp,
|
|
1
|
+
import { isComputedProp, isObservableProp, action, createAtom, computed, _allowStateChangesInsideComputed, reaction, runInAction, observable, values, entries, isObservableArray, isObservableObject, defineProperty as defineProperty$1, _interceptReads, intercept, observe, ObservableMap, _getAdministration, set, makeObservable, getAtom, when } from 'mobx';
|
|
2
2
|
|
|
3
3
|
let livelinessChecking = "warn";
|
|
4
4
|
/**
|
|
@@ -565,7 +565,9 @@ function getRelativePath(base, target) {
|
|
|
565
565
|
}
|
|
566
566
|
/**
|
|
567
567
|
* Returns a deep copy of the given state tree node as new tree.
|
|
568
|
-
*
|
|
568
|
+
* Like `getType(x).create(getSnapshot(x))`, except that a node wrapped in a
|
|
569
|
+
* `types.snapshotProcessor` is recreated through the processor, which
|
|
570
|
+
* `getType(x)` (the wrapped type) would skip.
|
|
569
571
|
*
|
|
570
572
|
* _Tip: clone will create a literal copy, including the same identifiers. To modify identifiers etc. during cloning, don't use clone but take a snapshot of the tree, modify it, and create new instance_
|
|
571
573
|
*
|
|
@@ -577,11 +579,11 @@ function clone(source, keepEnvironment = true) {
|
|
|
577
579
|
// check all arguments
|
|
578
580
|
assertIsStateTreeNode(source, 1);
|
|
579
581
|
const node = getStateTreeNode(source);
|
|
580
|
-
return node.type.create(node.snapshot, keepEnvironment === true
|
|
582
|
+
return (node.snapshotProcessorType ?? node.type).create(node.snapshot, keepEnvironment === true
|
|
581
583
|
? node.root.environment
|
|
582
584
|
: keepEnvironment === false
|
|
583
585
|
? undefined
|
|
584
|
-
: keepEnvironment);
|
|
586
|
+
: keepEnvironment);
|
|
585
587
|
}
|
|
586
588
|
/**
|
|
587
589
|
* Removes a model element from the state tree, and let it live on as a new state tree
|
|
@@ -700,17 +702,15 @@ function walk(target, processor) {
|
|
|
700
702
|
* @returns
|
|
701
703
|
*/
|
|
702
704
|
function getPropertyMembers(typeOrNode) {
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
}
|
|
710
|
-
assertArg(type, t => isModelType(t), "model type or model instance", 1);
|
|
705
|
+
const type = isStateTreeNode(typeOrNode)
|
|
706
|
+
? getType(typeOrNode)
|
|
707
|
+
: typeOrNode;
|
|
708
|
+
assertArg(type, isModelType, "model type or model instance", 1);
|
|
709
|
+
// a wrapped model reports the model's properties; a union of models has no
|
|
710
|
+
// single set and reports none
|
|
711
711
|
return {
|
|
712
712
|
name: type.name,
|
|
713
|
-
properties: { ...type
|
|
713
|
+
properties: { ...asModelType(type)?.properties }
|
|
714
714
|
};
|
|
715
715
|
}
|
|
716
716
|
/**
|
|
@@ -912,16 +912,28 @@ class BaseNode {
|
|
|
912
912
|
}
|
|
913
913
|
}
|
|
914
914
|
_hookSubscribers;
|
|
915
|
-
fireInternalHook(name) {
|
|
916
|
-
|
|
917
|
-
|
|
915
|
+
fireInternalHook(name, subject = this) {
|
|
916
|
+
this._hookSubscribers?.emit(name, subject, name);
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Detaching a node takes its whole subtree out of the tree, but only the
|
|
920
|
+
* detached node's parent changes, so only it fires `beforeDetach` for real.
|
|
921
|
+
* Internal subscribers below it (reference watchers on a target) still need
|
|
922
|
+
* to know their node is leaving.
|
|
923
|
+
*/
|
|
924
|
+
notifyDetachOf(subject) {
|
|
925
|
+
this.fireInternalHook(Hook.beforeDetach, subject);
|
|
926
|
+
}
|
|
927
|
+
isWithin(ancestor) {
|
|
928
|
+
for (let node = this.parent; node; node = node.parent) {
|
|
929
|
+
if (node === ancestor) {
|
|
930
|
+
return true;
|
|
931
|
+
}
|
|
918
932
|
}
|
|
933
|
+
return false;
|
|
919
934
|
}
|
|
920
935
|
registerHook(hook, hookHandler) {
|
|
921
|
-
|
|
922
|
-
this._hookSubscribers = new EventHandlers();
|
|
923
|
-
}
|
|
924
|
-
return this._hookSubscribers.register(hook, hookHandler);
|
|
936
|
+
return (this._hookSubscribers ??= new EventHandlers()).register(hook, hookHandler);
|
|
925
937
|
}
|
|
926
938
|
_parent;
|
|
927
939
|
get parent() {
|
|
@@ -982,6 +994,13 @@ class BaseNode {
|
|
|
982
994
|
this.aliveAtom.reportObserved();
|
|
983
995
|
return this.isAlive;
|
|
984
996
|
}
|
|
997
|
+
die() {
|
|
998
|
+
if (!this.isAlive || this.isDetaching) {
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
this.aboutToDie();
|
|
1002
|
+
this.finalizeDeath();
|
|
1003
|
+
}
|
|
985
1004
|
baseFinalizeCreation(whenFinalized) {
|
|
986
1005
|
if (devMode()) {
|
|
987
1006
|
if (!this.isAlive) {
|
|
@@ -1017,6 +1036,7 @@ class BaseNode {
|
|
|
1017
1036
|
this.fireHook(Hook.beforeDestroy);
|
|
1018
1037
|
}
|
|
1019
1038
|
}
|
|
1039
|
+
BaseNode.prototype.die = action(BaseNode.prototype.die);
|
|
1020
1040
|
|
|
1021
1041
|
/**
|
|
1022
1042
|
* @internal
|
|
@@ -1034,9 +1054,6 @@ class ScalarNode extends BaseNode {
|
|
|
1034
1054
|
throw e;
|
|
1035
1055
|
}
|
|
1036
1056
|
this.state = NodeLifeCycle.CREATED;
|
|
1037
|
-
// for scalar nodes there's no point in firing this event since it would fire on the constructor, before
|
|
1038
|
-
// anybody can actually register for/listen to it
|
|
1039
|
-
// this.fireHook(Hook.AfterCreate)
|
|
1040
1057
|
this.finalizeCreation();
|
|
1041
1058
|
}
|
|
1042
1059
|
get root() {
|
|
@@ -1079,13 +1096,6 @@ class ScalarNode extends BaseNode {
|
|
|
1079
1096
|
const path = (this.isAlive ? this.path : this.pathUponDeath) || "<root>";
|
|
1080
1097
|
return `${this.type.name}@${path}${this.isAlive ? "" : " [dead]"}`;
|
|
1081
1098
|
}
|
|
1082
|
-
die() {
|
|
1083
|
-
if (!this.isAlive || this.state === NodeLifeCycle.DETACHING) {
|
|
1084
|
-
return;
|
|
1085
|
-
}
|
|
1086
|
-
this.aboutToDie();
|
|
1087
|
-
this.finalizeDeath();
|
|
1088
|
-
}
|
|
1089
1099
|
finalizeCreation() {
|
|
1090
1100
|
this.baseFinalizeCreation();
|
|
1091
1101
|
}
|
|
@@ -1099,7 +1109,6 @@ class ScalarNode extends BaseNode {
|
|
|
1099
1109
|
this.fireInternalHook(name);
|
|
1100
1110
|
}
|
|
1101
1111
|
}
|
|
1102
|
-
ScalarNode.prototype.die = action(ScalarNode.prototype.die);
|
|
1103
1112
|
|
|
1104
1113
|
let nextNodeId = 1;
|
|
1105
1114
|
var ObservableInstanceLifecycle;
|
|
@@ -1287,8 +1296,8 @@ class ObjectNode extends BaseNode {
|
|
|
1287
1296
|
if (!this.parent) {
|
|
1288
1297
|
return;
|
|
1289
1298
|
}
|
|
1290
|
-
// detach if attached
|
|
1291
1299
|
this.fireHook(Hook.beforeDetach);
|
|
1300
|
+
this.notifyChildrenOfDetach(this);
|
|
1292
1301
|
const previousState = this.state;
|
|
1293
1302
|
this.state = NodeLifeCycle.DETACHING;
|
|
1294
1303
|
const root = this.root;
|
|
@@ -1304,6 +1313,21 @@ class ObjectNode extends BaseNode {
|
|
|
1304
1313
|
this.state = previousState;
|
|
1305
1314
|
}
|
|
1306
1315
|
}
|
|
1316
|
+
notifyDetachOf(subject) {
|
|
1317
|
+
super.notifyDetachOf(subject);
|
|
1318
|
+
this.notifyChildrenOfDetach(subject);
|
|
1319
|
+
}
|
|
1320
|
+
notifyChildrenOfDetach(subject) {
|
|
1321
|
+
// a handler notified earlier in the walk may have destroyed this node.
|
|
1322
|
+
// A node never read still has to be walked: an instance created elsewhere
|
|
1323
|
+
// can have been moved under it, subscribers and all.
|
|
1324
|
+
if (!this.isAlive) {
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
for (const child of this.getChildren()) {
|
|
1328
|
+
child.notifyDetachOf(subject);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1307
1331
|
setParent(newParent, subpath) {
|
|
1308
1332
|
const parentChanged = newParent !== this.parent;
|
|
1309
1333
|
const subpathChanged = subpath !== this.subpath;
|
|
@@ -1508,37 +1532,27 @@ class ObjectNode extends BaseNode {
|
|
|
1508
1532
|
this.clearParent();
|
|
1509
1533
|
}
|
|
1510
1534
|
preboot() {
|
|
1511
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1512
|
-
const self = this;
|
|
1513
1535
|
this._applyPatches = createActionInvoker(this.storedValue, "@APPLY_PATCHES", (patches) => {
|
|
1514
1536
|
patches.forEach(patch => {
|
|
1515
1537
|
if (!patch.path) {
|
|
1516
|
-
|
|
1538
|
+
this.type.applySnapshot(this, patch.value);
|
|
1517
1539
|
return;
|
|
1518
1540
|
}
|
|
1519
1541
|
const parts = splitJsonPath(patch.path);
|
|
1520
|
-
const node = resolveNodeByPathParts(
|
|
1542
|
+
const node = resolveNodeByPathParts(this, parts.slice(0, -1));
|
|
1521
1543
|
node.applyPatchLocally(parts[parts.length - 1], patch);
|
|
1522
1544
|
});
|
|
1523
1545
|
});
|
|
1524
1546
|
this._applySnapshot = createActionInvoker(this.storedValue, "@APPLY_SNAPSHOT", (snapshot) => {
|
|
1525
|
-
//
|
|
1526
|
-
if (snapshot ===
|
|
1547
|
+
// the current snapshot needs no reconcile
|
|
1548
|
+
if (snapshot === this.snapshot) {
|
|
1527
1549
|
return;
|
|
1528
1550
|
}
|
|
1529
|
-
|
|
1530
|
-
return self.type.applySnapshot(self, snapshot);
|
|
1551
|
+
this.type.applySnapshot(this, snapshot);
|
|
1531
1552
|
});
|
|
1532
1553
|
addHiddenFinalProp(this.storedValue, "$treenode", this);
|
|
1533
1554
|
addHiddenFinalProp(this.storedValue, "toJSON", toJSON);
|
|
1534
1555
|
}
|
|
1535
|
-
die() {
|
|
1536
|
-
if (!this.isAlive || this.state === NodeLifeCycle.DETACHING) {
|
|
1537
|
-
return;
|
|
1538
|
-
}
|
|
1539
|
-
this.aboutToDie();
|
|
1540
|
-
this.finalizeDeath();
|
|
1541
|
-
}
|
|
1542
1556
|
aboutToDie() {
|
|
1543
1557
|
if (this._observableInstanceState ===
|
|
1544
1558
|
ObservableInstanceLifecycle.UNINITIALIZED) {
|
|
@@ -1550,8 +1564,8 @@ class ObjectNode extends BaseNode {
|
|
|
1550
1564
|
// beforeDestroy should run before the disposers since else we could end up in a situation where
|
|
1551
1565
|
// a disposer added with addDisposer at this stage (beforeDestroy) is actually never released
|
|
1552
1566
|
this.baseAboutToDie();
|
|
1553
|
-
this.
|
|
1554
|
-
this.
|
|
1567
|
+
this._internalEvents?.emit(InternalEvents.Dispose);
|
|
1568
|
+
this._internalEvents?.clear(InternalEvents.Dispose);
|
|
1555
1569
|
}
|
|
1556
1570
|
finalizeDeath() {
|
|
1557
1571
|
// invariant: not called directly but from "die"
|
|
@@ -1562,57 +1576,57 @@ class ObjectNode extends BaseNode {
|
|
|
1562
1576
|
// "kill" the computed prop and just store the last snapshot
|
|
1563
1577
|
const snapshot = this.snapshot;
|
|
1564
1578
|
this._snapshotUponDeath = snapshot;
|
|
1565
|
-
this.
|
|
1579
|
+
this._internalEvents?.clearAll();
|
|
1566
1580
|
this.baseFinalizeDeath();
|
|
1567
1581
|
}
|
|
1568
1582
|
onSnapshot(onChange) {
|
|
1569
1583
|
this._addSnapshotReaction();
|
|
1570
|
-
const unregister = this.
|
|
1584
|
+
const unregister = this.internalEvents().register(InternalEvents.Snapshot, onChange);
|
|
1571
1585
|
return () => {
|
|
1572
1586
|
unregister();
|
|
1573
1587
|
// The reaction re-serializes the whole subtree on every change, so leaving
|
|
1574
1588
|
// it running once the last listener is gone would keep charging the node
|
|
1575
1589
|
// for a snapshot nobody receives. Referential stability of getSnapshot()
|
|
1576
1590
|
// does not depend on it — that comes from keepAlive on _snapshotComputed.
|
|
1577
|
-
if (!this.
|
|
1591
|
+
if (!this._internalEvents?.hasSubscribers(InternalEvents.Snapshot)) {
|
|
1578
1592
|
this._removeSnapshotReaction();
|
|
1579
1593
|
}
|
|
1580
1594
|
};
|
|
1581
1595
|
}
|
|
1582
1596
|
emitSnapshot(snapshot) {
|
|
1583
|
-
this.
|
|
1597
|
+
this._internalEvents?.emit(InternalEvents.Snapshot, snapshot);
|
|
1584
1598
|
}
|
|
1585
1599
|
onPatch(handler) {
|
|
1586
|
-
return this.
|
|
1600
|
+
return this.internalEvents().register(InternalEvents.Patch, handler);
|
|
1587
1601
|
}
|
|
1588
1602
|
emitPatch(basePatch, source) {
|
|
1589
|
-
if (this.
|
|
1603
|
+
if (this._internalEvents?.hasSubscribers(InternalEvents.Patch)) {
|
|
1590
1604
|
const localizedPatch = {
|
|
1591
1605
|
...basePatch,
|
|
1592
1606
|
path: `${source.path.slice(this.path.length)}/${basePatch.path}` // calculate the relative path of the patch
|
|
1593
1607
|
};
|
|
1594
1608
|
const [patch, reversePatch] = splitPatch(localizedPatch);
|
|
1595
|
-
this.
|
|
1609
|
+
this._internalEvents?.emit(InternalEvents.Patch, patch, reversePatch);
|
|
1596
1610
|
}
|
|
1597
1611
|
if (this.parent) {
|
|
1598
1612
|
this.parent.emitPatch(basePatch, source);
|
|
1599
1613
|
}
|
|
1600
1614
|
}
|
|
1601
1615
|
hasDisposer(disposer) {
|
|
1602
|
-
return this.
|
|
1616
|
+
return !!this._internalEvents?.has(InternalEvents.Dispose, disposer);
|
|
1603
1617
|
}
|
|
1604
1618
|
addDisposer(disposer) {
|
|
1605
1619
|
if (!this.hasDisposer(disposer)) {
|
|
1606
|
-
this.
|
|
1620
|
+
this.internalEvents().register(InternalEvents.Dispose, disposer, true);
|
|
1607
1621
|
return;
|
|
1608
1622
|
}
|
|
1609
1623
|
throw fail("cannot add a disposer when it is already registered for execution");
|
|
1610
1624
|
}
|
|
1611
1625
|
removeDisposer(disposer) {
|
|
1612
|
-
if (!this.
|
|
1626
|
+
if (!this._internalEvents?.has(InternalEvents.Dispose, disposer)) {
|
|
1613
1627
|
throw fail("cannot remove a disposer which was never registered for execution");
|
|
1614
1628
|
}
|
|
1615
|
-
this.
|
|
1629
|
+
this._internalEvents?.unregister(InternalEvents.Dispose, disposer);
|
|
1616
1630
|
}
|
|
1617
1631
|
removeMiddleware(middleware) {
|
|
1618
1632
|
if (this.middlewares) {
|
|
@@ -1657,48 +1671,17 @@ class ObjectNode extends BaseNode {
|
|
|
1657
1671
|
// not removeDisposer(), which throws when the registration is already gone —
|
|
1658
1672
|
// the last listener can be disposed from within a disposer, i.e. after
|
|
1659
1673
|
// aboutToDie has cleared them
|
|
1660
|
-
this.
|
|
1674
|
+
this._internalEvents?.unregister(InternalEvents.Dispose, disposer);
|
|
1661
1675
|
disposer();
|
|
1662
1676
|
}
|
|
1663
|
-
//
|
|
1677
|
+
// created on first registration: most nodes never get a listener
|
|
1664
1678
|
_internalEvents;
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
return !!this._internalEvents && this._internalEvents.hasSubscribers(event);
|
|
1668
|
-
}
|
|
1669
|
-
_internalEventsRegister(event, eventHandler, atTheBeginning = false) {
|
|
1670
|
-
if (!this._internalEvents) {
|
|
1671
|
-
this._internalEvents = new EventHandlers();
|
|
1672
|
-
}
|
|
1673
|
-
return this._internalEvents.register(event, eventHandler, atTheBeginning);
|
|
1674
|
-
}
|
|
1675
|
-
_internalEventsHas(event, eventHandler) {
|
|
1676
|
-
return (!!this._internalEvents && this._internalEvents.has(event, eventHandler));
|
|
1677
|
-
}
|
|
1678
|
-
_internalEventsUnregister(event, eventHandler) {
|
|
1679
|
-
if (this._internalEvents) {
|
|
1680
|
-
this._internalEvents.unregister(event, eventHandler);
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
_internalEventsEmit(event, ...args) {
|
|
1684
|
-
if (this._internalEvents) {
|
|
1685
|
-
this._internalEvents.emit(event, ...args);
|
|
1686
|
-
}
|
|
1687
|
-
}
|
|
1688
|
-
_internalEventsClear(event) {
|
|
1689
|
-
if (this._internalEvents) {
|
|
1690
|
-
this._internalEvents.clear(event);
|
|
1691
|
-
}
|
|
1692
|
-
}
|
|
1693
|
-
_internalEventsClearAll() {
|
|
1694
|
-
if (this._internalEvents) {
|
|
1695
|
-
this._internalEvents.clearAll();
|
|
1696
|
-
}
|
|
1679
|
+
internalEvents() {
|
|
1680
|
+
return (this._internalEvents ??= new EventHandlers());
|
|
1697
1681
|
}
|
|
1698
1682
|
}
|
|
1699
1683
|
ObjectNode.prototype.createObservableInstance = action(ObjectNode.prototype.createObservableInstance);
|
|
1700
1684
|
ObjectNode.prototype.detach = action(ObjectNode.prototype.detach);
|
|
1701
|
-
ObjectNode.prototype.die = action(ObjectNode.prototype.die);
|
|
1702
1685
|
|
|
1703
1686
|
/**
|
|
1704
1687
|
* @internal
|
|
@@ -1890,7 +1873,6 @@ class ComplexType extends BaseType {
|
|
|
1890
1873
|
return null;
|
|
1891
1874
|
}
|
|
1892
1875
|
}
|
|
1893
|
-
ComplexType.prototype.create = action(ComplexType.prototype.create);
|
|
1894
1876
|
/**
|
|
1895
1877
|
* @internal
|
|
1896
1878
|
* @hidden
|
|
@@ -1900,11 +1882,6 @@ class SimpleType extends BaseType {
|
|
|
1900
1882
|
return snapshot;
|
|
1901
1883
|
}
|
|
1902
1884
|
getValue(node) {
|
|
1903
|
-
// if we ever find a case where scalar nodes can be accessed without iterating through its parent
|
|
1904
|
-
// uncomment this to make sure the parent chain is created when this is accessed
|
|
1905
|
-
// if (node.parent) {
|
|
1906
|
-
// node.parent.createObservableInstanceIfNeeded()
|
|
1907
|
-
// }
|
|
1908
1885
|
return node.storedValue;
|
|
1909
1886
|
}
|
|
1910
1887
|
getSnapshot(node) {
|
|
@@ -1934,6 +1911,30 @@ class SimpleType extends BaseType {
|
|
|
1934
1911
|
function isType(value) {
|
|
1935
1912
|
return (typeof value === "object" && value?.isType === true);
|
|
1936
1913
|
}
|
|
1914
|
+
/**
|
|
1915
|
+
* The one type a wrapper hands everything to: what an `optional`,
|
|
1916
|
+
* `stripDefault`, `refinement`, `snapshotProcessor` or (resolved) `late`
|
|
1917
|
+
* wraps. `undefined` for any other type, including a union or a `resilient`,
|
|
1918
|
+
* which pick a type per value.
|
|
1919
|
+
*
|
|
1920
|
+
* Resolves a `late` type's definition if it has not been read yet.
|
|
1921
|
+
*/
|
|
1922
|
+
function getWrappedType(type) {
|
|
1923
|
+
const subtype = type.getSubTypes();
|
|
1924
|
+
return isType(subtype) ? subtype : undefined;
|
|
1925
|
+
}
|
|
1926
|
+
/**
|
|
1927
|
+
* Strips every wrapper {@link getWrappedType} sees through, down to the type
|
|
1928
|
+
* that actually builds the value: for a complex type `T`,
|
|
1929
|
+
* `getType(T.create(snapshot)) === unwrapType(T)`.
|
|
1930
|
+
*
|
|
1931
|
+
* `types.model({ xs: types.array(X) }).properties.xs`, for instance, is an
|
|
1932
|
+
* `optional` whose unwrapped type is the array type.
|
|
1933
|
+
*/
|
|
1934
|
+
function unwrapType(type) {
|
|
1935
|
+
const wrapped = getWrappedType(type);
|
|
1936
|
+
return wrapped ? unwrapType(wrapped) : type;
|
|
1937
|
+
}
|
|
1937
1938
|
/**
|
|
1938
1939
|
* @internal
|
|
1939
1940
|
* @hidden
|
|
@@ -2932,7 +2933,7 @@ function createScalarNode(type, parent, subpath, environment, initialValue) {
|
|
|
2932
2933
|
* @hidden
|
|
2933
2934
|
*/
|
|
2934
2935
|
function isNode(value) {
|
|
2935
|
-
return value instanceof
|
|
2936
|
+
return value instanceof BaseNode;
|
|
2936
2937
|
}
|
|
2937
2938
|
|
|
2938
2939
|
/**
|
|
@@ -3111,25 +3112,6 @@ function fail(message = "Illegal state") {
|
|
|
3111
3112
|
function identity(_) {
|
|
3112
3113
|
return _;
|
|
3113
3114
|
}
|
|
3114
|
-
/**
|
|
3115
|
-
* @internal
|
|
3116
|
-
* @hidden
|
|
3117
|
-
*/
|
|
3118
|
-
const isInteger = Number.isInteger;
|
|
3119
|
-
/**
|
|
3120
|
-
* @internal
|
|
3121
|
-
* @hidden
|
|
3122
|
-
*/
|
|
3123
|
-
function isFloat(val) {
|
|
3124
|
-
return Number(val) === val && val % 1 !== 0;
|
|
3125
|
-
}
|
|
3126
|
-
/**
|
|
3127
|
-
* @internal
|
|
3128
|
-
* @hidden
|
|
3129
|
-
*/
|
|
3130
|
-
function isFinite(val) {
|
|
3131
|
-
return Number.isFinite(val);
|
|
3132
|
-
}
|
|
3133
3115
|
/**
|
|
3134
3116
|
* @internal
|
|
3135
3117
|
* @hidden
|
|
@@ -3777,11 +3759,8 @@ class SnapshotProcessor extends BaseType {
|
|
|
3777
3759
|
return sn;
|
|
3778
3760
|
}
|
|
3779
3761
|
_fixNode(node) {
|
|
3780
|
-
// the node's type is the *inner* type, so `getType(instance).create(...)`
|
|
3781
|
-
// would bypass the processors — point it at ours instead
|
|
3782
|
-
const nodeType = node.type;
|
|
3783
|
-
nodeType.create = this.create.bind(this);
|
|
3784
3762
|
if (node instanceof ObjectNode) {
|
|
3763
|
+
node.snapshotProcessorType = this;
|
|
3785
3764
|
node.hasSnapshotPostProcessor = !!this._processors.postProcessor;
|
|
3786
3765
|
}
|
|
3787
3766
|
const oldGetSnapshot = node.getSnapshot;
|
|
@@ -4265,14 +4244,20 @@ function map(subtype) {
|
|
|
4265
4244
|
return new MapType(subtype);
|
|
4266
4245
|
}
|
|
4267
4246
|
/**
|
|
4268
|
-
* Returns if a
|
|
4269
|
-
*
|
|
4270
|
-
* @param type
|
|
4271
|
-
* @returns `true` if it is a map type.
|
|
4247
|
+
* Returns if a type is a map type, or wraps or unions one. For the map type
|
|
4248
|
+
* itself, use {@link asMapType}.
|
|
4272
4249
|
*/
|
|
4273
4250
|
function isMapType(type) {
|
|
4274
4251
|
return isType(type) && (type.flags & TypeFlags.Map) > 0;
|
|
4275
4252
|
}
|
|
4253
|
+
/**
|
|
4254
|
+
* The map type `type` builds its values with, seeing through the wrappers
|
|
4255
|
+
* {@link unwrapType} does, or `undefined` if that is not a map type.
|
|
4256
|
+
*/
|
|
4257
|
+
function asMapType(type) {
|
|
4258
|
+
const unwrapped = unwrapType(type);
|
|
4259
|
+
return unwrapped instanceof MapType ? unwrapped : undefined;
|
|
4260
|
+
}
|
|
4276
4261
|
|
|
4277
4262
|
/**
|
|
4278
4263
|
* @internal
|
|
@@ -4642,14 +4627,20 @@ function areSame(oldNode, newValue) {
|
|
|
4642
4627
|
oldNodeType.isMatchingSnapshotId(oldNode, newValue));
|
|
4643
4628
|
}
|
|
4644
4629
|
/**
|
|
4645
|
-
* Returns if a
|
|
4646
|
-
*
|
|
4647
|
-
* @param type
|
|
4648
|
-
* @returns `true` if the type is an array type.
|
|
4630
|
+
* Returns if a type is an array type, or wraps or unions one. For the array
|
|
4631
|
+
* type itself, use {@link asArrayType}.
|
|
4649
4632
|
*/
|
|
4650
4633
|
function isArrayType(type) {
|
|
4651
4634
|
return isType(type) && (type.flags & TypeFlags.Array) > 0;
|
|
4652
4635
|
}
|
|
4636
|
+
/**
|
|
4637
|
+
* The array type `type` builds its values with, seeing through the wrappers
|
|
4638
|
+
* {@link unwrapType} does, or `undefined` if that is not an array type.
|
|
4639
|
+
*/
|
|
4640
|
+
function asArrayType(type) {
|
|
4641
|
+
const unwrapped = unwrapType(type);
|
|
4642
|
+
return unwrapped instanceof ArrayType ? unwrapped : undefined;
|
|
4643
|
+
}
|
|
4653
4644
|
|
|
4654
4645
|
const PRE_PROCESS_SNAPSHOT = "preProcessSnapshot";
|
|
4655
4646
|
const POST_PROCESS_SNAPSHOT = "postProcessSnapshot";
|
|
@@ -4684,6 +4675,12 @@ function getPropObservables(storedValue) {
|
|
|
4684
4675
|
function objectTypeToString() {
|
|
4685
4676
|
return getStateTreeNode(this).toString();
|
|
4686
4677
|
}
|
|
4678
|
+
/** `second` applied to `first`'s result, allocating only when both exist */
|
|
4679
|
+
function chainProcessors(first, second) {
|
|
4680
|
+
return first && second
|
|
4681
|
+
? snapshot => second(first(snapshot))
|
|
4682
|
+
: (first ?? second);
|
|
4683
|
+
}
|
|
4687
4684
|
const ANONYMOUS_MODEL_NAME = "AnonymousModel";
|
|
4688
4685
|
/**
|
|
4689
4686
|
* A plain loop rather than a callback per property, which allocated a closure
|
|
@@ -4972,8 +4969,6 @@ class ModelType extends ComplexType {
|
|
|
4972
4969
|
? initialValue
|
|
4973
4970
|
: this.applySnapshotPreProcessor(initialValue);
|
|
4974
4971
|
return createObjectNode(this, parent, subpath, environment, value);
|
|
4975
|
-
// Optimization: record all prop- view- and action names after first construction, and generate an optimal base class
|
|
4976
|
-
// that pre-reserves all these fields for fast object-member lookups
|
|
4977
4972
|
}
|
|
4978
4973
|
initializeChildNodes(objNode, initialSnapshot = {}) {
|
|
4979
4974
|
const type = objNode.type;
|
|
@@ -5137,15 +5132,12 @@ class ModelType extends ComplexType {
|
|
|
5137
5132
|
}
|
|
5138
5133
|
}
|
|
5139
5134
|
applySnapshotPreProcessor(snapshot) {
|
|
5140
|
-
const
|
|
5141
|
-
return
|
|
5135
|
+
const preProcessor = this.preProcessor;
|
|
5136
|
+
return preProcessor ? preProcessor(snapshot) : snapshot;
|
|
5142
5137
|
}
|
|
5143
5138
|
applySnapshotPostProcessor(snapshot) {
|
|
5144
5139
|
const postProcessor = this.postProcessor;
|
|
5145
|
-
|
|
5146
|
-
return postProcessor.call(null, snapshot);
|
|
5147
|
-
}
|
|
5148
|
-
return snapshot;
|
|
5140
|
+
return postProcessor ? postProcessor(snapshot) : snapshot;
|
|
5149
5141
|
}
|
|
5150
5142
|
getChildType(propertyName) {
|
|
5151
5143
|
assertIsString(propertyName, 1);
|
|
@@ -5168,7 +5160,6 @@ class ModelType extends ComplexType {
|
|
|
5168
5160
|
return typeCheckSuccess();
|
|
5169
5161
|
}
|
|
5170
5162
|
describe() {
|
|
5171
|
-
// optimization: cache
|
|
5172
5163
|
return `{ ${this.propertyNames
|
|
5173
5164
|
.map(key => `${key}: ${this.properties[key].describe()}`)
|
|
5174
5165
|
.join("; ")} }`;
|
|
@@ -5190,27 +5181,17 @@ Object.assign(ModelType.prototype, {
|
|
|
5190
5181
|
props(properties) {
|
|
5191
5182
|
return this.cloneAndEnhance({ properties });
|
|
5192
5183
|
},
|
|
5184
|
+
// a newly added pre-processor sees the raw snapshot first; a newly added
|
|
5185
|
+
// post-processor sees what the existing one produced
|
|
5193
5186
|
preProcessSnapshot(preProcessor) {
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
}
|
|
5198
|
-
else {
|
|
5199
|
-
return this.cloneAndEnhance({
|
|
5200
|
-
preProcessor: snapshot => currentPreprocessor(preProcessor(snapshot))
|
|
5201
|
-
});
|
|
5202
|
-
}
|
|
5187
|
+
return this.cloneAndEnhance({
|
|
5188
|
+
preProcessor: chainProcessors(preProcessor, this.preProcessor)
|
|
5189
|
+
});
|
|
5203
5190
|
},
|
|
5204
5191
|
postProcessSnapshot(postProcessor) {
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
}
|
|
5209
|
-
else {
|
|
5210
|
-
return this.cloneAndEnhance({
|
|
5211
|
-
postProcessor: snapshot => postProcessor(currentPostprocessor(snapshot))
|
|
5212
|
-
});
|
|
5213
|
-
}
|
|
5192
|
+
return this.cloneAndEnhance({
|
|
5193
|
+
postProcessor: chainProcessors(this.postProcessor, postProcessor)
|
|
5194
|
+
});
|
|
5214
5195
|
}
|
|
5215
5196
|
});
|
|
5216
5197
|
/**
|
|
@@ -5234,39 +5215,44 @@ function model(...args) {
|
|
|
5234
5215
|
* the types are composed into a new Type with the given name
|
|
5235
5216
|
*/
|
|
5236
5217
|
function compose(...args) {
|
|
5237
|
-
// TODO: just join the base type names if no name is provided
|
|
5238
5218
|
const hasTypename = typeof args[0] === "string";
|
|
5239
5219
|
const typeName = hasTypename ? args[0] : ANONYMOUS_MODEL_NAME;
|
|
5240
5220
|
if (hasTypename) {
|
|
5241
5221
|
args.shift();
|
|
5242
5222
|
}
|
|
5243
|
-
//
|
|
5223
|
+
// exactly a model type: each part's own properties and initializers are
|
|
5224
|
+
// read below, and a wrapper around a model has neither
|
|
5244
5225
|
if (devMode()) {
|
|
5245
5226
|
args.forEach((type, i) => {
|
|
5246
|
-
assertArg(type,
|
|
5227
|
+
assertArg(type, t => t instanceof ModelType, "mobx-state-tree model type", hasTypename ? i + 2 : i + 1);
|
|
5247
5228
|
});
|
|
5248
5229
|
}
|
|
5249
5230
|
return args
|
|
5250
5231
|
.reduce((prev, cur) => prev.cloneAndEnhance({
|
|
5251
|
-
name: `${prev.name}_${cur.name}`,
|
|
5252
5232
|
properties: cur.properties,
|
|
5253
5233
|
// cur.properties is another ModelType's already-converted+frozen bag
|
|
5254
5234
|
propertiesAreConverted: true,
|
|
5255
5235
|
initializers: cur.initializers,
|
|
5256
|
-
preProcessor: (
|
|
5257
|
-
postProcessor: (
|
|
5236
|
+
preProcessor: chainProcessors(prev.preProcessor, cur.preProcessor),
|
|
5237
|
+
postProcessor: chainProcessors(prev.postProcessor, cur.postProcessor)
|
|
5258
5238
|
}))
|
|
5259
5239
|
.named(typeName);
|
|
5260
5240
|
}
|
|
5261
5241
|
/**
|
|
5262
|
-
* Returns if a
|
|
5263
|
-
*
|
|
5264
|
-
* @param type
|
|
5265
|
-
* @returns
|
|
5242
|
+
* Returns if a type is a model type, or wraps or unions one. For the model
|
|
5243
|
+
* type itself, use {@link asModelType}.
|
|
5266
5244
|
*/
|
|
5267
5245
|
function isModelType(type) {
|
|
5268
5246
|
return isType(type) && (type.flags & TypeFlags.Object) > 0;
|
|
5269
5247
|
}
|
|
5248
|
+
/**
|
|
5249
|
+
* The model type `type` builds its values with, seeing through the wrappers
|
|
5250
|
+
* {@link unwrapType} does, or `undefined` if that is not a model type.
|
|
5251
|
+
*/
|
|
5252
|
+
function asModelType(type) {
|
|
5253
|
+
const unwrapped = unwrapType(type);
|
|
5254
|
+
return unwrapped instanceof ModelType ? unwrapped : undefined;
|
|
5255
|
+
}
|
|
5270
5256
|
/**
|
|
5271
5257
|
* `extendInstance` - attaches additional actions, views and volatile state to an
|
|
5272
5258
|
* already-created model instance, using the same instantiation machinery as
|
|
@@ -5292,7 +5278,7 @@ function extendInstance(instance, fn) {
|
|
|
5292
5278
|
throw fail("extendInstance expects a mobx-state-tree node");
|
|
5293
5279
|
}
|
|
5294
5280
|
const type = getStateTreeNode(instance).type;
|
|
5295
|
-
if (!
|
|
5281
|
+
if (!(type instanceof ModelType)) {
|
|
5296
5282
|
throw fail("extendInstance can only be used on model instances");
|
|
5297
5283
|
}
|
|
5298
5284
|
// Views/actions/volatile are installed via defineProperty + makeObservable — the
|
|
@@ -5300,9 +5286,8 @@ function extendInstance(instance, fn) {
|
|
|
5300
5286
|
// write-protection interceptor is attached (see finalizeNewInstance). On a live
|
|
5301
5287
|
// instance that interceptor is already active, so run the attach inside an action
|
|
5302
5288
|
// context: isRunningAction() then short-circuits assertWritable.
|
|
5303
|
-
const modelType = type;
|
|
5304
5289
|
const attach = createActionInvoker(instance, "@@extendInstance", (() => {
|
|
5305
|
-
|
|
5290
|
+
type.applyExtensionToInstance(instance, fn(instance));
|
|
5306
5291
|
}));
|
|
5307
5292
|
attach();
|
|
5308
5293
|
return instance;
|
|
@@ -5374,7 +5359,7 @@ const number = new CoreType("number", TypeFlags.Number, v => typeof v === "numbe
|
|
|
5374
5359
|
* })
|
|
5375
5360
|
* ```
|
|
5376
5361
|
*/
|
|
5377
|
-
const integer = new CoreType("integer", TypeFlags.Integer,
|
|
5362
|
+
const integer = new CoreType("integer", TypeFlags.Integer, Number.isInteger);
|
|
5378
5363
|
/**
|
|
5379
5364
|
* `types.float` - Creates a type that can only contain an float value.
|
|
5380
5365
|
*
|
|
@@ -5386,7 +5371,7 @@ const integer = new CoreType("integer", TypeFlags.Integer, v => isInteger(v));
|
|
|
5386
5371
|
* })
|
|
5387
5372
|
* ```
|
|
5388
5373
|
*/
|
|
5389
|
-
const float = new CoreType("float", TypeFlags.Float, v =>
|
|
5374
|
+
const float = new CoreType("float", TypeFlags.Float, v => Number(v) === v && v % 1 !== 0);
|
|
5390
5375
|
/**
|
|
5391
5376
|
* `types.finite` - Creates a type that can only contain an finite value.
|
|
5392
5377
|
*
|
|
@@ -5398,7 +5383,7 @@ const float = new CoreType("float", TypeFlags.Float, v => isFloat(v));
|
|
|
5398
5383
|
* })
|
|
5399
5384
|
* ```
|
|
5400
5385
|
*/
|
|
5401
|
-
const finite = new CoreType("finite", TypeFlags.Finite,
|
|
5386
|
+
const finite = new CoreType("finite", TypeFlags.Finite, Number.isFinite);
|
|
5402
5387
|
/**
|
|
5403
5388
|
* `types.boolean` - Creates a type that can only contain a boolean value.
|
|
5404
5389
|
* This type is used for boolean values by default
|
|
@@ -5459,11 +5444,9 @@ function getPrimitiveFactoryFromValue(value) {
|
|
|
5459
5444
|
/**
|
|
5460
5445
|
* Returns if a given value represents a primitive type.
|
|
5461
5446
|
*
|
|
5462
|
-
*
|
|
5463
|
-
*
|
|
5464
|
-
*
|
|
5465
|
-
* to compile. Guards with a distinct narrowing target (`isArrayType`,
|
|
5466
|
-
* `isMapType`, `isModelType`) keep their predicate.
|
|
5447
|
+
* Like every `isXType` guard it reads the type's flags, which wrappers and
|
|
5448
|
+
* unions inherit from what they hold, so it is also true for a type that wraps
|
|
5449
|
+
* or unions one. Use {@link unwrapType} to get at the type itself.
|
|
5467
5450
|
*
|
|
5468
5451
|
* @param type
|
|
5469
5452
|
* @returns
|
|
@@ -5529,11 +5512,9 @@ function literal(value) {
|
|
|
5529
5512
|
/**
|
|
5530
5513
|
* Returns if a given value represents a literal type.
|
|
5531
5514
|
*
|
|
5532
|
-
*
|
|
5533
|
-
*
|
|
5534
|
-
*
|
|
5535
|
-
* to compile. Guards with a distinct narrowing target (`isArrayType`,
|
|
5536
|
-
* `isMapType`, `isModelType`) keep their predicate.
|
|
5515
|
+
* Like every `isXType` guard it reads the type's flags, which wrappers and
|
|
5516
|
+
* unions inherit from what they hold, so it is also true for a type that wraps
|
|
5517
|
+
* or unions one. Use {@link unwrapType} to get at the type itself.
|
|
5537
5518
|
*
|
|
5538
5519
|
* @param type
|
|
5539
5520
|
* @returns
|
|
@@ -5611,11 +5592,9 @@ function refinement(...args) {
|
|
|
5611
5592
|
/**
|
|
5612
5593
|
* Returns if a given value is a refinement type.
|
|
5613
5594
|
*
|
|
5614
|
-
*
|
|
5615
|
-
*
|
|
5616
|
-
*
|
|
5617
|
-
* to compile. Guards with a distinct narrowing target (`isArrayType`,
|
|
5618
|
-
* `isMapType`, `isModelType`) keep their predicate.
|
|
5595
|
+
* Like every `isXType` guard it reads the type's flags, which wrappers and
|
|
5596
|
+
* unions inherit from what they hold, so it is also true for a type that wraps
|
|
5597
|
+
* or unions one. Use {@link unwrapType} to get at the type itself.
|
|
5619
5598
|
*
|
|
5620
5599
|
* @param type
|
|
5621
5600
|
* @returns
|
|
@@ -5628,6 +5607,10 @@ function isRefinementType(type) {
|
|
|
5628
5607
|
* `types.enumeration` - Can be used to create an string based enumeration.
|
|
5629
5608
|
* (note: this methods is just sugar for a union of string literals)
|
|
5630
5609
|
*
|
|
5610
|
+
* The member type is inferred from the options, so a literal array, an
|
|
5611
|
+
* `as const` array and `Object.values(SomeStringEnum)` all produce the exact
|
|
5612
|
+
* union; only an array already typed `string[]` falls back to `string`.
|
|
5613
|
+
*
|
|
5631
5614
|
* Example:
|
|
5632
5615
|
* ```ts
|
|
5633
5616
|
* const TrafficLight = types.model({
|
|
@@ -5639,52 +5622,47 @@ function isRefinementType(type) {
|
|
|
5639
5622
|
* @param options possible values this enumeration can have
|
|
5640
5623
|
* @returns
|
|
5641
5624
|
*/
|
|
5642
|
-
function enumeration(
|
|
5643
|
-
const
|
|
5644
|
-
|
|
5625
|
+
function enumeration(nameOrOptions, maybeOptions) {
|
|
5626
|
+
const name = typeof nameOrOptions === "string" ? nameOrOptions : undefined;
|
|
5627
|
+
const options = typeof nameOrOptions === "string" ? maybeOptions : nameOrOptions;
|
|
5645
5628
|
if (devMode()) {
|
|
5646
|
-
|
|
5629
|
+
options.forEach((option, i) => {
|
|
5647
5630
|
assertIsString(option, i + 1);
|
|
5648
5631
|
});
|
|
5649
5632
|
}
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
}
|
|
5654
|
-
return type;
|
|
5633
|
+
// built directly rather than through union(): its members are fresh
|
|
5634
|
+
// literals, so interning could never share it, and the name belongs to this
|
|
5635
|
+
// union alone
|
|
5636
|
+
return new Union(options.map(option => literal(`${option}`)), name === undefined ? undefined : { name });
|
|
5655
5637
|
}
|
|
5656
5638
|
|
|
5657
|
-
//
|
|
5658
|
-
//
|
|
5659
|
-
//
|
|
5660
|
-
// members are rarely bare models (jbrowse config schemas
|
|
5661
|
-
// always optional(model) or optional(snapshotProcessor(model))).
|
|
5662
|
-
//
|
|
5663
|
-
//
|
|
5664
|
-
|
|
5665
|
-
// Only *successful* resolutions are cached. A wrapper chain's shape is fixed at
|
|
5666
|
-
// construction, so once a member resolves to a ModelType it always will; but a
|
|
5667
|
-
// `late` member reports no subtype until its definition evaluates, and that
|
|
5668
|
-
// miss must stay retryable.
|
|
5669
|
-
const resolvedModelTypes = new WeakMap();
|
|
5639
|
+
// The model a member is meant for: the one under its wrappers, and for a
|
|
5640
|
+
// `resilient` member the one it tries first. Matching a snapshot to a member
|
|
5641
|
+
// (quick-match dispatch, discriminator scoping) keys on that model's props,
|
|
5642
|
+
// and real-world members are rarely bare models (jbrowse config schemas are
|
|
5643
|
+
// always optional(model) or optional(snapshotProcessor(model))).
|
|
5644
|
+
// Misses are cached too, unless the member holds a `late` type: that has no
|
|
5645
|
+
// subtype until its definition evaluates, so its miss must stay retryable.
|
|
5646
|
+
const intendedModelTypes = new WeakMap();
|
|
5670
5647
|
function resolveModelType(type) {
|
|
5671
|
-
|
|
5672
|
-
|
|
5648
|
+
const cached = intendedModelTypes.get(type);
|
|
5649
|
+
if (cached !== undefined) {
|
|
5650
|
+
return cached ?? undefined;
|
|
5673
5651
|
}
|
|
5674
|
-
const
|
|
5675
|
-
if (
|
|
5676
|
-
|
|
5652
|
+
const model = findIntendedModelType(type);
|
|
5653
|
+
if (model || !(type.flags & TypeFlags.Late)) {
|
|
5654
|
+
intendedModelTypes.set(type, model ?? null);
|
|
5677
5655
|
}
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
const wrapper = current;
|
|
5685
|
-
current = wrapper._subtype ?? wrapper.getSubType?.(false);
|
|
5656
|
+
return model;
|
|
5657
|
+
}
|
|
5658
|
+
function findIntendedModelType(type) {
|
|
5659
|
+
const unwrapped = unwrapType(type);
|
|
5660
|
+
if (unwrapped instanceof ModelType) {
|
|
5661
|
+
return unwrapped;
|
|
5686
5662
|
}
|
|
5687
|
-
return
|
|
5663
|
+
return unwrapped instanceof Resilient
|
|
5664
|
+
? findIntendedModelType(unwrapped.primaryType)
|
|
5665
|
+
: undefined;
|
|
5688
5666
|
}
|
|
5689
5667
|
// The quick-match paths below already know a type carries TypeFlags.Literal,
|
|
5690
5668
|
// but `is()` still routes through BaseType.validate — a context array, an entry
|
|
@@ -5722,13 +5700,17 @@ class Union extends BaseType {
|
|
|
5722
5700
|
if (cached !== undefined) {
|
|
5723
5701
|
return cached;
|
|
5724
5702
|
}
|
|
5703
|
+
const result = this.foldFlags();
|
|
5704
|
+
if (!(result & TypeFlags.Late)) {
|
|
5705
|
+
this._flags = result;
|
|
5706
|
+
}
|
|
5707
|
+
return result;
|
|
5708
|
+
}
|
|
5709
|
+
foldFlags() {
|
|
5725
5710
|
let result = TypeFlags.Union;
|
|
5726
5711
|
for (const type of this.members()) {
|
|
5727
5712
|
result |= type.flags;
|
|
5728
5713
|
}
|
|
5729
|
-
if (!(result & TypeFlags.Late)) {
|
|
5730
|
-
this._flags = result;
|
|
5731
|
-
}
|
|
5732
5714
|
return result;
|
|
5733
5715
|
}
|
|
5734
5716
|
computeName() {
|
|
@@ -6063,11 +6045,7 @@ class DynamicUnion extends Union {
|
|
|
6063
6045
|
return this._members();
|
|
6064
6046
|
}
|
|
6065
6047
|
get flags() {
|
|
6066
|
-
|
|
6067
|
-
for (const type of this.members()) {
|
|
6068
|
-
result |= type.flags;
|
|
6069
|
-
}
|
|
6070
|
-
return result;
|
|
6048
|
+
return this.foldFlags();
|
|
6071
6049
|
}
|
|
6072
6050
|
get name() {
|
|
6073
6051
|
return this._explicitName !== undefined
|
|
@@ -6146,11 +6124,9 @@ function union(...args) {
|
|
|
6146
6124
|
/**
|
|
6147
6125
|
* Returns if a given value represents a union type.
|
|
6148
6126
|
*
|
|
6149
|
-
*
|
|
6150
|
-
*
|
|
6151
|
-
*
|
|
6152
|
-
* to compile. Guards with a distinct narrowing target (`isArrayType`,
|
|
6153
|
-
* `isMapType`, `isModelType`) keep their predicate.
|
|
6127
|
+
* Like every `isXType` guard it reads the type's flags, which wrappers and
|
|
6128
|
+
* unions inherit from what they hold, so it is also true for a type that wraps
|
|
6129
|
+
* or unions one. Use {@link unwrapType} to get at the type itself.
|
|
6154
6130
|
*
|
|
6155
6131
|
* @param type
|
|
6156
6132
|
* @returns
|
|
@@ -6159,13 +6135,9 @@ function isUnionType(type) {
|
|
|
6159
6135
|
return isType(type) && (type.flags & TypeFlags.Union) > 0;
|
|
6160
6136
|
}
|
|
6161
6137
|
/**
|
|
6162
|
-
* Returns the member types of a union
|
|
6163
|
-
*
|
|
6164
|
-
*
|
|
6165
|
-
* the type they wrap, so `isUnionType` is true for e.g. an optional-of-union,
|
|
6166
|
-
* but their `getSubTypes()` reports the single wrapped type rather than the
|
|
6167
|
-
* union's members. This drills through those wrappers until the union's member
|
|
6168
|
-
* array surfaces.
|
|
6138
|
+
* Returns the member types of a union, seeing through the wrappers
|
|
6139
|
+
* {@link unwrapType} does: `isUnionType` is also true for e.g. an
|
|
6140
|
+
* optional-of-union.
|
|
6169
6141
|
*
|
|
6170
6142
|
* @param type a type for which `isUnionType` is true
|
|
6171
6143
|
* @returns the array of member types of the underlying union
|
|
@@ -6174,16 +6146,11 @@ function getUnionSubtypes(type) {
|
|
|
6174
6146
|
if (!isUnionType(type)) {
|
|
6175
6147
|
throw fail("expected a union type");
|
|
6176
6148
|
}
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
subtypes !== null &&
|
|
6180
|
-
!Array.isArray(subtypes)) {
|
|
6181
|
-
subtypes = subtypes.getSubTypes();
|
|
6182
|
-
}
|
|
6183
|
-
if (!Array.isArray(subtypes)) {
|
|
6149
|
+
const union = unwrapType(type);
|
|
6150
|
+
if (!(union instanceof Union)) {
|
|
6184
6151
|
throw fail("could not extract subtypes from union type");
|
|
6185
6152
|
}
|
|
6186
|
-
return
|
|
6153
|
+
return union.getSubTypes();
|
|
6187
6154
|
}
|
|
6188
6155
|
|
|
6189
6156
|
/**
|
|
@@ -6330,11 +6297,9 @@ const undefinedAsOptionalValues = [undefined];
|
|
|
6330
6297
|
/**
|
|
6331
6298
|
* Returns if a value represents an optional type.
|
|
6332
6299
|
*
|
|
6333
|
-
*
|
|
6334
|
-
*
|
|
6335
|
-
*
|
|
6336
|
-
* to compile. Guards with a distinct narrowing target (`isArrayType`,
|
|
6337
|
-
* `isMapType`, `isModelType`) keep their predicate.
|
|
6300
|
+
* Like every `isXType` guard it reads the type's flags, which wrappers and
|
|
6301
|
+
* unions inherit from what they hold, so it is also true for a type that wraps
|
|
6302
|
+
* or unions one. Use {@link unwrapType} to get at the type itself.
|
|
6338
6303
|
*
|
|
6339
6304
|
* @param type
|
|
6340
6305
|
* @returns
|
|
@@ -6345,26 +6310,6 @@ function isOptionalType(type) {
|
|
|
6345
6310
|
function isRecord(value) {
|
|
6346
6311
|
return typeof value === "object" && value !== null;
|
|
6347
6312
|
}
|
|
6348
|
-
/**
|
|
6349
|
-
* The identifier attribute of the model a stripDefault ultimately wraps, or
|
|
6350
|
-
* `null` when there is none. Drills through the single-subtype wrappers the way
|
|
6351
|
-
* `resolveModelType` in union.ts does — that one is module-private there, and
|
|
6352
|
-
* this file may not reach into it.
|
|
6353
|
-
*
|
|
6354
|
-
* `null` is also the answer for an unresolved `types.late`, which only costs the
|
|
6355
|
-
* short-circuit, never correctness: the full structural walk still runs.
|
|
6356
|
-
*/
|
|
6357
|
-
function resolveIdentifierAttribute(type) {
|
|
6358
|
-
let current = type;
|
|
6359
|
-
for (let depth = 0; current && depth < 20; depth++) {
|
|
6360
|
-
if (current instanceof ModelType) {
|
|
6361
|
-
return current.identifierAttribute ? current.identifierAttribute : null;
|
|
6362
|
-
}
|
|
6363
|
-
const wrapper = current;
|
|
6364
|
-
current = wrapper._subtype ?? wrapper.getSubType?.(false);
|
|
6365
|
-
}
|
|
6366
|
-
return null;
|
|
6367
|
-
}
|
|
6368
6313
|
/**
|
|
6369
6314
|
* Compare a child snapshot to a stripped-default's reference snapshot: identity
|
|
6370
6315
|
* for primitives, structural for objects/arrays.
|
|
@@ -6446,7 +6391,10 @@ class StripDefaultValue extends OptionalValue {
|
|
|
6446
6391
|
equalsDefault(snapshot, defaultSnapshot) {
|
|
6447
6392
|
let identifierAttribute = this._identifierAttribute;
|
|
6448
6393
|
if (identifierAttribute === undefined) {
|
|
6449
|
-
|
|
6394
|
+
// null when not wrapping an identified model; an unresolved late member
|
|
6395
|
+
// also lands here, which only costs the short-circuit below
|
|
6396
|
+
identifierAttribute =
|
|
6397
|
+
asModelType(this.getSubTypes())?.identifierAttribute ?? null;
|
|
6450
6398
|
this._identifierAttribute = identifierAttribute;
|
|
6451
6399
|
}
|
|
6452
6400
|
// an identified model's snapshot normally has the same shape as the default
|
|
@@ -6556,16 +6504,14 @@ class Late extends BaseType {
|
|
|
6556
6504
|
}
|
|
6557
6505
|
getSubType(mustSucceed) {
|
|
6558
6506
|
if (!this._subType) {
|
|
6559
|
-
let t
|
|
6507
|
+
let t;
|
|
6560
6508
|
try {
|
|
6561
6509
|
t = this._definition();
|
|
6562
6510
|
}
|
|
6563
6511
|
catch (e) {
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
}
|
|
6568
|
-
else {
|
|
6512
|
+
// a self-referencing definition can read its binding before it is
|
|
6513
|
+
// initialized; that is "not defined yet", like returning undefined
|
|
6514
|
+
if (!(e instanceof ReferenceError)) {
|
|
6569
6515
|
throw e;
|
|
6570
6516
|
}
|
|
6571
6517
|
}
|
|
@@ -6581,10 +6527,15 @@ class Late extends BaseType {
|
|
|
6581
6527
|
}
|
|
6582
6528
|
return this._subType;
|
|
6583
6529
|
}
|
|
6584
|
-
constructor(
|
|
6530
|
+
constructor(_definition, name) {
|
|
6585
6531
|
super(name);
|
|
6586
6532
|
this._definition = _definition;
|
|
6587
6533
|
}
|
|
6534
|
+
// the unnamed form is named after the definition's source text, which is
|
|
6535
|
+
// only worth building if something reads it
|
|
6536
|
+
computeName() {
|
|
6537
|
+
return `late(${this._definition.toString()})`;
|
|
6538
|
+
}
|
|
6588
6539
|
instantiate(parent, subpath, environment, initialValue) {
|
|
6589
6540
|
return this.getSubType(true).instantiate(parent, subpath, environment, initialValue);
|
|
6590
6541
|
}
|
|
@@ -6593,7 +6544,7 @@ class Late extends BaseType {
|
|
|
6593
6544
|
}
|
|
6594
6545
|
describe() {
|
|
6595
6546
|
const t = this.getSubType(false);
|
|
6596
|
-
return t ? t.name : "<
|
|
6547
|
+
return t ? t.name : "<unknown late type>";
|
|
6597
6548
|
}
|
|
6598
6549
|
isValidSnapshot(value, context) {
|
|
6599
6550
|
const t = this.getSubType(false);
|
|
@@ -6608,8 +6559,7 @@ class Late extends BaseType {
|
|
|
6608
6559
|
return t ? t.isAssignableFrom(type) : false;
|
|
6609
6560
|
}
|
|
6610
6561
|
getSubTypes() {
|
|
6611
|
-
|
|
6612
|
-
return subtype ? subtype : cannotDetermineSubtype;
|
|
6562
|
+
return this.getSubType(false) ?? cannotDetermineSubtype;
|
|
6613
6563
|
}
|
|
6614
6564
|
}
|
|
6615
6565
|
/**
|
|
@@ -6629,26 +6579,21 @@ class Late extends BaseType {
|
|
|
6629
6579
|
* @returns
|
|
6630
6580
|
*/
|
|
6631
6581
|
function late(nameOrType, maybeType) {
|
|
6632
|
-
const name = typeof nameOrType === "string"
|
|
6633
|
-
? nameOrType
|
|
6634
|
-
: `late(${nameOrType.toString()})`;
|
|
6582
|
+
const name = typeof nameOrType === "string" ? nameOrType : undefined;
|
|
6635
6583
|
const type = typeof nameOrType === "string" ? maybeType : nameOrType;
|
|
6636
|
-
// checks that the type is actually a late type
|
|
6637
6584
|
if (devMode()) {
|
|
6638
6585
|
if (!(typeof type === "function" && type.length === 0)) {
|
|
6639
6586
|
throw fail(`Invalid late type, expected a function with zero arguments that returns a type, got: ${type}`);
|
|
6640
6587
|
}
|
|
6641
6588
|
}
|
|
6642
|
-
return new Late(
|
|
6589
|
+
return new Late(type, name);
|
|
6643
6590
|
}
|
|
6644
6591
|
/**
|
|
6645
6592
|
* Returns if a given value represents a late type.
|
|
6646
6593
|
*
|
|
6647
|
-
*
|
|
6648
|
-
*
|
|
6649
|
-
*
|
|
6650
|
-
* to compile. Guards with a distinct narrowing target (`isArrayType`,
|
|
6651
|
-
* `isMapType`, `isModelType`) keep their predicate.
|
|
6594
|
+
* Like every `isXType` guard it reads the type's flags, which wrappers and
|
|
6595
|
+
* unions inherit from what they hold, so it is also true for a type that wraps
|
|
6596
|
+
* or unions one. Use {@link unwrapType} to get at the type itself.
|
|
6652
6597
|
*
|
|
6653
6598
|
* @param type
|
|
6654
6599
|
* @returns
|
|
@@ -6658,7 +6603,8 @@ function isLateType(type) {
|
|
|
6658
6603
|
}
|
|
6659
6604
|
|
|
6660
6605
|
function lazy(name, options) {
|
|
6661
|
-
//
|
|
6606
|
+
// a lazy type stands in for the type it loads, down to that type's own
|
|
6607
|
+
// methods (a model's `.props`, say), which the placeholder does not have
|
|
6662
6608
|
return new Lazy(name, options);
|
|
6663
6609
|
}
|
|
6664
6610
|
/**
|
|
@@ -6825,11 +6771,9 @@ function frozen(arg) {
|
|
|
6825
6771
|
/**
|
|
6826
6772
|
* Returns if a given value represents a frozen type.
|
|
6827
6773
|
*
|
|
6828
|
-
*
|
|
6829
|
-
*
|
|
6830
|
-
*
|
|
6831
|
-
* to compile. Guards with a distinct narrowing target (`isArrayType`,
|
|
6832
|
-
* `isMapType`, `isModelType`) keep their predicate.
|
|
6774
|
+
* Like every `isXType` guard it reads the type's flags, which wrappers and
|
|
6775
|
+
* unions inherit from what they hold, so it is also true for a type that wraps
|
|
6776
|
+
* or unions one. Use {@link unwrapType} to get at the type itself.
|
|
6833
6777
|
*
|
|
6834
6778
|
* @param type
|
|
6835
6779
|
* @returns
|
|
@@ -6973,9 +6917,10 @@ class BaseReferenceType extends SimpleType {
|
|
|
6973
6917
|
return undefined;
|
|
6974
6918
|
}
|
|
6975
6919
|
const refTargetNode = getStateTreeNode(refTargetValue);
|
|
6976
|
-
const hookHandler = (
|
|
6920
|
+
const hookHandler = (subject, refTargetNodeHook) => {
|
|
6977
6921
|
const cause = getInvalidationCause(refTargetNodeHook);
|
|
6978
|
-
|
|
6922
|
+
// a reference detached along with its target still resolves it
|
|
6923
|
+
if (!cause || (cause === "detach" && storedRefNode.isWithin(subject))) {
|
|
6979
6924
|
return;
|
|
6980
6925
|
}
|
|
6981
6926
|
this.fireInvalidated(cause, storedRefNode, referenceId, refTargetNode);
|
|
@@ -7173,11 +7118,9 @@ function reference(subType, options) {
|
|
|
7173
7118
|
/**
|
|
7174
7119
|
* Returns if a given value represents a reference type.
|
|
7175
7120
|
*
|
|
7176
|
-
*
|
|
7177
|
-
*
|
|
7178
|
-
*
|
|
7179
|
-
* to compile. Guards with a distinct narrowing target (`isArrayType`,
|
|
7180
|
-
* `isMapType`, `isModelType`) keep their predicate.
|
|
7121
|
+
* Like every `isXType` guard it reads the type's flags, which wrappers and
|
|
7122
|
+
* unions inherit from what they hold, so it is also true for a type that wraps
|
|
7123
|
+
* or unions one. Use {@link unwrapType} to get at the type itself.
|
|
7181
7124
|
*
|
|
7182
7125
|
* @param type
|
|
7183
7126
|
* @returns
|
|
@@ -7302,11 +7245,9 @@ const identifierNumber = new IdentifierNumberType();
|
|
|
7302
7245
|
/**
|
|
7303
7246
|
* Returns if a given value represents an identifier type.
|
|
7304
7247
|
*
|
|
7305
|
-
*
|
|
7306
|
-
*
|
|
7307
|
-
*
|
|
7308
|
-
* to compile. Guards with a distinct narrowing target (`isArrayType`,
|
|
7309
|
-
* `isMapType`, `isModelType`) keep their predicate.
|
|
7248
|
+
* Like every `isXType` guard it reads the type's flags, which wrappers and
|
|
7249
|
+
* unions inherit from what they hold, so it is also true for a type that wraps
|
|
7250
|
+
* or unions one. Use {@link unwrapType} to get at the type itself.
|
|
7310
7251
|
*
|
|
7311
7252
|
* @param type
|
|
7312
7253
|
* @returns
|
|
@@ -7437,6 +7378,10 @@ class CustomType extends SimpleType {
|
|
|
7437
7378
|
}
|
|
7438
7379
|
}
|
|
7439
7380
|
|
|
7381
|
+
/**
|
|
7382
|
+
* @internal
|
|
7383
|
+
* @hidden
|
|
7384
|
+
*/
|
|
7440
7385
|
class Resilient extends BaseType {
|
|
7441
7386
|
_subtype;
|
|
7442
7387
|
_fallbackType;
|
|
@@ -7444,6 +7389,10 @@ class Resilient extends BaseType {
|
|
|
7444
7389
|
get flags() {
|
|
7445
7390
|
return this._subtype.flags;
|
|
7446
7391
|
}
|
|
7392
|
+
/** the type tried first; the fallback takes over only when it fails */
|
|
7393
|
+
get primaryType() {
|
|
7394
|
+
return this._subtype;
|
|
7395
|
+
}
|
|
7447
7396
|
constructor(_subtype, _fallbackType, _createFallbackSnapshot) {
|
|
7448
7397
|
super();
|
|
7449
7398
|
this._subtype = _subtype;
|
|
@@ -7599,5 +7548,5 @@ const types = {
|
|
|
7599
7548
|
resilient
|
|
7600
7549
|
};
|
|
7601
7550
|
|
|
7602
|
-
export { addDisposer, addMiddleware, applyAction, applyPatch, applySnapshot, cannotDetermineSubtype, cast, castFlowReturn, castToReferenceSnapshot, castToSnapshot, clone, createActionTrackingMiddleware, createActionTrackingMiddleware2, decorate, destroy, detach, escapeJsonPath, extendInstance, flow, getChildType, getEnv, getIdentifier, getLivelinessChecking, getMembers, getNodeId, getParent, getParentOfType, getPath, getPathParts, getPropertyMembers, getRelativePath, getRoot, getRunningActionContext, getSnapshot, getType, getUnionSubtypes, hasParent, hasParentOfType, isActionContextChildOf, isActionContextThisOrChildOf, isAlive, isArrayType, isFrozenType, isIdentifierType, isLateType, isLiteralType, isMapType, isModelType, isOptionalType, isPrimitiveType, isProtected, isReferenceType, isRefinementType, isRoot, isStateTreeNode, isType, isUnionType, isValidReference, joinJsonPath, onAction, onPatch, onSnapshot, protect, recordActions, recordPatches, resolveIdentifier, resolvePath, setDevMode, setLivelinessChecking, setLivelynessChecking, setTypeChecking, splitJsonPath, types as t, toGenerator, toGeneratorFunction, tryReference, tryResolve, typecheck, types, unescapeJsonPath, unprotect, walk };
|
|
7551
|
+
export { addDisposer, addMiddleware, applyAction, applyPatch, applySnapshot, asArrayType, asMapType, asModelType, cannotDetermineSubtype, cast, castFlowReturn, castToReferenceSnapshot, castToSnapshot, clone, createActionTrackingMiddleware, createActionTrackingMiddleware2, decorate, destroy, detach, escapeJsonPath, extendInstance, flow, getChildType, getEnv, getIdentifier, getLivelinessChecking, getMembers, getNodeId, getParent, getParentOfType, getPath, getPathParts, getPropertyMembers, getRelativePath, getRoot, getRunningActionContext, getSnapshot, getType, getUnionSubtypes, getWrappedType, hasParent, hasParentOfType, isActionContextChildOf, isActionContextThisOrChildOf, isAlive, isArrayType, isFrozenType, isIdentifierType, isLateType, isLiteralType, isMapType, isModelType, isOptionalType, isPrimitiveType, isProtected, isReferenceType, isRefinementType, isRoot, isStateTreeNode, isType, isUnionType, isValidReference, joinJsonPath, onAction, onPatch, onSnapshot, protect, recordActions, recordPatches, resolveIdentifier, resolvePath, setDevMode, setLivelinessChecking, setLivelynessChecking, setTypeChecking, splitJsonPath, types as t, toGenerator, toGeneratorFunction, tryReference, tryResolve, typecheck, types, unescapeJsonPath, unprotect, unwrapType, walk };
|
|
7603
7552
|
//# sourceMappingURL=mobx-state-tree.mjs.map
|