@jbrowse/mobx-state-tree 6.4.0 → 6.5.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/index.d.ts +5 -0
- package/dist/mobx-state-tree.cjs +106 -20
- package/dist/mobx-state-tree.cjs.map +1 -1
- package/dist/mobx-state-tree.mjs +106 -20
- package/dist/mobx-state-tree.mjs.map +1 -1
- package/package.json +3 -1
package/dist/mobx-state-tree.mjs
CHANGED
|
@@ -5723,7 +5723,7 @@ class Union extends BaseType {
|
|
|
5723
5723
|
return cached;
|
|
5724
5724
|
}
|
|
5725
5725
|
let result = TypeFlags.Union;
|
|
5726
|
-
for (const type of this.
|
|
5726
|
+
for (const type of this.members()) {
|
|
5727
5727
|
result |= type.flags;
|
|
5728
5728
|
}
|
|
5729
5729
|
if (!(result & TypeFlags.Late)) {
|
|
@@ -5732,12 +5732,14 @@ class Union extends BaseType {
|
|
|
5732
5732
|
return result;
|
|
5733
5733
|
}
|
|
5734
5734
|
computeName() {
|
|
5735
|
-
return `(${this.
|
|
5735
|
+
return `(${this.members()
|
|
5736
|
+
.map(type => type.name)
|
|
5737
|
+
.join(" | ")})`;
|
|
5736
5738
|
}
|
|
5737
5739
|
constructor(_types, options) {
|
|
5738
5740
|
super();
|
|
5739
5741
|
this._types = _types;
|
|
5740
|
-
// read the
|
|
5742
|
+
// read the options directly rather than spreading defaults into a fresh
|
|
5741
5743
|
// object: this constructor runs once per config slot in jbrowse, and the
|
|
5742
5744
|
// merged object was allocated only to be read twice and dropped
|
|
5743
5745
|
if (options !== undefined) {
|
|
@@ -5747,13 +5749,23 @@ class Union extends BaseType {
|
|
|
5747
5749
|
if (options.eager === false) {
|
|
5748
5750
|
this._eager = false;
|
|
5749
5751
|
}
|
|
5752
|
+
if (options.name !== undefined) {
|
|
5753
|
+
this.name = options.name;
|
|
5754
|
+
}
|
|
5750
5755
|
}
|
|
5751
5756
|
}
|
|
5757
|
+
// The one point membership is read through, so DynamicUnion can substitute
|
|
5758
|
+
// its thunk without duplicating any of the scanning logic below.
|
|
5759
|
+
members() {
|
|
5760
|
+
return this._types;
|
|
5761
|
+
}
|
|
5752
5762
|
isAssignableFrom(type) {
|
|
5753
|
-
return this.
|
|
5763
|
+
return this.members().some(subType => subType.isAssignableFrom(type));
|
|
5754
5764
|
}
|
|
5755
5765
|
describe() {
|
|
5756
|
-
return `(${this.
|
|
5766
|
+
return `(${this.members()
|
|
5767
|
+
.map(factory => factory.describe())
|
|
5768
|
+
.join(" | ")})`;
|
|
5757
5769
|
}
|
|
5758
5770
|
instantiate(parent, subpath, environment, initialValue) {
|
|
5759
5771
|
const type = this.determineType(initialValue, undefined);
|
|
@@ -5808,7 +5820,7 @@ class Union extends BaseType {
|
|
|
5808
5820
|
}
|
|
5809
5821
|
_scanForTypeDiscriminator(discriminator) {
|
|
5810
5822
|
let found;
|
|
5811
|
-
for (const t of this.
|
|
5823
|
+
for (const t of this.members()) {
|
|
5812
5824
|
const model = resolveModelType(t);
|
|
5813
5825
|
if (!model) {
|
|
5814
5826
|
continue;
|
|
@@ -5833,15 +5845,18 @@ class Union extends BaseType {
|
|
|
5833
5845
|
}
|
|
5834
5846
|
allMembersDiscriminated() {
|
|
5835
5847
|
if (this._allMembersDiscriminated === undefined) {
|
|
5836
|
-
this._allMembersDiscriminated = this.
|
|
5837
|
-
const model = resolveModelType(t);
|
|
5838
|
-
const typeProp = model &&
|
|
5839
|
-
model.properties["type"];
|
|
5840
|
-
return !!typeProp && (typeProp.flags & TypeFlags.Literal) !== 0;
|
|
5841
|
-
});
|
|
5848
|
+
this._allMembersDiscriminated = this.computeAllMembersDiscriminated();
|
|
5842
5849
|
}
|
|
5843
5850
|
return this._allMembersDiscriminated;
|
|
5844
5851
|
}
|
|
5852
|
+
computeAllMembersDiscriminated() {
|
|
5853
|
+
return this.members().every(t => {
|
|
5854
|
+
const model = resolveModelType(t);
|
|
5855
|
+
const typeProp = model &&
|
|
5856
|
+
model.properties["type"];
|
|
5857
|
+
return !!typeProp && (typeProp.flags & TypeFlags.Literal) !== 0;
|
|
5858
|
+
});
|
|
5859
|
+
}
|
|
5845
5860
|
determineType(value, reconcileCurrentType) {
|
|
5846
5861
|
// try the dispatcher, if defined
|
|
5847
5862
|
if (this._dispatcher) {
|
|
@@ -5862,9 +5877,9 @@ class Union extends BaseType {
|
|
|
5862
5877
|
if (reconcileCurrentType.is(value)) {
|
|
5863
5878
|
return reconcileCurrentType;
|
|
5864
5879
|
}
|
|
5865
|
-
return this.
|
|
5880
|
+
return this.members().find(type => type !== reconcileCurrentType && type.is(value));
|
|
5866
5881
|
}
|
|
5867
|
-
return this.
|
|
5882
|
+
return this.members().find(type => type.is(value));
|
|
5868
5883
|
}
|
|
5869
5884
|
tryQuickMatch(value, reconcileCurrentType) {
|
|
5870
5885
|
// state tree nodes need full type compatibility checking
|
|
@@ -5884,7 +5899,7 @@ class Union extends BaseType {
|
|
|
5884
5899
|
this.snapshotLooksLikeType(value, reconcileCurrentType)) {
|
|
5885
5900
|
return reconcileCurrentType;
|
|
5886
5901
|
}
|
|
5887
|
-
for (const type of this.
|
|
5902
|
+
for (const type of this.members()) {
|
|
5888
5903
|
if (type !== reconcileCurrentType &&
|
|
5889
5904
|
this.snapshotLooksLikeType(value, type)) {
|
|
5890
5905
|
return type;
|
|
@@ -5894,7 +5909,7 @@ class Union extends BaseType {
|
|
|
5894
5909
|
}
|
|
5895
5910
|
tryMatchPrimitive(value) {
|
|
5896
5911
|
const valueType = typeof value;
|
|
5897
|
-
for (const type of this.
|
|
5912
|
+
for (const type of this.members()) {
|
|
5898
5913
|
const flags = type.flags;
|
|
5899
5914
|
if ((valueType === "string" && flags & TypeFlags.String) ||
|
|
5900
5915
|
(valueType === "number" &&
|
|
@@ -5981,10 +5996,11 @@ class Union extends BaseType {
|
|
|
5981
5996
|
// for plain-object snapshots, prefer union members whose literal-typed
|
|
5982
5997
|
// discriminator properties match the value (e.g. {type: "MsaView"})
|
|
5983
5998
|
// so error output is scoped to the intended branch instead of every member
|
|
5999
|
+
const members = this.members();
|
|
5984
6000
|
const candidates = isSnapshotObject
|
|
5985
|
-
?
|
|
6001
|
+
? members.filter(t => this.snapshotLooksLikeType(value, t))
|
|
5986
6002
|
: [];
|
|
5987
|
-
const typesToValidate = candidates.length > 0 ? candidates :
|
|
6003
|
+
const typesToValidate = candidates.length > 0 ? candidates : members;
|
|
5988
6004
|
const allErrors = [];
|
|
5989
6005
|
let applicableTypes = 0;
|
|
5990
6006
|
for (const type of typesToValidate) {
|
|
@@ -6007,7 +6023,7 @@ class Union extends BaseType {
|
|
|
6007
6023
|
return typeCheckFailure(context, value, "No type is applicable for the union").concat(allErrors.flat());
|
|
6008
6024
|
}
|
|
6009
6025
|
getSubTypes() {
|
|
6010
|
-
return this.
|
|
6026
|
+
return this.members();
|
|
6011
6027
|
}
|
|
6012
6028
|
}
|
|
6013
6029
|
// Defaults shared by every union; see the field declarations at the top of the
|
|
@@ -6018,6 +6034,56 @@ Object.assign(Union.prototype, {
|
|
|
6018
6034
|
_discriminatorCache: undefined,
|
|
6019
6035
|
_allMembersDiscriminated: undefined
|
|
6020
6036
|
});
|
|
6037
|
+
/**
|
|
6038
|
+
* @internal
|
|
6039
|
+
* @hidden
|
|
6040
|
+
*
|
|
6041
|
+
* A union whose membership is read fresh from a thunk on every operation, so
|
|
6042
|
+
* members that come into existence after the union was built — a registry of
|
|
6043
|
+
* pluggable types whose modules load on demand — still dispatch, validate, and
|
|
6044
|
+
* satisfy references. That last one is the reason this exists: reference
|
|
6045
|
+
* resolution asks the target type `isAssignableFrom(node.type)` through the
|
|
6046
|
+
* identifier cache, and a membership list frozen at construction would reject
|
|
6047
|
+
* every late-loaded member's instances.
|
|
6048
|
+
*
|
|
6049
|
+
* Every membership-derived cache the base class keeps is bypassed here: flags
|
|
6050
|
+
* and the folded name are recomputed per read, and the discriminator scan is
|
|
6051
|
+
* uncached so a miss stays retryable once the missing member registers. A hit
|
|
6052
|
+
* for a given discriminator is assumed stable — registering two members with
|
|
6053
|
+
* the same `type` literal at different times can leave a stale unambiguous
|
|
6054
|
+
* answer where the base class would have reported ambiguity.
|
|
6055
|
+
*/
|
|
6056
|
+
class DynamicUnion extends Union {
|
|
6057
|
+
_members;
|
|
6058
|
+
constructor(members, options) {
|
|
6059
|
+
super([], options);
|
|
6060
|
+
this._members = members;
|
|
6061
|
+
}
|
|
6062
|
+
members() {
|
|
6063
|
+
return this._members();
|
|
6064
|
+
}
|
|
6065
|
+
get flags() {
|
|
6066
|
+
let result = TypeFlags.Union;
|
|
6067
|
+
for (const type of this.members()) {
|
|
6068
|
+
result |= type.flags;
|
|
6069
|
+
}
|
|
6070
|
+
return result;
|
|
6071
|
+
}
|
|
6072
|
+
get name() {
|
|
6073
|
+
return this._explicitName !== undefined
|
|
6074
|
+
? this._explicitName
|
|
6075
|
+
: this.computeName();
|
|
6076
|
+
}
|
|
6077
|
+
set name(value) {
|
|
6078
|
+
this._explicitName = value;
|
|
6079
|
+
}
|
|
6080
|
+
_findCandidateByTypeDiscriminator(discriminator) {
|
|
6081
|
+
return this._scanForTypeDiscriminator(discriminator);
|
|
6082
|
+
}
|
|
6083
|
+
allMembersDiscriminated() {
|
|
6084
|
+
return this.computeAllMembersDiscriminated();
|
|
6085
|
+
}
|
|
6086
|
+
}
|
|
6021
6087
|
const unionInternRoot = {};
|
|
6022
6088
|
function internUnion(types) {
|
|
6023
6089
|
let node = unionInternRoot;
|
|
@@ -6037,6 +6103,13 @@ function internUnion(types) {
|
|
|
6037
6103
|
/**
|
|
6038
6104
|
* `types.union` - Create a union of multiple types. If the correct type cannot be inferred unambiguously from a snapshot, provide a dispatcher function of the form `(snapshot) => Type`.
|
|
6039
6105
|
*
|
|
6106
|
+
* Passing `members: () => Type[]` in the options (with no positional member
|
|
6107
|
+
* types) creates a union whose membership is re-read from the thunk on every
|
|
6108
|
+
* operation, so types registered after construction — e.g. from a lazily
|
|
6109
|
+
* loaded module — participate in dispatch, validation and reference
|
|
6110
|
+
* resolution. Pair it with a `dispatcher` for snapshot dispatch and a `name`
|
|
6111
|
+
* for stable error messages.
|
|
6112
|
+
*
|
|
6040
6113
|
* @param optionsOrType
|
|
6041
6114
|
* @param otherTypes
|
|
6042
6115
|
* @returns
|
|
@@ -6056,12 +6129,18 @@ function union(...args) {
|
|
|
6056
6129
|
// check all options
|
|
6057
6130
|
if (devMode()) {
|
|
6058
6131
|
if (options) {
|
|
6059
|
-
assertArg(options, o => isPlainObject(o), "object { eager?: boolean, dispatcher?: Function }", 1);
|
|
6132
|
+
assertArg(options, o => isPlainObject(o), "object { eager?: boolean, dispatcher?: Function, members?: Function, name?: string }", 1);
|
|
6060
6133
|
}
|
|
6061
6134
|
types.forEach((type, i) => {
|
|
6062
6135
|
assertIsType(type, options ? i + 2 : i + 1);
|
|
6063
6136
|
});
|
|
6064
6137
|
}
|
|
6138
|
+
if (options?.members !== undefined) {
|
|
6139
|
+
if (types.length > 0) {
|
|
6140
|
+
throw fail("union(): the members option cannot be combined with positional member types");
|
|
6141
|
+
}
|
|
6142
|
+
return new DynamicUnion(options.members, options);
|
|
6143
|
+
}
|
|
6065
6144
|
return options === undefined ? internUnion(types) : new Union(types, options);
|
|
6066
6145
|
}
|
|
6067
6146
|
/**
|
|
@@ -6646,6 +6725,13 @@ class Lazy extends SimpleType {
|
|
|
6646
6725
|
}
|
|
6647
6726
|
reconcile(current, value, parent, subpath) {
|
|
6648
6727
|
if (this.loadedType) {
|
|
6728
|
+
// a node created after load carries the loaded type: let it reconcile so
|
|
6729
|
+
// the instance survives applySnapshot instead of dying on every write
|
|
6730
|
+
const loaded = this.loadedType;
|
|
6731
|
+
const currentType = current.type;
|
|
6732
|
+
if (currentType === loaded) {
|
|
6733
|
+
return this.loadedType.reconcile(current, value, parent, subpath);
|
|
6734
|
+
}
|
|
6649
6735
|
current.die();
|
|
6650
6736
|
return this.loadedType.instantiate(parent, subpath, parent.environment, value);
|
|
6651
6737
|
}
|