mobx-keystone 2.2.0 → 2.3.1
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 +10 -0
- package/dist/mobx-keystone.esm.js +426 -334
- package/dist/mobx-keystone.esm.mjs +426 -334
- package/dist/mobx-keystone.umd.js +429 -333
- package/dist/types/action/applyAction.d.ts +1 -1
- package/dist/types/action/applyMethodCall.d.ts +1 -1
- package/dist/types/action/index.d.ts +12 -12
- package/dist/types/action/isModelAction.d.ts +1 -1
- package/dist/types/action/middleware.d.ts +1 -1
- package/dist/types/actionMiddlewares/actionSerialization/actionSerialization.d.ts +3 -3
- package/dist/types/actionMiddlewares/actionSerialization/applySerializedAction.d.ts +2 -2
- package/dist/types/actionMiddlewares/actionSerialization/arraySerializer.d.ts +2 -2
- package/dist/types/actionMiddlewares/actionSerialization/dateSerializer.d.ts +1 -1
- package/dist/types/actionMiddlewares/actionSerialization/index.d.ts +3 -3
- package/dist/types/actionMiddlewares/actionSerialization/mapSerializer.d.ts +2 -2
- package/dist/types/actionMiddlewares/actionSerialization/objectPathSerializer.d.ts +2 -2
- package/dist/types/actionMiddlewares/actionSerialization/objectSnapshotSerializer.d.ts +1 -1
- package/dist/types/actionMiddlewares/actionSerialization/plainObjectSerializer.d.ts +1 -1
- package/dist/types/actionMiddlewares/actionSerialization/primitiveSerializer.d.ts +1 -1
- package/dist/types/actionMiddlewares/actionSerialization/setSerializer.d.ts +2 -2
- package/dist/types/actionMiddlewares/actionTrackingMiddleware.d.ts +3 -3
- package/dist/types/actionMiddlewares/index.d.ts +6 -6
- package/dist/types/actionMiddlewares/onActionMiddleware.d.ts +3 -3
- package/dist/types/actionMiddlewares/readonlyMiddleware.d.ts +1 -1
- package/dist/types/actionMiddlewares/transactionMiddleware.d.ts +2 -2
- package/dist/types/actionMiddlewares/undoMiddleware.d.ts +8 -8
- package/dist/types/computedTree/index.d.ts +1 -1
- package/dist/types/context/index.d.ts +1 -1
- package/dist/types/dataModel/BaseDataModel.d.ts +3 -3
- package/dist/types/dataModel/DataModel.d.ts +3 -3
- package/dist/types/dataModel/getDataModelMetadata.d.ts +3 -3
- package/dist/types/dataModel/index.d.ts +4 -4
- package/dist/types/dataModel/utils.d.ts +1 -1
- package/dist/types/deepChange/index.d.ts +1 -1
- package/dist/types/deepChange/onDeepChange.d.ts +1 -1
- package/dist/types/frozen/Frozen.d.ts +1 -1
- package/dist/types/frozen/index.d.ts +1 -1
- package/dist/types/globalConfig/index.d.ts +1 -1
- package/dist/types/index.d.ts +24 -24
- package/dist/types/model/BaseModel.d.ts +5 -5
- package/dist/types/model/Model.d.ts +3 -3
- package/dist/types/model/getModelMetadata.d.ts +3 -3
- package/dist/types/model/index.d.ts +6 -6
- package/dist/types/model/mixins.d.ts +4 -4
- package/dist/types/model/utils.d.ts +4 -4
- package/dist/types/modelShared/BaseModelShared.d.ts +5 -5
- package/dist/types/modelShared/index.d.ts +4 -4
- package/dist/types/modelShared/modelDecorator.d.ts +3 -3
- package/dist/types/modelShared/modelInfo.d.ts +3 -3
- package/dist/types/modelShared/newModel.d.ts +3 -3
- package/dist/types/modelShared/prop.d.ts +3 -3
- package/dist/types/modelShared/sharedInternalModel.d.ts +4 -4
- package/dist/types/parent/findParent.d.ts +1 -1
- package/dist/types/parent/index.d.ts +9 -9
- package/dist/types/parent/path.d.ts +1 -1
- package/dist/types/patch/Patch.d.ts +1 -1
- package/dist/types/patch/applyPatches.d.ts +1 -1
- package/dist/types/patch/emitPatch.d.ts +1 -1
- package/dist/types/patch/index.d.ts +5 -5
- package/dist/types/patch/jsonPatch.d.ts +2 -2
- package/dist/types/patch/patchRecorder.d.ts +2 -2
- package/dist/types/redux/index.d.ts +2 -2
- package/dist/types/redux/redux.d.ts +3 -3
- package/dist/types/ref/Ref.d.ts +3 -3
- package/dist/types/ref/core.d.ts +2 -2
- package/dist/types/ref/customRef.d.ts +2 -2
- package/dist/types/ref/index.d.ts +4 -4
- package/dist/types/ref/rootRef.d.ts +2 -2
- package/dist/types/rootStore/index.d.ts +1 -1
- package/dist/types/snapshot/SnapshotOf.d.ts +5 -5
- package/dist/types/snapshot/SnapshotProcessingError.d.ts +2 -2
- package/dist/types/snapshot/applySnapshot.d.ts +1 -1
- package/dist/types/snapshot/cloneTreeValue.d.ts +1 -1
- package/dist/types/snapshot/fromSnapshot.d.ts +2 -2
- package/dist/types/snapshot/getSnapshot.d.ts +2 -2
- package/dist/types/snapshot/index.d.ts +8 -8
- package/dist/types/snapshot/onSnapshot.d.ts +1 -1
- package/dist/types/standardActions/index.d.ts +3 -3
- package/dist/types/standardActions/objectActions.d.ts +1 -1
- package/dist/types/transforms/asMap.d.ts +1 -1
- package/dist/types/transforms/asSet.d.ts +2 -2
- package/dist/types/transforms/bigint.d.ts +1 -1
- package/dist/types/transforms/date.d.ts +1 -1
- package/dist/types/transforms/index.d.ts +4 -4
- package/dist/types/treeUtils/draft.d.ts +1 -1
- package/dist/types/treeUtils/index.d.ts +3 -3
- package/dist/types/tweaker/index.d.ts +2 -2
- package/dist/types/tweaker/tweak.d.ts +1 -1
- package/dist/types/types/SnapshotTypeMismatchError.d.ts +5 -3
- package/dist/types/types/TypeCheckError.d.ts +2 -2
- package/dist/types/types/TypeChecker.d.ts +3 -3
- package/dist/types/types/arrayBased/typesArray.d.ts +2 -2
- package/dist/types/types/arrayBased/typesTuple.d.ts +2 -2
- package/dist/types/types/getTypeInfo.d.ts +2 -2
- package/dist/types/types/index.d.ts +7 -7
- package/dist/types/types/modelTypeMatching.d.ts +1 -0
- package/dist/types/types/objectBased/typesArraySet.d.ts +3 -3
- package/dist/types/types/objectBased/typesDataModelData.d.ts +4 -4
- package/dist/types/types/objectBased/typesModel.d.ts +4 -4
- package/dist/types/types/objectBased/typesObject.d.ts +3 -3
- package/dist/types/types/objectBased/typesObjectMap.d.ts +3 -3
- package/dist/types/types/objectBased/typesRecord.d.ts +2 -2
- package/dist/types/types/objectBased/typesRef.d.ts +3 -3
- package/dist/types/types/primitiveBased/typesEnum.d.ts +1 -1
- package/dist/types/types/primitiveBased/typesPrimitive.d.ts +3 -3
- package/dist/types/types/primitiveBased/typesRefinedPrimitive.d.ts +2 -2
- package/dist/types/types/schemas.d.ts +5 -5
- package/dist/types/types/tProp.d.ts +4 -4
- package/dist/types/types/typeCheck.d.ts +2 -2
- package/dist/types/types/types.d.ts +39 -39
- package/dist/types/types/utility/typeToStoredData.d.ts +2 -2
- package/dist/types/types/utility/typesBigInt.d.ts +1 -1
- package/dist/types/types/utility/typesCodec.d.ts +6 -6
- package/dist/types/types/utility/typesCodecCore.d.ts +4 -4
- package/dist/types/types/utility/typesCodecSupport.d.ts +4 -4
- package/dist/types/types/utility/typesDate.d.ts +2 -2
- package/dist/types/types/utility/typesMap.d.ts +2 -2
- package/dist/types/types/utility/typesMaybe.d.ts +1 -1
- package/dist/types/types/utility/typesOr.d.ts +2 -2
- package/dist/types/types/utility/typesRefinement.d.ts +3 -3
- package/dist/types/types/utility/typesSet.d.ts +3 -3
- package/dist/types/types/utility/typesSkipCheck.d.ts +2 -2
- package/dist/types/types/utility/typesTag.d.ts +2 -2
- package/dist/types/types/utility/typesUnchecked.d.ts +2 -2
- package/dist/types/utils/ModelPool.d.ts +1 -1
- package/dist/types/wrappers/ArraySet.d.ts +1 -1
- package/dist/types/wrappers/ObjectMap.d.ts +1 -1
- package/dist/types/wrappers/asMap.d.ts +1 -1
- package/dist/types/wrappers/asSet.d.ts +1 -1
- package/dist/types/wrappers/index.d.ts +4 -4
- package/package.json +10 -23
- package/src/action/modelAction.ts +1 -1
- package/src/action/modelFlow.ts +1 -1
- package/src/dataModel/BaseDataModel.ts +5 -5
- package/src/model/BaseModel.ts +7 -6
- package/src/model/mixins.ts +1 -1
- package/src/model/newModel.ts +1 -1
- package/src/modelShared/modelDecorator.ts +6 -11
- package/src/modelShared/modelInfo.ts +76 -0
- package/src/modelShared/sharedInternalModel.ts +1 -1
- package/src/ref/Ref.ts +1 -1
- package/src/snapshot/SnapshotterAndReconcilerPriority.ts +2 -1
- package/src/snapshot/fromModelSnapshot.ts +1 -1
- package/src/snapshot/fromSnapshot.ts +1 -1
- package/src/transforms/ImmutableDate.ts +19 -19
- package/src/tweaker/tweakArray.ts +1 -1
- package/src/tweaker/tweakFrozen.ts +1 -1
- package/src/tweaker/tweakModel.ts +1 -1
- package/src/tweaker/tweakPlainObject.ts +1 -1
- package/src/types/SnapshotTypeMismatchError.ts +3 -1
- package/src/types/arrayBased/typesArray.ts +1 -1
- package/src/types/arrayBased/typesTuple.ts +1 -1
- package/src/types/modelTypeMatching.ts +276 -0
- package/src/types/objectBased/typesArraySet.ts +1 -1
- package/src/types/objectBased/typesModel.ts +24 -7
- package/src/types/objectBased/typesObject.ts +1 -1
- package/src/types/objectBased/typesObjectMap.ts +1 -1
- package/src/types/objectBased/typesRecord.ts +1 -1
- package/src/types/objectBased/typesRef.ts +24 -5
- package/src/types/primitiveBased/typesPrimitive.ts +1 -1
- package/src/types/schemas.ts +1 -1
- package/src/types/utility/typesCodecCore.ts +4 -2
- package/src/types/utility/typesCodecSupport.ts +15 -7
- package/src/types/utility/typesOr.ts +40 -10
- package/src/types/utility/typesRefinement.ts +1 -1
- package/src/utils/index.ts +20 -13
- package/src/wrappers/ArraySet.ts +3 -5
- package/src/wrappers/ObjectMap.ts +3 -5
|
@@ -6,7 +6,6 @@ import { ObjectMap } from "../../wrappers/ObjectMap"
|
|
|
6
6
|
import { getTypeInfo } from "../getTypeInfo"
|
|
7
7
|
import { resolveStandardType, resolveTypeChecker } from "../resolveTypeChecker"
|
|
8
8
|
import type { AnyStandardType, AnyType, ModelType, TypeToData } from "../schemas"
|
|
9
|
-
import { TypeCheckError } from "../TypeCheckError"
|
|
10
9
|
import {
|
|
11
10
|
lateTypeChecker,
|
|
12
11
|
snapshotProcessorPlan,
|
|
@@ -15,6 +14,7 @@ import {
|
|
|
15
14
|
TypeInfo,
|
|
16
15
|
type TypeInfoGen,
|
|
17
16
|
} from "../TypeChecker"
|
|
17
|
+
import { TypeCheckError } from "../TypeCheckError"
|
|
18
18
|
import { resolveCodecSupport } from "../utility/typesCodec"
|
|
19
19
|
import { typesObject } from "./typesObject"
|
|
20
20
|
import { typesRecord } from "./typesRecord"
|
|
@@ -6,7 +6,6 @@ import { createChunkedRecordCachedCheck } from "../createCachedTypeCheck"
|
|
|
6
6
|
import { getTypeInfo } from "../getTypeInfo"
|
|
7
7
|
import { resolveStandardType, resolveTypeChecker } from "../resolveTypeChecker"
|
|
8
8
|
import type { AnyStandardType, AnyType, RecordType } from "../schemas"
|
|
9
|
-
import { TypeCheckError } from "../TypeCheckError"
|
|
10
9
|
import {
|
|
11
10
|
lateTypeChecker,
|
|
12
11
|
snapshotProcessorPlan,
|
|
@@ -15,6 +14,7 @@ import {
|
|
|
15
14
|
TypeInfo,
|
|
16
15
|
type TypeInfoGen,
|
|
17
16
|
} from "../TypeChecker"
|
|
17
|
+
import { TypeCheckError } from "../TypeCheckError"
|
|
18
18
|
import { prependPathElementToTypeCheckError } from "../typeCheckErrorUtils"
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { modelTypeKey } from "../../model/metadata"
|
|
2
|
+
import { isModel } from "../../model/utils"
|
|
2
3
|
import { modelInfoByClass } from "../../modelShared/modelInfo"
|
|
3
4
|
import type { Ref, RefConstructor } from "../../ref/Ref"
|
|
4
5
|
import { isObject } from "../../utils"
|
|
6
|
+
import {
|
|
7
|
+
isModelInstanceOfModelName,
|
|
8
|
+
isUnrelatedSnapshotModelType,
|
|
9
|
+
snapshotModelTypeMatches,
|
|
10
|
+
} from "../modelTypeMatching"
|
|
5
11
|
import { typesString } from "../primitiveBased/typesPrimitive"
|
|
6
12
|
import { resolveTypeChecker } from "../resolveTypeChecker"
|
|
7
13
|
import type { ModelType } from "../schemas"
|
|
8
|
-
import {
|
|
14
|
+
import { SnapshotTypeMismatchError } from "../SnapshotTypeMismatchError"
|
|
9
15
|
import { TypeChecker, TypeCheckerBaseType, TypeInfo } from "../TypeChecker"
|
|
16
|
+
import { TypeCheckError } from "../TypeCheckError"
|
|
10
17
|
import { typesObject } from "./typesObject"
|
|
11
18
|
|
|
12
19
|
/**
|
|
@@ -36,7 +43,10 @@ export function typesRef<O extends object>(refConstructor: RefConstructor<O>): M
|
|
|
36
43
|
TypeCheckerBaseType.Object,
|
|
37
44
|
|
|
38
45
|
(value, path, typeCheckedValue) => {
|
|
39
|
-
if (
|
|
46
|
+
if (
|
|
47
|
+
!(value instanceof refConstructor.refClass) &&
|
|
48
|
+
!(isModel(value) && isModelInstanceOfModelName(value, modelInfo.name))
|
|
49
|
+
) {
|
|
40
50
|
return new TypeCheckError({
|
|
41
51
|
path,
|
|
42
52
|
expectedTypeName: typeName,
|
|
@@ -56,16 +66,25 @@ export function typesRef<O extends object>(refConstructor: RefConstructor<O>): M
|
|
|
56
66
|
return null
|
|
57
67
|
}
|
|
58
68
|
|
|
59
|
-
|
|
69
|
+
const snModelType = obj[modelTypeKey]
|
|
70
|
+
if (snModelType !== undefined) {
|
|
60
71
|
// fast check
|
|
61
|
-
return
|
|
72
|
+
return snapshotModelTypeMatches(snModelType, modelInfo.name) ? thisTc : null
|
|
62
73
|
}
|
|
63
74
|
|
|
64
75
|
return refDataTypeChecker.snapshotType(obj) ? thisTc : null
|
|
65
76
|
},
|
|
66
77
|
|
|
67
78
|
(sn: Record<string, unknown>) => {
|
|
68
|
-
|
|
79
|
+
const snModelType = sn[modelTypeKey]
|
|
80
|
+
if (typeof snModelType === "string") {
|
|
81
|
+
// the snapshot names its own model; make sure it is this ref or a subclass of it
|
|
82
|
+
if (isUnrelatedSnapshotModelType(snModelType, modelInfo.name)) {
|
|
83
|
+
throw new SnapshotTypeMismatchError({
|
|
84
|
+
expectedTypeName: typeName,
|
|
85
|
+
actualValue: sn,
|
|
86
|
+
})
|
|
87
|
+
}
|
|
69
88
|
return sn
|
|
70
89
|
} else {
|
|
71
90
|
return {
|
|
@@ -2,8 +2,8 @@ import { assertIsPrimitive, isEqualOrBothNaN } from "../../utils"
|
|
|
2
2
|
import type { PrimitiveValue } from "../../utils/types"
|
|
3
3
|
import { registerStandardTypeResolver, type StandardTypeResolverFn } from "../resolveTypeChecker"
|
|
4
4
|
import type { AnyStandardType, IdentityType } from "../schemas"
|
|
5
|
-
import { TypeCheckError } from "../TypeCheckError"
|
|
6
5
|
import { TypeChecker, TypeCheckerBaseType, TypeInfo, type TypeInfoGen } from "../TypeChecker"
|
|
6
|
+
import { TypeCheckError } from "../TypeCheckError"
|
|
7
7
|
|
|
8
8
|
const standardTypeResolvers: StandardTypeResolverFn[] = []
|
|
9
9
|
|
package/src/types/schemas.ts
CHANGED
|
@@ -96,7 +96,7 @@ type ObjectSnapshotOutData<S, OK = ObjectOptionalKeys<S>> = SimplifyObject<
|
|
|
96
96
|
export interface ObjectType<S> extends Type<"object", ObjectData<S>> {}
|
|
97
97
|
|
|
98
98
|
export interface ObjectTypeFunction {
|
|
99
|
-
//
|
|
99
|
+
// oxlint-disable-next-line typescript/prefer-function-type -- make the type recursive
|
|
100
100
|
(): ObjectOfTypes
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ModelPropTransform } from "../../modelShared/prop"
|
|
2
2
|
import { lazy } from "../../utils"
|
|
3
3
|
import { getTypeInfo } from "../getTypeInfo"
|
|
4
|
+
import { runInModelTypeMatchingPass } from "../modelTypeMatching"
|
|
4
5
|
import { resolveStandardType, resolveTypeChecker } from "../resolveTypeChecker"
|
|
5
6
|
import type {
|
|
6
7
|
AnyStandardType,
|
|
@@ -10,7 +11,6 @@ import type {
|
|
|
10
11
|
TypeToSnapshotIn,
|
|
11
12
|
TypeToSnapshotOut,
|
|
12
13
|
} from "../schemas"
|
|
13
|
-
import { TypeCheckError } from "../TypeCheckError"
|
|
14
14
|
import {
|
|
15
15
|
lateTypeChecker,
|
|
16
16
|
TypeChecker,
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
TypeInfo,
|
|
19
19
|
type TypeInfoGen,
|
|
20
20
|
} from "../TypeChecker"
|
|
21
|
+
import { TypeCheckError } from "../TypeCheckError"
|
|
21
22
|
import type { TypeToStoredData } from "./typeToStoredData"
|
|
22
23
|
|
|
23
24
|
export interface RuntimeAdapter<Stored, Runtime> {
|
|
@@ -145,7 +146,8 @@ export function createCodecType<TEncodedType extends AnyType, TRuntime>(
|
|
|
145
146
|
() => typeName,
|
|
146
147
|
typeInfoGen,
|
|
147
148
|
|
|
148
|
-
|
|
149
|
+
// user code, so it must not see the model type matching pass of an outer union
|
|
150
|
+
(value) => (runInModelTypeMatchingPass("none", is, value, undefined) ? thisTc : null),
|
|
149
151
|
|
|
150
152
|
(snapshot) => {
|
|
151
153
|
const processedSnapshot = encodedTypeChecker.fromSnapshotProcessor(snapshot)
|
|
@@ -5,6 +5,7 @@ import { setIfDifferent } from "../../utils/setIfDifferent"
|
|
|
5
5
|
import { ArrayTypeInfo, typesArray } from "../arrayBased/typesArray"
|
|
6
6
|
import { TupleTypeInfo, typesTuple } from "../arrayBased/typesTuple"
|
|
7
7
|
import { getTypeInfo } from "../getTypeInfo"
|
|
8
|
+
import { findClosestModelTypeMatch, findFirstMatch } from "../modelTypeMatching"
|
|
8
9
|
import { isDataModelDataStandardType } from "../objectBased/typesDataModelData"
|
|
9
10
|
import { isModelStandardType } from "../objectBased/typesModel"
|
|
10
11
|
import { ObjectTypeInfo, typesObject } from "../objectBased/typesObject"
|
|
@@ -274,6 +275,7 @@ function createArrayLikeRuntimeAdapter(
|
|
|
274
275
|
target.length = storedValues.length
|
|
275
276
|
for (let i = 0; i < storedValues.length; i++) {
|
|
276
277
|
if (i in storedValues) target[i] = storedValues[i]
|
|
278
|
+
// oxlint-disable-next-line typescript/no-array-delete -- keep the holes of sparse arrays
|
|
277
279
|
else delete target[i]
|
|
278
280
|
}
|
|
279
281
|
}
|
|
@@ -512,6 +514,7 @@ function createCodecLeafRuntimeAdapter(
|
|
|
512
514
|
|
|
513
515
|
// Declared up front (rather than initialized from the call) so that a setter invoked
|
|
514
516
|
// while decoding can read it without hitting the temporal dead zone.
|
|
517
|
+
// oxlint-disable-next-line eslint/prefer-const -- see above
|
|
515
518
|
let runtime: unknown
|
|
516
519
|
let storedChanged = false
|
|
517
520
|
runtime = transform.transform({
|
|
@@ -577,6 +580,13 @@ function createCodecLeafRuntimeAdapter(
|
|
|
577
580
|
}
|
|
578
581
|
}
|
|
579
582
|
|
|
583
|
+
function matchCodecSupport(
|
|
584
|
+
support: ResolvedCodecSupport,
|
|
585
|
+
value: unknown
|
|
586
|
+
): ResolvedCodecSupport | undefined {
|
|
587
|
+
return resolveTypeChecker(support.storedType).snapshotType(value) ? support : undefined
|
|
588
|
+
}
|
|
589
|
+
|
|
580
590
|
function createOrRuntimeAdapter(
|
|
581
591
|
childTypes: ReadonlyArray<AnyStandardType>,
|
|
582
592
|
getChildSupports: () => ReadonlyArray<ResolvedCodecSupport>,
|
|
@@ -607,14 +617,12 @@ function createOrRuntimeAdapter(
|
|
|
607
617
|
}
|
|
608
618
|
|
|
609
619
|
const supports = getChildSupports()
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
}
|
|
615
|
-
}
|
|
620
|
+
// prefer branches whose (possibly nested) models are the closest to the snapshot ones
|
|
621
|
+
const matchingSupport = isObject(value)
|
|
622
|
+
? findClosestModelTypeMatch(supports, matchCodecSupport, value)
|
|
623
|
+
: findFirstMatch(supports, matchCodecSupport, value)
|
|
616
624
|
|
|
617
|
-
return supports[0]
|
|
625
|
+
return matchingSupport ?? supports[0]
|
|
618
626
|
}
|
|
619
627
|
|
|
620
628
|
return {
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
+
import { modelTypeKey } from "../../model/metadata"
|
|
2
|
+
import { getModelInfoForName } from "../../modelShared/modelInfo"
|
|
1
3
|
import { failure, lazy } from "../../utils"
|
|
2
4
|
import { getTypeInfo } from "../getTypeInfo"
|
|
5
|
+
import {
|
|
6
|
+
findClosestModelTypeMatch,
|
|
7
|
+
findFirstMatch,
|
|
8
|
+
getModelTypeMatchingPass,
|
|
9
|
+
hasSnapshotModelType,
|
|
10
|
+
matchUnlessModelSnapshotRejected,
|
|
11
|
+
} from "../modelTypeMatching"
|
|
3
12
|
import {
|
|
4
13
|
resolveStandardType,
|
|
5
14
|
resolveStandardTypeNoThrow,
|
|
6
15
|
resolveTypeChecker,
|
|
7
16
|
} from "../resolveTypeChecker"
|
|
8
|
-
import { SnapshotTypeMismatchError } from "../SnapshotTypeMismatchError"
|
|
9
17
|
import type { AnyStandardType, AnyType } from "../schemas"
|
|
10
|
-
import {
|
|
18
|
+
import { SnapshotTypeMismatchError } from "../SnapshotTypeMismatchError"
|
|
11
19
|
import {
|
|
12
20
|
getTypeCheckerBaseTypeFromValue,
|
|
13
21
|
lateTypeChecker,
|
|
@@ -17,6 +25,7 @@ import {
|
|
|
17
25
|
TypeInfo,
|
|
18
26
|
type TypeInfoGen,
|
|
19
27
|
} from "../TypeChecker"
|
|
28
|
+
import { TypeCheckError } from "../TypeCheckError"
|
|
20
29
|
import { typesUnchecked } from "./typesUnchecked"
|
|
21
30
|
|
|
22
31
|
/**
|
|
@@ -195,17 +204,34 @@ export function typesOr(
|
|
|
195
204
|
// this is done because:
|
|
196
205
|
// 1) performance (avoid checking structure if not needed)
|
|
197
206
|
// 2) so we can accept untyped models when paired with undefined | null
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
207
|
+
const candidate = checkerForBaseType[0]
|
|
208
|
+
if (
|
|
209
|
+
getModelTypeMatchingPass() !== "none" &&
|
|
210
|
+
valueBaseType !== TypeCheckerBaseType.Primitive
|
|
211
|
+
) {
|
|
212
|
+
// an outer union is matching its branches, so let it know whether this one matches
|
|
213
|
+
// the (possibly nested) snapshot models; if it does not because a (possibly nested)
|
|
214
|
+
// model type rejected a model snapshot (in the exact pass, also one of a subclass),
|
|
215
|
+
// or because the snapshot names a registered model this branch does not accept, the
|
|
216
|
+
// outer union has to try other branches first, else it might pick a farther branch
|
|
217
|
+
// or one that rejects the snapshot
|
|
218
|
+
const matched = matchUnlessModelSnapshotRejected(matchSnapshotType, candidate, value)
|
|
219
|
+
if (
|
|
220
|
+
matched === undefined ||
|
|
221
|
+
(!matched &&
|
|
222
|
+
hasSnapshotModelType(value) &&
|
|
223
|
+
getModelInfoForName((value as any)[modelTypeKey]))
|
|
224
|
+
) {
|
|
225
|
+
return null
|
|
226
|
+
}
|
|
205
227
|
}
|
|
228
|
+
return candidate
|
|
206
229
|
}
|
|
207
230
|
|
|
208
|
-
|
|
231
|
+
// prefer branches whose (possibly nested) models are the closest to the snapshot ones
|
|
232
|
+
return valueBaseType === TypeCheckerBaseType.Primitive
|
|
233
|
+
? (findFirstMatch(checkerForBaseType, matchSnapshotType, value) ?? null)
|
|
234
|
+
: (findClosestModelTypeMatch(checkerForBaseType, matchSnapshotType, value) ?? null)
|
|
209
235
|
},
|
|
210
236
|
|
|
211
237
|
snapshotProcessorPlan(
|
|
@@ -272,3 +298,7 @@ export class OrTypeInfo extends TypeInfo {
|
|
|
272
298
|
this.dispatcher = dispatcher
|
|
273
299
|
}
|
|
274
300
|
}
|
|
301
|
+
|
|
302
|
+
function matchSnapshotType(checker: TypeChecker, value: unknown): TypeChecker | null {
|
|
303
|
+
return checker.snapshotType(value)
|
|
304
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { getTypeInfo } from "../getTypeInfo"
|
|
2
2
|
import { resolveStandardType, resolveTypeChecker } from "../resolveTypeChecker"
|
|
3
3
|
import type { AnyStandardType, AnyType, TypeToData } from "../schemas"
|
|
4
|
-
import { TypeCheckError } from "../TypeCheckError"
|
|
5
4
|
import {
|
|
6
5
|
lateTypeChecker,
|
|
7
6
|
snapshotProcessorPlan,
|
|
@@ -9,6 +8,7 @@ import {
|
|
|
9
8
|
TypeInfo,
|
|
10
9
|
type TypeInfoGen,
|
|
11
10
|
} from "../TypeChecker"
|
|
11
|
+
import { TypeCheckError } from "../TypeCheckError"
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* A refinement over a given type. This allows you to do extra checks
|
package/src/utils/index.ts
CHANGED
|
@@ -117,7 +117,7 @@ export let hasOwnProp: (object: object, propName: PropertyKey) => boolean = (
|
|
|
117
117
|
typeof Object.hasOwn === "function"
|
|
118
118
|
? Object.hasOwn
|
|
119
119
|
: (object, propName) => {
|
|
120
|
-
//
|
|
120
|
+
// oxlint-disable-next-line eslint/no-prototype-builtins -- legacy fallback for runtimes without Object.hasOwn.
|
|
121
121
|
return Object.prototype.hasOwnProperty.call(object, propName)
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -133,7 +133,7 @@ export let hasOwnProp: (object: object, propName: PropertyKey) => boolean = (
|
|
|
133
133
|
* @internal
|
|
134
134
|
*/
|
|
135
135
|
export function isEqualOrBothNaN(a: unknown, b: unknown): boolean {
|
|
136
|
-
//
|
|
136
|
+
// oxlint-disable-next-line eslint/no-self-compare -- NaN check
|
|
137
137
|
return a === b || (a !== a && b !== b)
|
|
138
138
|
}
|
|
139
139
|
|
|
@@ -244,19 +244,26 @@ export function isArray(val: unknown): val is any[] | IObservableArray {
|
|
|
244
244
|
return Array.isArray(val) || isObservableArray(val)
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
declare const process:
|
|
248
|
-
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
247
|
+
declare const process: {
|
|
248
|
+
env: Record<string, string | undefined>
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function readInDevMode(): boolean {
|
|
252
|
+
// Bundlers replace the literal expression `process.env.NODE_ENV` with a string, so it must stay
|
|
253
|
+
// spelled out in full (no optional chaining, destructuring or `typeof process` guard) for dev
|
|
254
|
+
// mode to work in browser bundles. The try/catch keeps the library loadable where there is
|
|
255
|
+
// neither a bundler replacement nor a global `process`.
|
|
256
|
+
try {
|
|
257
|
+
return process.env.NODE_ENV !== undefined && process.env.NODE_ENV !== "production"
|
|
258
|
+
} catch {
|
|
259
|
+
return false
|
|
260
|
+
}
|
|
261
|
+
}
|
|
252
262
|
|
|
253
263
|
/**
|
|
254
264
|
* @internal
|
|
255
265
|
*/
|
|
256
|
-
export const inDevMode =
|
|
257
|
-
typeof process !== "undefined" &&
|
|
258
|
-
process?.env?.NODE_ENV !== undefined &&
|
|
259
|
-
process.env.NODE_ENV !== "production"
|
|
266
|
+
export const inDevMode = readInDevMode()
|
|
260
267
|
|
|
261
268
|
/**
|
|
262
269
|
* @internal
|
|
@@ -390,11 +397,11 @@ export function logWarning(type: "warn" | "error", msg: string, uniqueKey?: stri
|
|
|
390
397
|
msg = "[mobx-keystone] " + msg
|
|
391
398
|
switch (type) {
|
|
392
399
|
case "warn":
|
|
393
|
-
//
|
|
400
|
+
// oxlint-disable-next-line eslint/no-console -- this internal helper intentionally emits user-facing warnings.
|
|
394
401
|
console.warn(msg)
|
|
395
402
|
break
|
|
396
403
|
case "error":
|
|
397
|
-
//
|
|
404
|
+
// oxlint-disable-next-line eslint/no-console -- this internal helper intentionally emits user-facing errors.
|
|
398
405
|
console.error(msg)
|
|
399
406
|
break
|
|
400
407
|
default:
|
package/src/wrappers/ArraySet.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { modelAction } from "../action/modelAction"
|
|
2
2
|
import type { AnyModel } from "../model/BaseModel"
|
|
3
|
-
import { Model } from "../model/Model"
|
|
4
3
|
import { modelIdKey } from "../model/metadata"
|
|
4
|
+
import { Model } from "../model/Model"
|
|
5
5
|
import { model } from "../modelShared/modelDecorator"
|
|
6
6
|
import { idProp } from "../modelShared/prop"
|
|
7
7
|
import { typesArray } from "../types/arrayBased/typesArray"
|
|
@@ -21,9 +21,7 @@ import {
|
|
|
21
21
|
const arraySetBase = Model({
|
|
22
22
|
[modelIdKey]: idProp,
|
|
23
23
|
items: tProp(typesArray(typesUnchecked<any>()), () => []), // will be properly checked by types.arraySet(subType)
|
|
24
|
-
}) as abstract new (
|
|
25
|
-
data: any
|
|
26
|
-
) => AnyModel & {
|
|
24
|
+
}) as abstract new (data: any) => AnyModel & {
|
|
27
25
|
readonly $: {
|
|
28
26
|
items: any[]
|
|
29
27
|
}
|
|
@@ -35,7 +33,7 @@ const arraySetBase = Model({
|
|
|
35
33
|
* Use `arraySet` to create it.
|
|
36
34
|
*/
|
|
37
35
|
@model(`${namespace}/ArraySet`)
|
|
38
|
-
//
|
|
36
|
+
// oxlint-disable-next-line typescript/no-unsafe-declaration-merging -- model base defines these properties at runtime.
|
|
39
37
|
export class ArraySet<V> extends arraySetBase implements Set<V> {
|
|
40
38
|
@modelAction
|
|
41
39
|
add(value: V): this {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { entries, get, has, keys, remove, values } from "mobx"
|
|
2
2
|
import { modelAction } from "../action/modelAction"
|
|
3
3
|
import type { AnyModel } from "../model/BaseModel"
|
|
4
|
-
import { Model } from "../model/Model"
|
|
5
4
|
import { modelIdKey } from "../model/metadata"
|
|
5
|
+
import { Model } from "../model/Model"
|
|
6
6
|
import { model } from "../modelShared/modelDecorator"
|
|
7
7
|
import { idProp } from "../modelShared/prop"
|
|
8
8
|
import { typesRecord } from "../types/objectBased/typesRecord"
|
|
@@ -14,9 +14,7 @@ import { setIfDifferent } from "../utils/setIfDifferent"
|
|
|
14
14
|
const objectMapBase = Model({
|
|
15
15
|
[modelIdKey]: idProp,
|
|
16
16
|
items: tProp(typesRecord(typesUnchecked<any>()), () => ({})), // will be properly checked by types.objectMap(subType)
|
|
17
|
-
}) as abstract new (
|
|
18
|
-
data: any
|
|
19
|
-
) => AnyModel & {
|
|
17
|
+
}) as abstract new (data: any) => AnyModel & {
|
|
20
18
|
readonly $: {
|
|
21
19
|
items: Record<string, any>
|
|
22
20
|
}
|
|
@@ -28,7 +26,7 @@ const objectMapBase = Model({
|
|
|
28
26
|
* Use `objectMap` to create it.
|
|
29
27
|
*/
|
|
30
28
|
@model(`${namespace}/ObjectMap`)
|
|
31
|
-
//
|
|
29
|
+
// oxlint-disable-next-line typescript/no-unsafe-declaration-merging -- model base defines these properties at runtime.
|
|
32
30
|
export class ObjectMap<V> extends objectMapBase implements Map<string, V> {
|
|
33
31
|
@modelAction
|
|
34
32
|
clear(): void {
|