@jbrowse/mobx-state-tree 5.11.1 → 5.11.2
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/README.md +85 -12
- package/dist/index.d.ts +1 -47
- package/dist/mobx-state-tree.cjs +79 -84
- package/dist/mobx-state-tree.cjs.map +1 -1
- package/dist/mobx-state-tree.mjs +80 -84
- package/dist/mobx-state-tree.mjs.map +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -16,6 +16,79 @@ documents only the additions and changes made in this fork.
|
|
|
16
16
|
exported string-keyed brand interfaces (`$EmptyObjectBrand`, `$__mstStateTreeNodeType__`),
|
|
17
17
|
fixing tsgo TS4058/TS4023 errors when MST types appear in exported function return types
|
|
18
18
|
|
|
19
|
+
## Error message changes
|
|
20
|
+
|
|
21
|
+
Validation and conversion errors have been reworked to stay readable on large state
|
|
22
|
+
trees. Upstream MST could throw error messages hundreds of kilobytes long because it
|
|
23
|
+
expanded every union member's full structure and stringified entire snapshots unbounded.
|
|
24
|
+
This fork keeps the errors short while making them more diagnosable.
|
|
25
|
+
|
|
26
|
+
### Bounded conversion errors
|
|
27
|
+
|
|
28
|
+
`typecheck()` / instantiation errors no longer dump unbounded output:
|
|
29
|
+
|
|
30
|
+
- Stringified snapshots are depth-bound (nested objects past 3 levels collapse to `…`)
|
|
31
|
+
- Each printed value is capped in length
|
|
32
|
+
- At most 10 individual errors are reported, with a `(… and N more errors)` suffix
|
|
33
|
+
|
|
34
|
+
### Scoped discriminated-union errors
|
|
35
|
+
|
|
36
|
+
Take a union of view types discriminated by a literal `type` property:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
const LinearGenomeView = types.model("LinearGenomeView", {
|
|
40
|
+
type: types.literal("LinearGenomeView"),
|
|
41
|
+
height: types.number,
|
|
42
|
+
assembly: types.string
|
|
43
|
+
})
|
|
44
|
+
const DotplotView = types.model("DotplotView", {
|
|
45
|
+
type: types.literal("DotplotView"),
|
|
46
|
+
height: types.number
|
|
47
|
+
})
|
|
48
|
+
const AnyView = types.union(LinearGenomeView, DotplotView)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Upstream MST listed every member's full structure on any failure. A single mistyped field
|
|
52
|
+
produced output like this — each member's entire schema expanded inline, repeated for every
|
|
53
|
+
member, often hundreds of kilobytes on a real config union:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
No matching type for union(LinearGenomeView | DotplotView)
|
|
57
|
+
(snapshot `{"type":"LinearGenomeView","height":"tall","assembly":"hg38"}` is not assignable
|
|
58
|
+
to type: `({ type: ("LinearGenomeView" | snapshot like `"LinearGenomeView"`); height: number;
|
|
59
|
+
assembly: string } | { type: ("DotplotView" | snapshot like `"DotplotView"`); height: number })`,
|
|
60
|
+
expected an instance of `LinearGenomeView` or a snapshot like `{ type: ("LinearGenomeView" |
|
|
61
|
+
snapshot like `"LinearGenomeView"`); height: number; assembly: string }` instead. … )
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Now the error is scoped to the single member whose literal `type` matches the snapshot's
|
|
65
|
+
discriminator, and reports only the property-level reasons it failed.
|
|
66
|
+
|
|
67
|
+
`AnyView.create({ type: "LinearGenomeView", height: "tall", assembly: "hg38" })` throws:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
[mobx-state-tree] Error while converting `{"type":"LinearGenomeView","height":"tall","assembly":"hg38"}` to `(LinearGenomeView | DotplotView)`:
|
|
71
|
+
|
|
72
|
+
at path "/height" value `"tall"` is not assignable to type: `number` (Value is not a number).
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
And in production builds (where full type-checking is skipped) a missing required field on a
|
|
76
|
+
recognized member still names the discriminator and the offending path —
|
|
77
|
+
`AnyView.create({ type: "LinearGenomeView", height: 100 })` throws:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
[mobx-state-tree] No matching type for union (LinearGenomeView | DotplotView) for snapshot with type "LinearGenomeView":
|
|
81
|
+
at path "/assembly" value `undefined` is not assignable to type: `string` (Value is not a string).
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Instead of a wall of text covering every union member, you get the discriminator that was
|
|
85
|
+
seen plus the property-level reasons that one intended member rejected the snapshot (wrong
|
|
86
|
+
field type, missing required field, etc.). The scoping drills through wrapped members
|
|
87
|
+
(`optional`, `refinement`, `snapshotProcessor`, `late`) to find the underlying model, so
|
|
88
|
+
real-world members like an `optional(model)` config schema are still matched correctly.
|
|
89
|
+
When two members declare the same `type` literal (ambiguous), it falls back to the short
|
|
90
|
+
message rather than guessing.
|
|
91
|
+
|
|
19
92
|
## Added APIs
|
|
20
93
|
|
|
21
94
|
### `types.resilient`
|
|
@@ -28,12 +101,12 @@ crashing the entire state tree.
|
|
|
28
101
|
const PluginWidget = types.resilient(
|
|
29
102
|
KnownWidget,
|
|
30
103
|
UnknownWidget,
|
|
31
|
-
(error, originalSnapshot) => ({ kind: "unknown", raw: originalSnapshot })
|
|
104
|
+
(error, originalSnapshot) => ({ kind: "unknown", raw: originalSnapshot })
|
|
32
105
|
)
|
|
33
106
|
|
|
34
107
|
// Arrays of plugins stay alive even if one entry is unrecognized
|
|
35
108
|
const Store = types.model({
|
|
36
|
-
widgets: types.array(PluginWidget)
|
|
109
|
+
widgets: types.array(PluginWidget)
|
|
37
110
|
})
|
|
38
111
|
```
|
|
39
112
|
|
|
@@ -66,11 +139,11 @@ creating a model:
|
|
|
66
139
|
|
|
67
140
|
```ts
|
|
68
141
|
const Settings = types.model({
|
|
69
|
-
theme: types.optional(types.string, "light")
|
|
142
|
+
theme: types.optional(types.string, "light")
|
|
70
143
|
})
|
|
71
144
|
|
|
72
|
-
const s = Settings.create()
|
|
73
|
-
getSnapshot(s)
|
|
145
|
+
const s = Settings.create() // theme is "light"
|
|
146
|
+
getSnapshot(s) // { theme: "light" }
|
|
74
147
|
```
|
|
75
148
|
|
|
76
149
|
Even though `"light"` is just the default, it always appears in the snapshot. If you store
|
|
@@ -84,17 +157,17 @@ equals the default:
|
|
|
84
157
|
|
|
85
158
|
```ts
|
|
86
159
|
const Settings = types.model({
|
|
87
|
-
theme: types.stripDefault(types.string, "light")
|
|
160
|
+
theme: types.stripDefault(types.string, "light")
|
|
88
161
|
})
|
|
89
162
|
|
|
90
163
|
const s = Settings.create()
|
|
91
|
-
getSnapshot(s)
|
|
164
|
+
getSnapshot(s) // {} ← key omitted because value equals default
|
|
92
165
|
|
|
93
166
|
s.theme = "dark"
|
|
94
|
-
getSnapshot(s)
|
|
167
|
+
getSnapshot(s) // { theme: "dark" }
|
|
95
168
|
|
|
96
169
|
s.theme = "light"
|
|
97
|
-
getSnapshot(s)
|
|
170
|
+
getSnapshot(s) // {} ← omitted again
|
|
98
171
|
```
|
|
99
172
|
|
|
100
173
|
#### Why this matters
|
|
@@ -132,7 +205,7 @@ ignored (all children share one element type).
|
|
|
132
205
|
const Box = types.model({ x: types.number, y: types.number })
|
|
133
206
|
const box = Box.create({ x: 1, y: 2 })
|
|
134
207
|
|
|
135
|
-
getChildType(box, "x").name
|
|
208
|
+
getChildType(box, "x").name // "number"
|
|
136
209
|
```
|
|
137
210
|
|
|
138
211
|
**`getUnionSubtypes(type)`** — given a `types.union` type, returns the array of its member
|
|
@@ -141,7 +214,7 @@ types. Useful when you need to enumerate what a union can hold.
|
|
|
141
214
|
```ts
|
|
142
215
|
const Shape = types.union(Circle, Square, Triangle)
|
|
143
216
|
|
|
144
|
-
getUnionSubtypes(Shape)
|
|
217
|
+
getUnionSubtypes(Shape) // [Circle, Square, Triangle]
|
|
145
218
|
```
|
|
146
219
|
|
|
147
220
|
**`getDefaultInstanceOrSnapshot(optionalType)`** — returns the default value (or snapshot)
|
|
@@ -151,5 +224,5 @@ default without having to create a model instance.
|
|
|
151
224
|
```ts
|
|
152
225
|
const t = types.optional(types.string, "hello")
|
|
153
226
|
|
|
154
|
-
t.getDefaultInstanceOrSnapshot()
|
|
227
|
+
t.getDefaultInstanceOrSnapshot() // "hello"
|
|
155
228
|
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1284,52 +1284,6 @@ interface IAnyStateTreeNode extends STNValue<any, IAnyType> {
|
|
|
1284
1284
|
*/
|
|
1285
1285
|
declare function isStateTreeNode<IT extends IAnyComplexType = IAnyComplexType>(value: any): value is STNValue<Instance<IT>, IT>;
|
|
1286
1286
|
|
|
1287
|
-
/**
|
|
1288
|
-
* @deprecated has been renamed to `flow()`.
|
|
1289
|
-
* @hidden
|
|
1290
|
-
*/
|
|
1291
|
-
declare function process<R>(generator: () => IterableIterator<any>): () => Promise<R>;
|
|
1292
|
-
/**
|
|
1293
|
-
* @deprecated has been renamed to `flow()`.
|
|
1294
|
-
* @hidden
|
|
1295
|
-
*/
|
|
1296
|
-
declare function process<A1>(generator: (a1: A1) => IterableIterator<any>): (a1: A1) => Promise<any>;
|
|
1297
|
-
/**
|
|
1298
|
-
* @deprecated has been renamed to `flow()`.
|
|
1299
|
-
* @hidden
|
|
1300
|
-
*/
|
|
1301
|
-
declare function process<A1, A2>(generator: (a1: A1, a2: A2) => IterableIterator<any>): (a1: A1, a2: A2) => Promise<any>;
|
|
1302
|
-
/**
|
|
1303
|
-
* @deprecated has been renamed to `flow()`.
|
|
1304
|
-
* @hidden
|
|
1305
|
-
*/
|
|
1306
|
-
declare function process<A1, A2, A3>(generator: (a1: A1, a2: A2, a3: A3) => IterableIterator<any>): (a1: A1, a2: A2, a3: A3) => Promise<any>;
|
|
1307
|
-
/**
|
|
1308
|
-
* @deprecated has been renamed to `flow()`.
|
|
1309
|
-
* @hidden
|
|
1310
|
-
*/
|
|
1311
|
-
declare function process<A1, A2, A3, A4>(generator: (a1: A1, a2: A2, a3: A3, a4: A4) => IterableIterator<any>): (a1: A1, a2: A2, a3: A3, a4: A4) => Promise<any>;
|
|
1312
|
-
/**
|
|
1313
|
-
* @deprecated has been renamed to `flow()`.
|
|
1314
|
-
* @hidden
|
|
1315
|
-
*/
|
|
1316
|
-
declare function process<A1, A2, A3, A4, A5>(generator: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => IterableIterator<any>): (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => Promise<any>;
|
|
1317
|
-
/**
|
|
1318
|
-
* @deprecated has been renamed to `flow()`.
|
|
1319
|
-
* @hidden
|
|
1320
|
-
*/
|
|
1321
|
-
declare function process<A1, A2, A3, A4, A5, A6>(generator: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6) => IterableIterator<any>): (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6) => Promise<any>;
|
|
1322
|
-
/**
|
|
1323
|
-
* @deprecated has been renamed to `flow()`.
|
|
1324
|
-
* @hidden
|
|
1325
|
-
*/
|
|
1326
|
-
declare function process<A1, A2, A3, A4, A5, A6, A7>(generator: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7) => IterableIterator<any>): (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7) => Promise<any>;
|
|
1327
|
-
/**
|
|
1328
|
-
* @deprecated has been renamed to `flow()`.
|
|
1329
|
-
* @hidden
|
|
1330
|
-
*/
|
|
1331
|
-
declare function process<A1, A2, A3, A4, A5, A6, A7, A8>(generator: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7, a8: A8) => IterableIterator<any>): (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7, a8: A8) => Promise<any>;
|
|
1332
|
-
|
|
1333
1287
|
/**
|
|
1334
1288
|
* @hidden
|
|
1335
1289
|
*/
|
|
@@ -2185,5 +2139,5 @@ declare const types: {
|
|
|
2185
2139
|
resilient: typeof resilient;
|
|
2186
2140
|
};
|
|
2187
2141
|
|
|
2188
|
-
export { addDisposer, addMiddleware, applyAction, applyPatch, applySnapshot, cast, castFlowReturn, castToReferenceSnapshot, castToSnapshot, clone, createActionTrackingMiddleware, createActionTrackingMiddleware2, decorate, destroy, detach, escapeJsonPath, 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,
|
|
2142
|
+
export { addDisposer, addMiddleware, applyAction, applyPatch, applySnapshot, cast, castFlowReturn, castToReferenceSnapshot, castToSnapshot, clone, createActionTrackingMiddleware, createActionTrackingMiddleware2, decorate, destroy, detach, escapeJsonPath, 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 };
|
|
2189
2143
|
export type { $EmptyObjectBrand, CustomTypeOptions, IActionContext, IActionRecorder, IActionTrackingMiddleware2Call, IActionTrackingMiddleware2Hooks, IActionTrackingMiddlewareHooks, IAnyComplexType, IAnyModelType, IAnyStateTreeNode, IAnyType, IArrayType, IComplexType, IDisposer, IJsonPatch, IMSTArray, IMSTMap, IMapType, IMaybe, IMaybeIType, IMaybeNull, IMiddlewareEvent, IMiddlewareEventType, IMiddlewareHandler, IModelReflectionData, IModelReflectionPropertiesData, IModelType, IOptionalIType, IPatchRecorder, IReferenceType, IReversibleJsonPatch, ISerializedActionCall, ISimpleType, ISnapshotProcessor, ISnapshotProcessors, IStateTreeNode, IType, ITypeUnion, Instance, LivelinessMode, LivelynessMode, ModelActions, ModelCreationType, ModelCreationType2, ModelInstanceType, ModelInstanceTypeProps, ModelPrimitive, ModelProperties, ModelPropertiesDeclaration, ModelPropertiesDeclarationToProperties, ModelSnapshotType, ModelSnapshotType2, OnReferenceInvalidated, OnReferenceInvalidatedEvent, OptionalDefaultValueOrFunction, ReferenceIdentifier, ReferenceOptions, ReferenceOptionsGetSet, ReferenceOptionsOnInvalidated, SnapshotIn, SnapshotOrInstance, SnapshotOut, TypeOfValue, TypeOrStateTreeNodeToStateTreeNode, UnionOptions, UnionStringArray, ValidOptionalValue, ValidOptionalValues, _CustomCSProcessor, _CustomJoin, _CustomOrOther, _NotCustomized };
|
package/dist/mobx-state-tree.cjs
CHANGED
|
@@ -1118,6 +1118,21 @@ class ScalarNode extends BaseNode {
|
|
|
1118
1118
|
ScalarNode.prototype.die = mobx.action(ScalarNode.prototype.die);
|
|
1119
1119
|
|
|
1120
1120
|
let nextNodeId = 1;
|
|
1121
|
+
var ObservableInstanceLifecycle;
|
|
1122
|
+
(function (ObservableInstanceLifecycle) {
|
|
1123
|
+
// the actual observable instance has not been created yet
|
|
1124
|
+
ObservableInstanceLifecycle[ObservableInstanceLifecycle["UNINITIALIZED"] = 0] = "UNINITIALIZED";
|
|
1125
|
+
// the actual observable instance is being created
|
|
1126
|
+
ObservableInstanceLifecycle[ObservableInstanceLifecycle["CREATING"] = 1] = "CREATING";
|
|
1127
|
+
// the actual observable instance has been created
|
|
1128
|
+
ObservableInstanceLifecycle[ObservableInstanceLifecycle["CREATED"] = 2] = "CREATED";
|
|
1129
|
+
})(ObservableInstanceLifecycle || (ObservableInstanceLifecycle = {}));
|
|
1130
|
+
var InternalEvents;
|
|
1131
|
+
(function (InternalEvents) {
|
|
1132
|
+
InternalEvents["Dispose"] = "dispose";
|
|
1133
|
+
InternalEvents["Patch"] = "patch";
|
|
1134
|
+
InternalEvents["Snapshot"] = "snapshot";
|
|
1135
|
+
})(InternalEvents || (InternalEvents = {}));
|
|
1121
1136
|
const snapshotReactionOptions = {
|
|
1122
1137
|
onError(e) {
|
|
1123
1138
|
throw e;
|
|
@@ -1149,7 +1164,7 @@ class ObjectNode extends BaseNode {
|
|
|
1149
1164
|
_autoUnbox = true; // unboxing is disabled when reading child nodes
|
|
1150
1165
|
_isRunningAction = false; // only relevant for root
|
|
1151
1166
|
_hasSnapshotReaction = false;
|
|
1152
|
-
_observableInstanceState =
|
|
1167
|
+
_observableInstanceState = ObservableInstanceLifecycle.UNINITIALIZED;
|
|
1153
1168
|
_childNodes;
|
|
1154
1169
|
_initialSnapshot;
|
|
1155
1170
|
_cachedInitialSnapshot;
|
|
@@ -1194,7 +1209,7 @@ class ObjectNode extends BaseNode {
|
|
|
1194
1209
|
}
|
|
1195
1210
|
createObservableInstanceIfNeeded(fireHooks = true) {
|
|
1196
1211
|
if (this._observableInstanceState ===
|
|
1197
|
-
|
|
1212
|
+
ObservableInstanceLifecycle.UNINITIALIZED) {
|
|
1198
1213
|
this.createObservableInstance(fireHooks);
|
|
1199
1214
|
}
|
|
1200
1215
|
}
|
|
@@ -1205,7 +1220,7 @@ class ObjectNode extends BaseNode {
|
|
|
1205
1220
|
throw fail("assertion failed: the creation of the observable instance must be done on the initializing phase");
|
|
1206
1221
|
}
|
|
1207
1222
|
}
|
|
1208
|
-
this._observableInstanceState =
|
|
1223
|
+
this._observableInstanceState = ObservableInstanceLifecycle.CREATING;
|
|
1209
1224
|
// make sure the parent chain is created as well
|
|
1210
1225
|
// array with parent chain from parent to child
|
|
1211
1226
|
const parentChain = [];
|
|
@@ -1215,7 +1230,7 @@ class ObjectNode extends BaseNode {
|
|
|
1215
1230
|
// this is done to avoid traversing the whole tree to the root when using
|
|
1216
1231
|
// the same reference again
|
|
1217
1232
|
while (parent?._observableInstanceState ===
|
|
1218
|
-
|
|
1233
|
+
ObservableInstanceLifecycle.UNINITIALIZED) {
|
|
1219
1234
|
parentChain.unshift(parent);
|
|
1220
1235
|
parent = parent.parent;
|
|
1221
1236
|
}
|
|
@@ -1240,7 +1255,7 @@ class ObjectNode extends BaseNode {
|
|
|
1240
1255
|
finally {
|
|
1241
1256
|
this._isRunningAction = false;
|
|
1242
1257
|
}
|
|
1243
|
-
this._observableInstanceState =
|
|
1258
|
+
this._observableInstanceState = ObservableInstanceLifecycle.CREATED;
|
|
1244
1259
|
this._snapshotComputed.trackAndCompute();
|
|
1245
1260
|
if (this.isRoot) {
|
|
1246
1261
|
this._addSnapshotReaction();
|
|
@@ -1354,7 +1369,7 @@ class ObjectNode extends BaseNode {
|
|
|
1354
1369
|
if (!this.isAlive) {
|
|
1355
1370
|
return this._snapshotUponDeath;
|
|
1356
1371
|
}
|
|
1357
|
-
return this._observableInstanceState ===
|
|
1372
|
+
return this._observableInstanceState === ObservableInstanceLifecycle.CREATED
|
|
1358
1373
|
? this._getActualSnapshot()
|
|
1359
1374
|
: this._getCachedInitialSnapshot();
|
|
1360
1375
|
}
|
|
@@ -1417,7 +1432,7 @@ class ObjectNode extends BaseNode {
|
|
|
1417
1432
|
this._autoUnbox = false;
|
|
1418
1433
|
try {
|
|
1419
1434
|
return this._observableInstanceState ===
|
|
1420
|
-
|
|
1435
|
+
ObservableInstanceLifecycle.CREATED
|
|
1421
1436
|
? this.type.getChildNode(this, subpath)
|
|
1422
1437
|
: this._childNodes[subpath];
|
|
1423
1438
|
}
|
|
@@ -1430,7 +1445,7 @@ class ObjectNode extends BaseNode {
|
|
|
1430
1445
|
this._autoUnbox = false;
|
|
1431
1446
|
try {
|
|
1432
1447
|
return this._observableInstanceState ===
|
|
1433
|
-
|
|
1448
|
+
ObservableInstanceLifecycle.CREATED
|
|
1434
1449
|
? this.type.getChildren(this)
|
|
1435
1450
|
: convertChildNodesToArray(this._childNodes);
|
|
1436
1451
|
}
|
|
@@ -1516,7 +1531,7 @@ class ObjectNode extends BaseNode {
|
|
|
1516
1531
|
}
|
|
1517
1532
|
aboutToDie() {
|
|
1518
1533
|
if (this._observableInstanceState ===
|
|
1519
|
-
|
|
1534
|
+
ObservableInstanceLifecycle.UNINITIALIZED) {
|
|
1520
1535
|
return;
|
|
1521
1536
|
}
|
|
1522
1537
|
this.getChildren().forEach(node => {
|
|
@@ -1525,8 +1540,8 @@ class ObjectNode extends BaseNode {
|
|
|
1525
1540
|
// beforeDestroy should run before the disposers since else we could end up in a situation where
|
|
1526
1541
|
// a disposer added with addDisposer at this stage (beforeDestroy) is actually never released
|
|
1527
1542
|
this.baseAboutToDie();
|
|
1528
|
-
this._internalEventsEmit(
|
|
1529
|
-
this._internalEventsClear(
|
|
1543
|
+
this._internalEventsEmit(InternalEvents.Dispose);
|
|
1544
|
+
this._internalEventsClear(InternalEvents.Dispose);
|
|
1530
1545
|
}
|
|
1531
1546
|
finalizeDeath() {
|
|
1532
1547
|
// invariant: not called directly but from "die"
|
|
@@ -1542,42 +1557,42 @@ class ObjectNode extends BaseNode {
|
|
|
1542
1557
|
}
|
|
1543
1558
|
onSnapshot(onChange) {
|
|
1544
1559
|
this._addSnapshotReaction();
|
|
1545
|
-
return this._internalEventsRegister(
|
|
1560
|
+
return this._internalEventsRegister(InternalEvents.Snapshot, onChange);
|
|
1546
1561
|
}
|
|
1547
1562
|
emitSnapshot(snapshot) {
|
|
1548
|
-
this._internalEventsEmit(
|
|
1563
|
+
this._internalEventsEmit(InternalEvents.Snapshot, snapshot);
|
|
1549
1564
|
}
|
|
1550
1565
|
onPatch(handler) {
|
|
1551
|
-
return this._internalEventsRegister(
|
|
1566
|
+
return this._internalEventsRegister(InternalEvents.Patch, handler);
|
|
1552
1567
|
}
|
|
1553
1568
|
emitPatch(basePatch, source) {
|
|
1554
|
-
if (this._internalEventsHasSubscribers(
|
|
1569
|
+
if (this._internalEventsHasSubscribers(InternalEvents.Patch)) {
|
|
1555
1570
|
const localizedPatch = {
|
|
1556
1571
|
...basePatch,
|
|
1557
|
-
path: `${source.path.
|
|
1572
|
+
path: `${source.path.slice(this.path.length)}/${basePatch.path}` // calculate the relative path of the patch
|
|
1558
1573
|
};
|
|
1559
1574
|
const [patch, reversePatch] = splitPatch(localizedPatch);
|
|
1560
|
-
this._internalEventsEmit(
|
|
1575
|
+
this._internalEventsEmit(InternalEvents.Patch, patch, reversePatch);
|
|
1561
1576
|
}
|
|
1562
1577
|
if (this.parent) {
|
|
1563
1578
|
this.parent.emitPatch(basePatch, source);
|
|
1564
1579
|
}
|
|
1565
1580
|
}
|
|
1566
1581
|
hasDisposer(disposer) {
|
|
1567
|
-
return this._internalEventsHas(
|
|
1582
|
+
return this._internalEventsHas(InternalEvents.Dispose, disposer);
|
|
1568
1583
|
}
|
|
1569
1584
|
addDisposer(disposer) {
|
|
1570
1585
|
if (!this.hasDisposer(disposer)) {
|
|
1571
|
-
this._internalEventsRegister(
|
|
1586
|
+
this._internalEventsRegister(InternalEvents.Dispose, disposer, true);
|
|
1572
1587
|
return;
|
|
1573
1588
|
}
|
|
1574
1589
|
throw fail("cannot add a disposer when it is already registered for execution");
|
|
1575
1590
|
}
|
|
1576
1591
|
removeDisposer(disposer) {
|
|
1577
|
-
if (!this._internalEventsHas(
|
|
1592
|
+
if (!this._internalEventsHas(InternalEvents.Dispose, disposer)) {
|
|
1578
1593
|
throw fail("cannot remove a disposer which was never registered for execution");
|
|
1579
1594
|
}
|
|
1580
|
-
this._internalEventsUnregister(
|
|
1595
|
+
this._internalEventsUnregister(InternalEvents.Dispose, disposer);
|
|
1581
1596
|
}
|
|
1582
1597
|
removeMiddleware(middleware) {
|
|
1583
1598
|
if (this.middlewares) {
|
|
@@ -2567,22 +2582,47 @@ function isActionContextThisOrChildOf(actionContext, parentOrThis) {
|
|
|
2567
2582
|
}
|
|
2568
2583
|
|
|
2569
2584
|
const MAX_STRINGIFY_DEPTH = 3;
|
|
2585
|
+
const MAX_STRINGIFY_ARRAY_ITEMS = 10;
|
|
2586
|
+
const MAX_STRINGIFY_OBJECT_KEYS = 20;
|
|
2587
|
+
const MAX_STRINGIFY_STRING_LENGTH = 100;
|
|
2588
|
+
// Recursively cap depth, array length, object key count, and string length so a
|
|
2589
|
+
// huge offending snapshot degrades into readable, bounded context instead of a
|
|
2590
|
+
// wall of text that then gets sliced mid-structure. The depth cap also bounds
|
|
2591
|
+
// recursion on circular structures.
|
|
2592
|
+
function truncateForStringify(value, depth) {
|
|
2593
|
+
if (typeof value === "string") {
|
|
2594
|
+
return value.length > MAX_STRINGIFY_STRING_LENGTH
|
|
2595
|
+
? `${value.substring(0, MAX_STRINGIFY_STRING_LENGTH)}… (${value.length - MAX_STRINGIFY_STRING_LENGTH} more characters)`
|
|
2596
|
+
: value;
|
|
2597
|
+
}
|
|
2598
|
+
if (value === null || typeof value !== "object") {
|
|
2599
|
+
return value;
|
|
2600
|
+
}
|
|
2601
|
+
if (depth >= MAX_STRINGIFY_DEPTH) {
|
|
2602
|
+
return Array.isArray(value) ? "[…]" : "{…}";
|
|
2603
|
+
}
|
|
2604
|
+
if (Array.isArray(value)) {
|
|
2605
|
+
const items = value
|
|
2606
|
+
.slice(0, MAX_STRINGIFY_ARRAY_ITEMS)
|
|
2607
|
+
.map(item => truncateForStringify(item, depth + 1));
|
|
2608
|
+
if (value.length > MAX_STRINGIFY_ARRAY_ITEMS) {
|
|
2609
|
+
items.push(`… ${value.length - MAX_STRINGIFY_ARRAY_ITEMS} more items`);
|
|
2610
|
+
}
|
|
2611
|
+
return items;
|
|
2612
|
+
}
|
|
2613
|
+
const keys = Object.keys(value);
|
|
2614
|
+
const result = {};
|
|
2615
|
+
for (const key of keys.slice(0, MAX_STRINGIFY_OBJECT_KEYS)) {
|
|
2616
|
+
result[key] = truncateForStringify(value[key], depth + 1);
|
|
2617
|
+
}
|
|
2618
|
+
if (keys.length > MAX_STRINGIFY_OBJECT_KEYS) {
|
|
2619
|
+
result["…"] = `${keys.length - MAX_STRINGIFY_OBJECT_KEYS} more keys`;
|
|
2620
|
+
}
|
|
2621
|
+
return result;
|
|
2622
|
+
}
|
|
2570
2623
|
function safeStringify(value) {
|
|
2571
2624
|
try {
|
|
2572
|
-
|
|
2573
|
-
return JSON.stringify(value, function (_key, val) {
|
|
2574
|
-
if (val !== null && typeof val === "object") {
|
|
2575
|
-
while (ancestors.length > 0 &&
|
|
2576
|
-
ancestors[ancestors.length - 1] !== this) {
|
|
2577
|
-
ancestors.pop();
|
|
2578
|
-
}
|
|
2579
|
-
if (ancestors.length >= MAX_STRINGIFY_DEPTH) {
|
|
2580
|
-
return Array.isArray(val) ? "[…]" : "{…}";
|
|
2581
|
-
}
|
|
2582
|
-
ancestors.push(val);
|
|
2583
|
-
}
|
|
2584
|
-
return val;
|
|
2585
|
-
});
|
|
2625
|
+
return JSON.stringify(truncateForStringify(value, 0));
|
|
2586
2626
|
}
|
|
2587
2627
|
catch (e) {
|
|
2588
2628
|
// istanbul ignore next
|
|
@@ -3013,31 +3053,6 @@ function convertChildNodesToArray(childNodes) {
|
|
|
3013
3053
|
return result;
|
|
3014
3054
|
}
|
|
3015
3055
|
|
|
3016
|
-
// based on: https://github.com/mobxjs/mobx-utils/blob/master/src/async-action.ts
|
|
3017
|
-
/*
|
|
3018
|
-
All contents of this file are deprecated.
|
|
3019
|
-
|
|
3020
|
-
The term `process` has been replaced with `flow` to avoid conflicts with the
|
|
3021
|
-
global `process` object.
|
|
3022
|
-
|
|
3023
|
-
Refer to `flow.ts` for any further changes to this implementation.
|
|
3024
|
-
*/
|
|
3025
|
-
const DEPRECATION_MESSAGE = "See https://github.com/mobxjs/mobx-state-tree/issues/399 for more information. " +
|
|
3026
|
-
"Note that the middleware event types starting with `process` now start with `flow`.";
|
|
3027
|
-
/**
|
|
3028
|
-
* @hidden
|
|
3029
|
-
*
|
|
3030
|
-
* @deprecated has been renamed to `flow()`.
|
|
3031
|
-
* See https://github.com/mobxjs/mobx-state-tree/issues/399 for more information.
|
|
3032
|
-
* Note that the middleware event types starting with `process` now start with `flow`.
|
|
3033
|
-
*
|
|
3034
|
-
* @returns {Promise}
|
|
3035
|
-
*/
|
|
3036
|
-
function process$1(asyncAction) {
|
|
3037
|
-
deprecated("process", `\`process()\` has been renamed to \`flow()\`. ${DEPRECATION_MESSAGE}`);
|
|
3038
|
-
return flow(asyncAction);
|
|
3039
|
-
}
|
|
3040
|
-
|
|
3041
3056
|
const plainObjectString = Object.toString();
|
|
3042
3057
|
/**
|
|
3043
3058
|
* @internal
|
|
@@ -3328,25 +3343,6 @@ class EventHandlers {
|
|
|
3328
3343
|
}
|
|
3329
3344
|
}
|
|
3330
3345
|
}
|
|
3331
|
-
/**
|
|
3332
|
-
* @internal
|
|
3333
|
-
* @hidden
|
|
3334
|
-
*/
|
|
3335
|
-
const deprecated = function (id, message) {
|
|
3336
|
-
// skip if running production
|
|
3337
|
-
if (!devMode()) {
|
|
3338
|
-
return;
|
|
3339
|
-
}
|
|
3340
|
-
// warn if hasn't been warned before
|
|
3341
|
-
if (deprecated.ids && !deprecated.ids.hasOwnProperty(id)) {
|
|
3342
|
-
warnError(`Deprecation warning: ${message}`);
|
|
3343
|
-
}
|
|
3344
|
-
// mark as warned to avoid duplicate warn message
|
|
3345
|
-
if (deprecated.ids) {
|
|
3346
|
-
deprecated.ids[id] = true;
|
|
3347
|
-
}
|
|
3348
|
-
};
|
|
3349
|
-
deprecated.ids = {};
|
|
3350
3346
|
/**
|
|
3351
3347
|
* @internal
|
|
3352
3348
|
* @hidden
|
|
@@ -4299,9 +4295,9 @@ class ArrayType extends ComplexType {
|
|
|
4299
4295
|
return node.storedValue.slice();
|
|
4300
4296
|
}
|
|
4301
4297
|
getChildNode(node, key) {
|
|
4302
|
-
const
|
|
4303
|
-
if (
|
|
4304
|
-
return
|
|
4298
|
+
const child = node.storedValue[Number(key)];
|
|
4299
|
+
if (child) {
|
|
4300
|
+
return child;
|
|
4305
4301
|
}
|
|
4306
4302
|
throw fail(`Not a child: ${key}`);
|
|
4307
4303
|
}
|
|
@@ -4468,7 +4464,7 @@ function reconcileArrayChildren(parent, childType, oldNodes, newValues, newPaths
|
|
|
4468
4464
|
// both are empty, end
|
|
4469
4465
|
break;
|
|
4470
4466
|
}
|
|
4471
|
-
else if (!hasNewNode) {
|
|
4467
|
+
else if (oldNode && !hasNewNode) {
|
|
4472
4468
|
// new one does not exists
|
|
4473
4469
|
nothingChanged = false;
|
|
4474
4470
|
oldNodes.splice(i, 1);
|
|
@@ -7068,7 +7064,6 @@ exports.joinJsonPath = joinJsonPath;
|
|
|
7068
7064
|
exports.onAction = onAction;
|
|
7069
7065
|
exports.onPatch = onPatch;
|
|
7070
7066
|
exports.onSnapshot = onSnapshot;
|
|
7071
|
-
exports.process = process$1;
|
|
7072
7067
|
exports.protect = protect;
|
|
7073
7068
|
exports.recordActions = recordActions;
|
|
7074
7069
|
exports.recordPatches = recordPatches;
|