@jbrowse/mobx-state-tree 5.11.1 → 5.12.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/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() // theme is "light"
73
- getSnapshot(s) // { theme: "light" }
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) // {} ← key omitted because value equals default
164
+ getSnapshot(s) // {} ← key omitted because value equals default
92
165
 
93
166
  s.theme = "dark"
94
- getSnapshot(s) // { theme: "dark" }
167
+ getSnapshot(s) // { theme: "dark" }
95
168
 
96
169
  s.theme = "light"
97
- getSnapshot(s) // {} ← omitted again
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 // "number"
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) // [Circle, Square, Triangle]
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() // "hello"
227
+ t.getDefaultInstanceOrSnapshot() // "hello"
155
228
  ```
package/dist/index.d.ts CHANGED
@@ -347,7 +347,7 @@ declare function getRelativePath(base: IAnyStateTreeNode, target: IAnyStateTreeN
347
347
  * @param keepEnvironment indicates whether the clone should inherit the same environment (`true`, the default), or not have an environment (`false`). If an object is passed in as second argument, that will act as the environment for the cloned tree.
348
348
  * @returns
349
349
  */
350
- declare function clone<T extends IAnyStateTreeNode>(source: T, keepEnvironment?: boolean | any): T;
350
+ declare function clone<T extends IAnyStateTreeNode>(source: T, keepEnvironment?: boolean | object): T;
351
351
  /**
352
352
  * Removes a model element from the state tree, and let it live on as a new state tree
353
353
  */
@@ -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, process, protect, recordActions, recordPatches, resolveIdentifier, resolvePath, setDevMode, setLivelinessChecking, setLivelynessChecking, setTypeChecking, splitJsonPath, types as t, toGenerator, toGeneratorFunction, tryReference, tryResolve, typecheck, types, unescapeJsonPath, unprotect, walk };
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 };