mobx-keystone 2.1.0 → 2.3.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 +17 -0
- package/README.md +1 -1
- package/dist/mobx-keystone.esm.js +555 -516
- package/dist/mobx-keystone.esm.mjs +555 -516
- package/dist/mobx-keystone.umd.js +558 -519
- package/dist/types/actionMiddlewares/undoMiddleware.d.ts +2 -10
- package/dist/types/modelShared/modelDecorator.d.ts +5 -2
- package/dist/types/modelShared/prop.d.ts +42 -29
- package/dist/types/ref/Ref.d.ts +1 -4
- package/dist/types/snapshot/SnapshotOf.d.ts +4 -4
- package/dist/types/snapshot/applySnapshot.d.ts +1 -1
- package/dist/types/snapshot/fromSnapshot.d.ts +2 -2
- package/dist/types/snapshot/getSnapshot.d.ts +1 -1
- package/dist/types/types/SnapshotTypeMismatchError.d.ts +3 -1
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/modelTypeMatching.d.ts +1 -0
- package/dist/types/types/schemas.d.ts +41 -37
- package/dist/types/types/tProp.d.ts +12 -6
- package/dist/types/types/types.d.ts +6 -6
- package/dist/types/types/utility/typeToStoredData.d.ts +14 -10
- package/dist/types/types/utility/typesCodecCore.d.ts +3 -0
- package/dist/types/utils/ModelPool.d.ts +0 -1
- package/dist/types/utils/types.d.ts +6 -0
- package/dist/types/wrappers/ArraySet.d.ts +1 -0
- package/package.json +13 -11
- package/src/action/modelFlow.ts +35 -66
- package/src/actionMiddlewares/actionTrackingMiddleware.ts +41 -71
- package/src/actionMiddlewares/transactionMiddleware.ts +1 -1
- package/src/actionMiddlewares/undoMiddleware.ts +16 -22
- package/src/context/context.ts +15 -36
- package/src/dataModel/utils.ts +5 -28
- package/src/deepChange/onDeepChange.ts +44 -126
- package/src/model/BaseModel.ts +1 -1
- package/src/model/utils.ts +5 -10
- package/src/modelShared/modelDecorator.ts +13 -10
- package/src/modelShared/modelInfo.ts +75 -0
- package/src/modelShared/prop.ts +115 -111
- package/src/modelShared/sharedInternalModel.ts +2 -2
- package/src/parent/arrayPaths.ts +1 -4
- package/src/parent/path.ts +0 -10
- package/src/patch/patchRecorder.ts +13 -28
- package/src/ref/core.ts +6 -19
- package/src/rootStore/rootStore.ts +1 -3
- package/src/snapshot/SnapshotOf.ts +24 -48
- package/src/snapshot/applySnapshot.ts +1 -1
- package/src/snapshot/fromSnapshot.ts +10 -3
- package/src/snapshot/getSnapshot.ts +1 -1
- package/src/snapshot/internal.ts +0 -2
- package/src/snapshot/reconcileModelSnapshot.ts +5 -3
- package/src/snapshot/reconcilePlainObjectSnapshot.ts +3 -1
- package/src/treeUtils/draft.ts +6 -1
- package/src/treeUtils/sandbox.ts +10 -7
- package/src/tweaker/tweakArray.ts +20 -50
- package/src/tweaker/tweakPlainObject.ts +9 -15
- package/src/types/SnapshotTypeMismatchError.ts +3 -1
- package/src/types/arrayBased/typesArray.ts +13 -19
- package/src/types/arrayBased/typesTuple.ts +16 -25
- package/src/types/createCachedTypeCheck.ts +17 -30
- package/src/types/index.ts +1 -0
- package/src/types/modelTypeMatching.ts +276 -0
- package/src/types/objectBased/typesDataModelData.ts +7 -8
- package/src/types/objectBased/typesModel.ts +23 -6
- package/src/types/objectBased/typesObject.ts +11 -15
- package/src/types/objectBased/typesRecord.ts +11 -15
- package/src/types/objectBased/typesRef.ts +23 -4
- package/src/types/schemas.ts +59 -71
- package/src/types/tProp.ts +29 -29
- package/src/types/utility/typeToStoredData.ts +22 -21
- package/src/types/utility/typesCodecCore.ts +8 -1
- package/src/types/utility/typesCodecSupport.ts +16 -10
- package/src/types/utility/typesMap.ts +43 -51
- package/src/types/utility/typesOr.ts +38 -8
- package/src/types/utility/typesRefinement.ts +7 -8
- package/src/types/utility/typesSkipCheck.ts +7 -8
- package/src/types/utility/typesTag.ts +7 -8
- package/src/utils/ModelPool.ts +1 -18
- package/src/utils/decorators.ts +5 -5
- package/src/utils/index.ts +1 -20
- package/src/utils/types.ts +5 -0
- package/src/wrappers/ArraySet.ts +27 -14
- package/src/wrappers/ObjectMap.ts +1 -6
- package/src/wrappers/asMap.ts +1 -21
- package/src/wrappers/asSet.ts +0 -8
package/src/modelShared/prop.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { AnyStandardType } from "../types/schemas"
|
|
|
3
3
|
import { isEqualOrBothNaN, lazy } from "../utils"
|
|
4
4
|
import { runWithErrorDiagnosticsContext, withErrorPathSegment } from "../utils/errorDiagnostics"
|
|
5
5
|
import { getOrCreate } from "../utils/mapUtils"
|
|
6
|
-
import type {
|
|
6
|
+
import type { IsNeverType, IsOptionalValue, SimplifyObject } from "../utils/types"
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @ignore
|
|
@@ -71,50 +71,18 @@ export interface ModelProp<
|
|
|
71
71
|
* Adds a setter to the property. The setter will be named `set${CapitalizedPropName}`
|
|
72
72
|
* and will be available in the model instance.
|
|
73
73
|
*/
|
|
74
|
-
withSetter():
|
|
75
|
-
TPropValue,
|
|
76
|
-
TPropCreationValue,
|
|
77
|
-
TTransformedValue,
|
|
78
|
-
TTransformedCreationValue,
|
|
79
|
-
TIsRequired,
|
|
80
|
-
TIsId,
|
|
81
|
-
string,
|
|
82
|
-
TFromSnapshotOverride,
|
|
83
|
-
TToSnapshotOverride
|
|
84
|
-
>
|
|
74
|
+
withSetter(): ModelPropWithSetter<this>
|
|
85
75
|
/**
|
|
86
76
|
* Adds a setter with a transform to the property. The setter will be named `set${CapitalizedPropName}`
|
|
87
77
|
* and will be available in the model instance.
|
|
88
78
|
*/
|
|
89
79
|
withSetter(
|
|
90
80
|
valueTransform: ModelPropSetterValueTransform<TTransformedValue>
|
|
91
|
-
):
|
|
92
|
-
TPropValue,
|
|
93
|
-
TPropCreationValue,
|
|
94
|
-
TTransformedValue,
|
|
95
|
-
TTransformedCreationValue,
|
|
96
|
-
TIsRequired,
|
|
97
|
-
TIsId,
|
|
98
|
-
string,
|
|
99
|
-
TFromSnapshotOverride,
|
|
100
|
-
TToSnapshotOverride
|
|
101
|
-
>
|
|
81
|
+
): ModelPropWithSetter<this>
|
|
102
82
|
/**
|
|
103
83
|
* @deprecated Setter methods are preferred.
|
|
104
84
|
*/
|
|
105
|
-
withSetter(
|
|
106
|
-
mode: "assign"
|
|
107
|
-
): ModelProp<
|
|
108
|
-
TPropValue,
|
|
109
|
-
TPropCreationValue,
|
|
110
|
-
TTransformedValue,
|
|
111
|
-
TTransformedCreationValue,
|
|
112
|
-
TIsRequired,
|
|
113
|
-
TIsId,
|
|
114
|
-
string,
|
|
115
|
-
TFromSnapshotOverride,
|
|
116
|
-
TToSnapshotOverride
|
|
117
|
-
>
|
|
85
|
+
withSetter(mode: "assign"): ModelPropWithSetter<this>
|
|
118
86
|
|
|
119
87
|
/**
|
|
120
88
|
* Sets a transform for the property instance value.
|
|
@@ -130,17 +98,7 @@ export interface ModelProp<
|
|
|
130
98
|
*/
|
|
131
99
|
withTransform<TTV>(
|
|
132
100
|
transform: ModelPropTransform<NonNullable<TPropValue>, TTV>
|
|
133
|
-
):
|
|
134
|
-
TPropValue,
|
|
135
|
-
TPropCreationValue,
|
|
136
|
-
TTV | Extract<TPropValue, null | undefined>,
|
|
137
|
-
TTV | Extract<TPropCreationValue, null | undefined>,
|
|
138
|
-
TIsRequired,
|
|
139
|
-
TIsId,
|
|
140
|
-
THasSetter,
|
|
141
|
-
TFromSnapshotOverride,
|
|
142
|
-
TToSnapshotOverride
|
|
143
|
-
>
|
|
101
|
+
): ModelPropWithTransform<this, TTV>
|
|
144
102
|
|
|
145
103
|
/**
|
|
146
104
|
* Sets snapshot processors for this property.
|
|
@@ -158,18 +116,69 @@ export interface ModelProp<
|
|
|
158
116
|
>(processor: {
|
|
159
117
|
fromSnapshot?: (sn: FS) => ModelPropFromSnapshot<This>
|
|
160
118
|
toSnapshot?: (sn: ModelPropToSnapshot<This>) => TS
|
|
161
|
-
}):
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
TS
|
|
171
|
-
>
|
|
119
|
+
}): ModelPropWithSnapshotProcessor<this, FS, TS>
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
type ModelPropStoredMetadataKey = "$storedValueType" | "$storedCreationValueType"
|
|
123
|
+
|
|
124
|
+
// keeps the stored value metadata that `tProp` adds (e.g. the encoded type of a codec)
|
|
125
|
+
// when a model prop is derived through one of its modifiers
|
|
126
|
+
type ModelPropStoredMetadata<MP, K extends PropertyKey> = MP extends {
|
|
127
|
+
$storedValueType: unknown
|
|
172
128
|
}
|
|
129
|
+
? Pick<MP, Extract<keyof MP, K>>
|
|
130
|
+
: {}
|
|
131
|
+
|
|
132
|
+
// the modifier result types are exported so emitted declaration files can reference them by name
|
|
133
|
+
// instead of expanding them inline in every exported model class
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The model property returned by `withSetter`.
|
|
137
|
+
*/
|
|
138
|
+
export type ModelPropWithSetter<MP extends AnyModelProp> = ModelProp<
|
|
139
|
+
MP["$valueType"],
|
|
140
|
+
MP["$creationValueType"],
|
|
141
|
+
MP["$transformedValueType"],
|
|
142
|
+
MP["$transformedCreationValueType"],
|
|
143
|
+
MP["$isRequired"],
|
|
144
|
+
MP["$isId"],
|
|
145
|
+
string,
|
|
146
|
+
MP["$fromSnapshotOverride"],
|
|
147
|
+
MP["$toSnapshotOverride"]
|
|
148
|
+
> &
|
|
149
|
+
ModelPropStoredMetadata<MP, ModelPropStoredMetadataKey | "$typedFromSnapshotOverride">
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* The model property returned by `withTransform`.
|
|
153
|
+
*/
|
|
154
|
+
export type ModelPropWithTransform<MP extends AnyModelProp, TTV> = ModelProp<
|
|
155
|
+
MP["$valueType"],
|
|
156
|
+
MP["$creationValueType"],
|
|
157
|
+
TTV | Extract<MP["$valueType"], null | undefined>,
|
|
158
|
+
TTV | Extract<MP["$creationValueType"], null | undefined>,
|
|
159
|
+
MP["$isRequired"],
|
|
160
|
+
MP["$isId"],
|
|
161
|
+
MP["$hasSetter"],
|
|
162
|
+
MP["$fromSnapshotOverride"],
|
|
163
|
+
MP["$toSnapshotOverride"]
|
|
164
|
+
> &
|
|
165
|
+
ModelPropStoredMetadata<MP, ModelPropStoredMetadataKey | "$typedFromSnapshotOverride">
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* The model property returned by `withSnapshotProcessor`.
|
|
169
|
+
*/
|
|
170
|
+
export type ModelPropWithSnapshotProcessor<MP extends AnyModelProp, FS, TS> = ModelProp<
|
|
171
|
+
MP["$valueType"],
|
|
172
|
+
MP["$creationValueType"],
|
|
173
|
+
MP["$transformedValueType"],
|
|
174
|
+
MP["$transformedCreationValueType"],
|
|
175
|
+
MP["$isRequired"],
|
|
176
|
+
MP["$isId"],
|
|
177
|
+
MP["$hasSetter"],
|
|
178
|
+
FS,
|
|
179
|
+
TS
|
|
180
|
+
> &
|
|
181
|
+
ModelPropStoredMetadata<MP, ModelPropStoredMetadataKey>
|
|
173
182
|
|
|
174
183
|
/**
|
|
175
184
|
* The snapshot in type of a model property.
|
|
@@ -189,23 +198,19 @@ export type ModelPropToSnapshot<MP extends AnyModelProp> = IsNeverType<
|
|
|
189
198
|
MP["$toSnapshotOverride"]
|
|
190
199
|
>
|
|
191
200
|
|
|
192
|
-
export type ModelPropStoredValue<MP extends AnyModelProp> =
|
|
193
|
-
$storedValueType
|
|
194
|
-
}
|
|
195
|
-
? TStoredValue
|
|
201
|
+
export type ModelPropStoredValue<MP extends AnyModelProp> = "$storedValueType" extends keyof MP
|
|
202
|
+
? MP["$storedValueType" & keyof MP]
|
|
196
203
|
: MP["$valueType"]
|
|
197
204
|
|
|
198
|
-
export type ModelPropStoredCreationValue<MP extends AnyModelProp> =
|
|
199
|
-
$storedCreationValueType
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
: MP["$creationValueType"]
|
|
205
|
+
export type ModelPropStoredCreationValue<MP extends AnyModelProp> =
|
|
206
|
+
"$storedCreationValueType" extends keyof MP
|
|
207
|
+
? MP["$storedCreationValueType" & keyof MP]
|
|
208
|
+
: MP["$creationValueType"]
|
|
203
209
|
|
|
204
|
-
export type ModelPropFromSnapshotOverride<MP extends AnyModelProp> =
|
|
205
|
-
$typedFromSnapshotOverride
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
: MP["$fromSnapshotOverride"]
|
|
210
|
+
export type ModelPropFromSnapshotOverride<MP extends AnyModelProp> =
|
|
211
|
+
"$typedFromSnapshotOverride" extends keyof MP
|
|
212
|
+
? MP["$typedFromSnapshotOverride" & keyof MP]
|
|
213
|
+
: MP["$fromSnapshotOverride"]
|
|
209
214
|
|
|
210
215
|
/**
|
|
211
216
|
* A model prop transform.
|
|
@@ -245,13 +250,13 @@ export type RequiredModelProps<MP extends ModelProps> = {
|
|
|
245
250
|
[K in keyof MP]: MP[K]["$isRequired"] & K
|
|
246
251
|
}[keyof MP]
|
|
247
252
|
|
|
248
|
-
export type ModelPropsToUntransformedData<MP extends ModelProps> =
|
|
253
|
+
export type ModelPropsToUntransformedData<MP extends ModelProps> = {
|
|
249
254
|
[k in keyof MP]: ModelPropStoredValue<MP[k]>
|
|
250
|
-
}
|
|
255
|
+
} & {}
|
|
251
256
|
|
|
252
|
-
export type ModelPropsToSnapshotData<MP extends ModelProps> =
|
|
257
|
+
export type ModelPropsToSnapshotData<MP extends ModelProps> = {
|
|
253
258
|
[k in keyof MP]: ModelPropToSnapshot<MP[k]> extends infer R ? R : never
|
|
254
|
-
}
|
|
259
|
+
} & {}
|
|
255
260
|
|
|
256
261
|
// we don't use O.Optional anymore since it generates unions too heavy
|
|
257
262
|
// also if we use Pick over the optional props we will loose the ability to infer generics
|
|
@@ -264,23 +269,29 @@ export type ModelPropsToUntransformedCreationData<MP extends ModelProps> = {
|
|
|
264
269
|
|
|
265
270
|
// we don't use O.Optional anymore since it generates unions too heavy
|
|
266
271
|
// also if we use Pick over the optional props we will loose the ability to infer generics
|
|
267
|
-
export type ModelPropsToSnapshotCreationData<MP extends ModelProps> =
|
|
272
|
+
export type ModelPropsToSnapshotCreationData<MP extends ModelProps> = SimplifyObject<
|
|
268
273
|
{
|
|
269
274
|
[k in keyof MP]?: ModelPropFromSnapshot<MP[k]> extends infer R ? R : never
|
|
270
275
|
} & {
|
|
271
|
-
[k in
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
MP[K]["$isRequired"] & K, // no override
|
|
275
|
-
IsOptionalValue<ModelPropFromSnapshotOverride<MP[K]>, never, K> // with override
|
|
276
|
-
>
|
|
277
|
-
}[keyof MP]]: ModelPropFromSnapshot<MP[k]> extends infer R ? R : never
|
|
276
|
+
[k in SnapshotCreationRequiredKeys<MP>]: ModelPropFromSnapshot<MP[k]> extends infer R
|
|
277
|
+
? R
|
|
278
|
+
: never
|
|
278
279
|
}
|
|
279
280
|
>
|
|
280
281
|
|
|
281
|
-
|
|
282
|
+
// without a snapshot processor a key is required when the prop is required,
|
|
283
|
+
// with one when the processor input does not accept undefined
|
|
284
|
+
type SnapshotCreationRequiredKeys<MP extends ModelProps> = {
|
|
285
|
+
[K in keyof MP]: IsNeverType<
|
|
286
|
+
ModelPropFromSnapshotOverride<MP[K]>,
|
|
287
|
+
MP[K]["$isRequired"] & K,
|
|
288
|
+
IsOptionalValue<ModelPropFromSnapshotOverride<MP[K]>, never, K>
|
|
289
|
+
>
|
|
290
|
+
}[keyof MP]
|
|
291
|
+
|
|
292
|
+
export type ModelPropsToTransformedData<MP extends ModelProps> = {
|
|
282
293
|
[k in keyof MP]: MP[k]["$transformedValueType"]
|
|
283
|
-
}
|
|
294
|
+
} & {}
|
|
284
295
|
|
|
285
296
|
// we don't use O.Optional anymore since it generates unions too heavy
|
|
286
297
|
// also if we use Pick over the optional props we will loose the ability to infer generics
|
|
@@ -292,11 +303,11 @@ export type ModelPropsToTransformedCreationData<MP extends ModelProps> = {
|
|
|
292
303
|
[k in RequiredModelProps<MP>]: MP[k]["$transformedCreationValueType"]
|
|
293
304
|
}
|
|
294
305
|
|
|
295
|
-
export type ModelPropsToSetter<MP extends ModelProps> =
|
|
306
|
+
export type ModelPropsToSetter<MP extends ModelProps> = {
|
|
296
307
|
[k in keyof MP as MP[k]["$hasSetter"] & `set${Capitalize<k & string>}`]: (
|
|
297
308
|
value: MP[k]["$transformedValueType"]
|
|
298
309
|
) => void
|
|
299
|
-
}
|
|
310
|
+
} & {}
|
|
300
311
|
|
|
301
312
|
export type ModelIdProp<T extends string = string> = ModelProp<
|
|
302
313
|
T,
|
|
@@ -307,7 +318,12 @@ export type ModelIdProp<T extends string = string> = ModelProp<
|
|
|
307
318
|
true
|
|
308
319
|
>
|
|
309
320
|
|
|
310
|
-
|
|
321
|
+
// exported (and publicly re-exported) so emitted declaration files can reference it by name
|
|
322
|
+
// instead of expanding it inline in every exported model class, which is much slower and larger
|
|
323
|
+
/**
|
|
324
|
+
* The type of `idProp`.
|
|
325
|
+
*/
|
|
326
|
+
export type TypedModelIdProp<T extends string = string, THasSetter = never> = Omit<
|
|
311
327
|
ModelProp<T, T | undefined, T, T | undefined, never, true, THasSetter>,
|
|
312
328
|
"withSetter"
|
|
313
329
|
> & {
|
|
@@ -569,21 +585,17 @@ export function prop(...args: [] | [def: any]): AnyModelProp {
|
|
|
569
585
|
|
|
570
586
|
const [def] = args
|
|
571
587
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
if (!p) {
|
|
575
|
-
p = Object.create(baseProp)
|
|
588
|
+
return getOrCreate(propCache, def, () => {
|
|
589
|
+
const p: AnyModelProp = Object.create(baseProp)
|
|
576
590
|
|
|
577
591
|
if (typeof def === "function") {
|
|
578
|
-
p
|
|
592
|
+
p._defaultFn = def
|
|
579
593
|
} else {
|
|
580
|
-
p
|
|
594
|
+
p._defaultValue = def
|
|
581
595
|
}
|
|
582
596
|
|
|
583
|
-
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
return p!
|
|
597
|
+
return p
|
|
598
|
+
})
|
|
587
599
|
}
|
|
588
600
|
|
|
589
601
|
function parseSetterConfig(
|
|
@@ -599,19 +611,11 @@ function parseSetterConfig(
|
|
|
599
611
|
}
|
|
600
612
|
}
|
|
601
613
|
|
|
602
|
-
if (
|
|
603
|
-
modeOrValueTransform === undefined ||
|
|
604
|
-
typeof modeOrValueTransform === "boolean" ||
|
|
605
|
-
modeOrValueTransform === "assign"
|
|
606
|
-
) {
|
|
607
|
-
return {
|
|
608
|
-
mode: modeOrValueTransform ?? true,
|
|
609
|
-
valueTransform: undefined,
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
|
|
613
614
|
return {
|
|
614
|
-
mode:
|
|
615
|
+
mode:
|
|
616
|
+
typeof modeOrValueTransform === "boolean" || modeOrValueTransform === "assign"
|
|
617
|
+
? modeOrValueTransform
|
|
618
|
+
: true,
|
|
615
619
|
valueTransform: undefined,
|
|
616
620
|
}
|
|
617
621
|
}
|
|
@@ -241,7 +241,7 @@ export function sharedInternalModel<
|
|
|
241
241
|
const idPropGenerator = idProp._idGenerator
|
|
242
242
|
const baseIdProp = baseModelProps?.[idKey]
|
|
243
243
|
const baseIdPropGenerator = baseIdProp?._idGenerator
|
|
244
|
-
const isOverridingBaseIdProp = !!baseIdProp?._isId &&
|
|
244
|
+
const isOverridingBaseIdProp = !!baseIdProp?._isId && hasOwnProp(modelProps, idKey)
|
|
245
245
|
if (isOverridingBaseIdProp && baseIdPropGenerator !== idPropGenerator) {
|
|
246
246
|
throw failure(
|
|
247
247
|
`expected same idProp.withGenerator function when overriding a base idProp, but got different references`
|
|
@@ -315,7 +315,7 @@ export function sharedInternalModel<
|
|
|
315
315
|
// make sure abstract classes do not override prototype props
|
|
316
316
|
if (!propsToDeleteFromBase) {
|
|
317
317
|
propsToDeleteFromBase = Object.keys(modelProps).filter(
|
|
318
|
-
(p) => !basePropNames.has(p as any) &&
|
|
318
|
+
(p) => !basePropNames.has(p as any) && hasOwnProp(baseModel, p)
|
|
319
319
|
)
|
|
320
320
|
}
|
|
321
321
|
|
package/src/parent/arrayPaths.ts
CHANGED
|
@@ -235,8 +235,5 @@ export function getArrayPaths(
|
|
|
235
235
|
* @internal
|
|
236
236
|
*/
|
|
237
237
|
export function setLazyArrayParentPath(entry: LazyArrayParentPath, node: object): void {
|
|
238
|
-
|
|
239
|
-
if (metadata.parentPath !== entry) {
|
|
240
|
-
metadata.parentPath = entry
|
|
241
|
-
}
|
|
238
|
+
treeNodeMetadata.get(node)!.parentPath = entry
|
|
242
239
|
}
|
package/src/parent/path.ts
CHANGED
|
@@ -127,16 +127,6 @@ export function fastGetParent<T extends object = any>(
|
|
|
127
127
|
return fastGetParentPath(value, useAtom)?.parent
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
/**
|
|
131
|
-
* @internal
|
|
132
|
-
*/
|
|
133
|
-
export function fastGetParentIncludingDataObjects<T extends object = any>(
|
|
134
|
-
value: object,
|
|
135
|
-
useAtom: boolean
|
|
136
|
-
): T | undefined {
|
|
137
|
-
return fastGetParentPathIncludingDataObjects(value, useAtom)?.parent
|
|
138
|
-
}
|
|
139
|
-
|
|
140
130
|
/**
|
|
141
131
|
* Returns if a given object is a model interim data object (`$`).
|
|
142
132
|
*
|
|
@@ -108,36 +108,21 @@ export function internalPatchRecorder(
|
|
|
108
108
|
deep: false,
|
|
109
109
|
})
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
patches: p,
|
|
121
|
-
inversePatches: invP,
|
|
122
|
-
})
|
|
123
|
-
opts?.onPatches?.(p, invP)
|
|
124
|
-
}
|
|
125
|
-
},
|
|
126
|
-
true
|
|
127
|
-
)
|
|
128
|
-
} else {
|
|
129
|
-
onPatchesDisposer = internalOnGlobalPatches((target, p, invP) => {
|
|
130
|
-
if (recording && filter(p, invP)) {
|
|
131
|
-
events.push({
|
|
132
|
-
target,
|
|
133
|
-
patches: p,
|
|
134
|
-
inversePatches: invP,
|
|
135
|
-
})
|
|
136
|
-
opts?.onPatches?.(p, invP)
|
|
137
|
-
}
|
|
138
|
-
}, true)
|
|
111
|
+
const record = (target: object, p: Patch[], invP: Patch[]) => {
|
|
112
|
+
if (recording && filter(p, invP)) {
|
|
113
|
+
events.push({
|
|
114
|
+
target,
|
|
115
|
+
patches: p,
|
|
116
|
+
inversePatches: invP,
|
|
117
|
+
})
|
|
118
|
+
opts?.onPatches?.(p, invP)
|
|
119
|
+
}
|
|
139
120
|
}
|
|
140
121
|
|
|
122
|
+
const onPatchesDisposer: OnPatchesDisposer = subtreeRoot
|
|
123
|
+
? internalOnPatches(subtreeRoot, (p, invP) => record(subtreeRoot, p, invP), true)
|
|
124
|
+
: internalOnGlobalPatches(record, true)
|
|
125
|
+
|
|
141
126
|
return {
|
|
142
127
|
get recording() {
|
|
143
128
|
return recording
|
package/src/ref/core.ts
CHANGED
|
@@ -220,29 +220,16 @@ export function resolveId<T extends object>(
|
|
|
220
220
|
return resolveRefIdByIndex(root, id, getId) as T | undefined
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
const createRefSet = () => observable.set<Ref<any>>(undefined, { deep: false })
|
|
224
|
+
|
|
225
|
+
const createBackRefs = (): BackRefs<any> => ({ all: createRefSet(), byType: new WeakMap() })
|
|
226
|
+
|
|
223
227
|
function getBackRefs<T extends object>(
|
|
224
228
|
target: T,
|
|
225
229
|
refType?: RefConstructor<T>
|
|
226
230
|
): ObservableSet<Ref<T>> {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
backRefs = {
|
|
230
|
-
all: observable.set(undefined, { deep: false }),
|
|
231
|
-
byType: new WeakMap(),
|
|
232
|
-
}
|
|
233
|
-
objectBackRefs.set(target, backRefs)
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
if (refType) {
|
|
237
|
-
let byType = backRefs.byType.get(refType)
|
|
238
|
-
if (!byType) {
|
|
239
|
-
byType = observable.set(undefined, { deep: false })
|
|
240
|
-
backRefs.byType.set(refType, byType)
|
|
241
|
-
}
|
|
242
|
-
return byType
|
|
243
|
-
} else {
|
|
244
|
-
return backRefs.all
|
|
245
|
-
}
|
|
231
|
+
const backRefs: BackRefs<T> = getOrCreate(objectBackRefs, target, createBackRefs)
|
|
232
|
+
return refType ? getOrCreate(backRefs.byType, refType, createRefSet) : backRefs.all
|
|
246
233
|
}
|
|
247
234
|
|
|
248
235
|
/**
|
|
@@ -84,9 +84,7 @@ export function isRootStore(node: object): boolean {
|
|
|
84
84
|
assertTweakedObject(node, "node")
|
|
85
85
|
|
|
86
86
|
const entry = getOrCreateRootStoreEntry(node)
|
|
87
|
-
|
|
88
|
-
entry.atom = createAtom("rootStore")
|
|
89
|
-
}
|
|
87
|
+
entry.atom ??= createAtom("rootStore")
|
|
90
88
|
entry.atom.reportObserved()
|
|
91
89
|
return entry.is
|
|
92
90
|
}
|
|
@@ -13,10 +13,8 @@ export type FrozenData<D> = {
|
|
|
13
13
|
|
|
14
14
|
// snapshot out
|
|
15
15
|
|
|
16
|
-
// infer is there just to cache type generation
|
|
17
|
-
|
|
18
16
|
export type SnapshotOutOfObject<T> = {
|
|
19
|
-
[k in keyof T]: SnapshotOutOf<T[k]>
|
|
17
|
+
[k in keyof T]: SnapshotOutOf<T[k]>
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
export type SnapshotOutOfModel<M extends AnyModel> = ModelToSnapshot<M>
|
|
@@ -35,33 +33,22 @@ export interface SnapshotOutOfArraySet<V> {
|
|
|
35
33
|
[modelIdKey]: string
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
export type SnapshotOutOf<T> =
|
|
39
|
-
T extends
|
|
40
|
-
?
|
|
41
|
-
?
|
|
42
|
-
:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
: T
|
|
48
|
-
|
|
49
|
-
? R
|
|
50
|
-
: never
|
|
51
|
-
: T extends Frozen<any>
|
|
52
|
-
? SnapshotOutOfFrozen<T> extends infer R
|
|
53
|
-
? R
|
|
54
|
-
: never
|
|
55
|
-
: T extends object
|
|
56
|
-
? SnapshotOutOfObject<T> extends infer R
|
|
57
|
-
? R
|
|
58
|
-
: never
|
|
59
|
-
: T
|
|
36
|
+
export type SnapshotOutOf<T> = T extends object
|
|
37
|
+
? T extends AnyModel
|
|
38
|
+
? T extends ObjectMap<infer V>
|
|
39
|
+
? SnapshotOutOfObjectMap<V>
|
|
40
|
+
: T extends ArraySet<infer V>
|
|
41
|
+
? SnapshotOutOfArraySet<V>
|
|
42
|
+
: SnapshotOutOfModel<T>
|
|
43
|
+
: T extends Frozen<any>
|
|
44
|
+
? SnapshotOutOfFrozen<T>
|
|
45
|
+
: SnapshotOutOfObject<T>
|
|
46
|
+
: T
|
|
60
47
|
|
|
61
48
|
// snapshot in
|
|
62
49
|
|
|
63
50
|
export type SnapshotInOfObject<T> = {
|
|
64
|
-
[k in keyof T]: SnapshotInOf<T[k]>
|
|
51
|
+
[k in keyof T]: SnapshotInOf<T[k]>
|
|
65
52
|
}
|
|
66
53
|
|
|
67
54
|
export type SnapshotInOfModel<M extends AnyModel> = ModelFromSnapshot<M>
|
|
@@ -80,25 +67,14 @@ export interface SnapshotInOfArraySet<V> {
|
|
|
80
67
|
[modelIdKey]: string
|
|
81
68
|
}
|
|
82
69
|
|
|
83
|
-
export type SnapshotInOf<T> =
|
|
84
|
-
T extends
|
|
85
|
-
?
|
|
86
|
-
?
|
|
87
|
-
:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
: T
|
|
93
|
-
|
|
94
|
-
? R
|
|
95
|
-
: never
|
|
96
|
-
: T extends Frozen<any>
|
|
97
|
-
? SnapshotInOfFrozen<T> extends infer R
|
|
98
|
-
? R
|
|
99
|
-
: never
|
|
100
|
-
: T extends object
|
|
101
|
-
? SnapshotInOfObject<T> extends infer R
|
|
102
|
-
? R
|
|
103
|
-
: never
|
|
104
|
-
: T
|
|
70
|
+
export type SnapshotInOf<T> = T extends object
|
|
71
|
+
? T extends AnyModel
|
|
72
|
+
? T extends ObjectMap<infer V>
|
|
73
|
+
? SnapshotInOfObjectMap<V>
|
|
74
|
+
: T extends ArraySet<infer V>
|
|
75
|
+
? SnapshotInOfArraySet<V>
|
|
76
|
+
: SnapshotInOfModel<T>
|
|
77
|
+
: T extends Frozen<any>
|
|
78
|
+
? SnapshotInOfFrozen<T>
|
|
79
|
+
: SnapshotInOfObject<T>
|
|
80
|
+
: T
|
|
@@ -33,7 +33,7 @@ import { SnapshotProcessingError } from "./SnapshotProcessingError"
|
|
|
33
33
|
*/
|
|
34
34
|
export function applySnapshot<T extends object>(
|
|
35
35
|
node: T,
|
|
36
|
-
snapshot: SnapshotInOf<T> | SnapshotOutOf<T
|
|
36
|
+
snapshot: NoInfer<SnapshotInOf<T> | SnapshotOutOf<T>>
|
|
37
37
|
): void
|
|
38
38
|
|
|
39
39
|
export function applySnapshot(node: object, snapshot: unknown): void {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { action, observable } from "mobx"
|
|
2
2
|
import type { AnyModel } from "../model/BaseModel"
|
|
3
3
|
import { isReservedModelKey } from "../model/metadata"
|
|
4
|
+
import { isTweakedObject } from "../tweaker/core"
|
|
4
5
|
import { resolveStandardTypeNoThrow, resolveTypeChecker } from "../types/resolveTypeChecker"
|
|
5
|
-
import type { AnyType, TypeToData, TypeToSnapshotIn } from "../types/schemas"
|
|
6
|
+
import type { AnyType, TypeToData, TypeToSnapshotIn, TypeToSnapshotOut } from "../types/schemas"
|
|
6
7
|
import { isLateTypeChecker, TypeChecker } from "../types/TypeChecker"
|
|
7
8
|
import { resolveCodecSupport } from "../types/utility/typesCodec"
|
|
8
9
|
import { isMap, isPrimitive, isSet, nodeObservableOptions, setProtoProp } from "../utils"
|
|
@@ -60,7 +61,7 @@ export interface FromSnapshotContext {
|
|
|
60
61
|
*/
|
|
61
62
|
export function fromSnapshot<TType extends AnyType>(
|
|
62
63
|
type: TType,
|
|
63
|
-
snapshot: TypeToSnapshotIn<TType
|
|
64
|
+
snapshot: NoInfer<TypeToSnapshotIn<TType> | TypeToSnapshotOut<TType>>,
|
|
64
65
|
options?: Partial<FromSnapshotOptions>
|
|
65
66
|
): TypeToData<TType>
|
|
66
67
|
|
|
@@ -122,7 +123,6 @@ const fromSnapshotAction = action(
|
|
|
122
123
|
): T => {
|
|
123
124
|
const opts = {
|
|
124
125
|
generateNewIds: false,
|
|
125
|
-
overrideRootModelId: undefined,
|
|
126
126
|
...options,
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -172,6 +172,13 @@ export function internalFromSnapshot<T>(
|
|
|
172
172
|
})
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
if (isTweakedObject(sn, true)) {
|
|
176
|
+
throw new SnapshotProcessingError({
|
|
177
|
+
message: "a snapshot must not contain tree nodes (use getSnapshot to get their snapshots)",
|
|
178
|
+
actualSnapshot: sn,
|
|
179
|
+
})
|
|
180
|
+
}
|
|
181
|
+
|
|
175
182
|
throw new SnapshotProcessingError({
|
|
176
183
|
message: "unsupported snapshot",
|
|
177
184
|
actualSnapshot: sn,
|
package/src/snapshot/internal.ts
CHANGED
|
@@ -156,7 +156,9 @@ function reconcileModelSnapshot(
|
|
|
156
156
|
if (!isReservedModelKey(k)) {
|
|
157
157
|
const v = processedSn[k]
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
// an inherited member such as `toString` is no old value (but `__proto__`
|
|
160
|
+
// still reads the prototype, which is rejected as it is no tree node)
|
|
161
|
+
const oldValue = k === "__proto__" || hasOwnProp(data, k) ? data[k] : undefined
|
|
160
162
|
// Non-null primitives need neither reconciliation nor detachment.
|
|
161
163
|
// Nullish values must still pass through default handling below.
|
|
162
164
|
if (v != null && isPrimitive(v)) {
|
|
@@ -216,10 +218,10 @@ function snapshotSlotsAreEqual(
|
|
|
216
218
|
for (let i = 0; i < currentKeys.length; i++) {
|
|
217
219
|
const key = currentKeys[i]
|
|
218
220
|
// a matching key at the same index proves the key is an own property of
|
|
219
|
-
// the incoming snapshot without an
|
|
221
|
+
// the incoming snapshot without an own-property check; canonical snapshots
|
|
220
222
|
// keep key order, so the fallback is rare (never trust inherited values,
|
|
221
223
|
// e.g. a crafted __proto__ chain, without an own-property proof)
|
|
222
|
-
if (incomingKeys[i] !== key && !
|
|
224
|
+
if (incomingKeys[i] !== key && !hasOwnProp(incomingSnapshot, key)) {
|
|
223
225
|
return false
|
|
224
226
|
}
|
|
225
227
|
if (currentSnapshot[key] !== incomingSnapshot[key]) {
|