mobx-keystone 1.20.0 → 1.22.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.
Files changed (174) hide show
  1. package/CHANGELOG.md +864 -853
  2. package/README.md +61 -61
  3. package/dist/mobx-keystone.esm.js +11336 -11148
  4. package/dist/mobx-keystone.esm.mjs +11336 -11148
  5. package/dist/mobx-keystone.umd.js +12229 -11738
  6. package/dist/types/actionMiddlewares/undoMiddleware.d.ts +1 -1
  7. package/dist/types/modelShared/prop.d.ts +5 -0
  8. package/dist/types/redux/connectReduxDevTools.d.ts +17 -4
  9. package/dist/types/ref/Ref.d.ts +1 -1
  10. package/dist/types/treeUtils/sandbox.d.ts +1 -1
  11. package/dist/types/types/TypeChecker.d.ts +1 -1
  12. package/dist/types/types/arrayBased/typesArray.d.ts +1 -1
  13. package/dist/types/types/arrayBased/typesTuple.d.ts +1 -1
  14. package/dist/types/types/objectBased/typesArraySet.d.ts +1 -1
  15. package/dist/types/types/objectBased/typesDataModelData.d.ts +1 -1
  16. package/dist/types/types/objectBased/typesModel.d.ts +1 -1
  17. package/dist/types/types/objectBased/typesObject.d.ts +3 -3
  18. package/dist/types/types/objectBased/typesObjectMap.d.ts +1 -1
  19. package/dist/types/types/objectBased/typesRecord.d.ts +1 -1
  20. package/dist/types/types/primitiveBased/typesPrimitive.d.ts +1 -1
  21. package/dist/types/types/types.d.ts +3 -3
  22. package/dist/types/types/utility/typesCodec.d.ts +1 -6
  23. package/dist/types/types/utility/typesCodecCore.d.ts +1 -1
  24. package/dist/types/types/utility/typesOr.d.ts +1 -1
  25. package/dist/types/types/utility/typesRefinement.d.ts +1 -1
  26. package/dist/types/types/utility/typesSkipCheck.d.ts +1 -1
  27. package/dist/types/types/utility/typesTag.d.ts +1 -1
  28. package/dist/types/wrappers/ObjectMap.d.ts +2 -0
  29. package/dist/types/wrappers/asMap.d.ts +10 -6
  30. package/package.json +14 -12
  31. package/src/action/applyAction.ts +125 -114
  32. package/src/action/applyMethodCall.ts +37 -37
  33. package/src/action/isModelAction.ts +16 -16
  34. package/src/action/middleware.ts +137 -137
  35. package/src/action/modelFlow.ts +240 -240
  36. package/src/action/modelFlowPromiseGenerator.ts +127 -125
  37. package/src/action/pendingActions.ts +42 -42
  38. package/src/action/wrapInAction.ts +156 -156
  39. package/src/actionMiddlewares/actionSerialization/actionSerialization.ts +1 -1
  40. package/src/actionMiddlewares/actionSerialization/applySerializedAction.ts +172 -172
  41. package/src/actionMiddlewares/actionSerialization/arraySerializer.ts +20 -20
  42. package/src/actionMiddlewares/actionSerialization/dateSerializer.ts +17 -17
  43. package/src/actionMiddlewares/actionSerialization/mapSerializer.ts +42 -42
  44. package/src/actionMiddlewares/actionSerialization/objectPathSerializer.ts +50 -50
  45. package/src/actionMiddlewares/actionSerialization/objectSnapshotSerializer.ts +21 -21
  46. package/src/actionMiddlewares/actionSerialization/plainObjectSerializer.ts +24 -32
  47. package/src/actionMiddlewares/actionSerialization/primitiveSerializer.ts +51 -51
  48. package/src/actionMiddlewares/actionSerialization/setSerializer.ts +37 -37
  49. package/src/actionMiddlewares/actionTrackingMiddleware.ts +3 -3
  50. package/src/actionMiddlewares/onActionMiddleware.ts +2 -2
  51. package/src/actionMiddlewares/readonlyMiddleware.ts +2 -2
  52. package/src/actionMiddlewares/transactionMiddleware.ts +4 -4
  53. package/src/actionMiddlewares/undoMiddleware.ts +804 -796
  54. package/src/actionMiddlewares/utils.ts +2 -2
  55. package/src/computedTree/computedTree.ts +143 -143
  56. package/src/context/context.ts +1 -1
  57. package/src/dataModel/BaseDataModel.ts +194 -192
  58. package/src/dataModel/actions.ts +1 -1
  59. package/src/dataModel/newDataModel.ts +57 -57
  60. package/src/deepChange/index.ts +1 -1
  61. package/src/deepChange/onDeepChange.ts +244 -244
  62. package/src/frozen/Frozen.ts +146 -146
  63. package/src/globalConfig/globalConfig.ts +107 -107
  64. package/src/index.ts +24 -24
  65. package/src/model/BaseModel.ts +275 -273
  66. package/src/model/ModelConstructorOptions.ts +15 -15
  67. package/src/model/getModelMetadata.ts +51 -51
  68. package/src/model/index.ts +6 -6
  69. package/src/model/mixins.ts +288 -288
  70. package/src/model/newModel.ts +301 -301
  71. package/src/model/utils.ts +249 -249
  72. package/src/modelShared/modelDecorator.ts +260 -253
  73. package/src/modelShared/modelInfo.ts +50 -50
  74. package/src/modelShared/modelSymbols.ts +3 -3
  75. package/src/modelShared/newModel.ts +25 -25
  76. package/src/modelShared/prop.ts +713 -684
  77. package/src/modelShared/sharedInternalModel.ts +427 -417
  78. package/src/modelShared/utils.ts +24 -24
  79. package/src/parent/core.ts +65 -65
  80. package/src/parent/coreObjectChildren.ts +180 -180
  81. package/src/parent/detach.ts +47 -47
  82. package/src/parent/findParent.ts +1 -1
  83. package/src/parent/getChildrenObjects.ts +25 -25
  84. package/src/parent/path.ts +386 -381
  85. package/src/parent/setParent.ts +149 -149
  86. package/src/parent/walkTree.ts +1 -1
  87. package/src/patch/applyPatches.ts +187 -187
  88. package/src/patch/jsonPatch.ts +108 -108
  89. package/src/patch/patchRecorder.ts +6 -1
  90. package/src/redux/connectReduxDevTools.ts +39 -7
  91. package/src/redux/redux.ts +6 -2
  92. package/src/ref/Ref.ts +1 -1
  93. package/src/ref/core.ts +339 -345
  94. package/src/ref/customRef.ts +3 -3
  95. package/src/ref/rootRef.ts +100 -100
  96. package/src/rootStore/attachDetach.ts +89 -89
  97. package/src/rootStore/rootStore.ts +1 -1
  98. package/src/snapshot/SnapshotOf.ts +104 -104
  99. package/src/snapshot/SnapshotProcessingError.ts +45 -45
  100. package/src/snapshot/applySnapshot.ts +177 -181
  101. package/src/snapshot/cloneTreeValue.ts +30 -30
  102. package/src/snapshot/fromArraySnapshot.ts +27 -33
  103. package/src/snapshot/fromModelSnapshot.ts +70 -70
  104. package/src/snapshot/fromPlainObjectSnapshot.ts +47 -42
  105. package/src/snapshot/fromSnapshot.ts +198 -198
  106. package/src/snapshot/getSnapshot.ts +80 -79
  107. package/src/snapshot/index.ts +8 -8
  108. package/src/snapshot/internal.ts +230 -230
  109. package/src/snapshot/reconcileArraySnapshot.ts +70 -70
  110. package/src/snapshot/reconcileModelSnapshot.ts +155 -150
  111. package/src/snapshot/reconcilePlainObjectSnapshot.ts +72 -72
  112. package/src/snapshot/reconcileSnapshot.ts +88 -88
  113. package/src/standardActions/actions.ts +64 -64
  114. package/src/standardActions/objectActions.ts +60 -60
  115. package/src/transforms/ImmutableDate.ts +93 -93
  116. package/src/transforms/asMap.ts +50 -50
  117. package/src/transforms/asSet.ts +22 -22
  118. package/src/transforms/bigint.ts +20 -20
  119. package/src/transforms/date.ts +40 -40
  120. package/src/treeUtils/deepEquals.ts +55 -55
  121. package/src/treeUtils/sandbox.ts +6 -3
  122. package/src/tweaker/TweakerPriority.ts +9 -9
  123. package/src/tweaker/tweak.ts +4 -3
  124. package/src/tweaker/tweakArray.ts +530 -475
  125. package/src/tweaker/tweakFrozen.ts +42 -42
  126. package/src/tweaker/tweakModel.ts +1 -1
  127. package/src/tweaker/tweakPlainObject.ts +355 -355
  128. package/src/tweaker/typeChecking.ts +101 -101
  129. package/src/types/SnapshotTypeMismatchError.ts +46 -46
  130. package/src/types/TypeCheckError.ts +183 -184
  131. package/src/types/TypeChecker.ts +202 -185
  132. package/src/types/arrayBased/typesArray.ts +136 -137
  133. package/src/types/arrayBased/typesTuple.ts +138 -139
  134. package/src/types/createPerEntryCachedCheck.ts +166 -160
  135. package/src/types/index.ts +6 -6
  136. package/src/types/objectBased/typesArraySet.ts +133 -134
  137. package/src/types/objectBased/typesDataModelData.ts +203 -204
  138. package/src/types/objectBased/typesModel.ts +220 -221
  139. package/src/types/objectBased/typesObject.ts +308 -310
  140. package/src/types/objectBased/typesObjectMap.ts +142 -143
  141. package/src/types/objectBased/typesRecord.ts +156 -157
  142. package/src/types/objectBased/typesRef.ts +89 -89
  143. package/src/types/primitiveBased/typesEnum.ts +63 -63
  144. package/src/types/primitiveBased/typesPrimitive.ts +219 -220
  145. package/src/types/registerDefaultStandardTypeResolvers.ts +21 -21
  146. package/src/types/resolveTypeChecker.ts +78 -78
  147. package/src/types/schemas.ts +208 -208
  148. package/src/types/tProp.ts +277 -268
  149. package/src/types/typeCheck.ts +21 -21
  150. package/src/types/typeCheckErrorUtils.ts +23 -23
  151. package/src/types/types.ts +142 -142
  152. package/src/types/utility/typeToStoredData.ts +37 -37
  153. package/src/types/utility/typesBigInt.ts +15 -15
  154. package/src/types/utility/typesCodec.ts +41 -38
  155. package/src/types/utility/typesCodecCore.ts +178 -178
  156. package/src/types/utility/typesCodecSupport.ts +806 -806
  157. package/src/types/utility/typesDate.ts +27 -27
  158. package/src/types/utility/typesMap.ts +253 -222
  159. package/src/types/utility/typesOr.ts +263 -259
  160. package/src/types/utility/typesRefinement.ts +131 -125
  161. package/src/types/utility/typesSet.ts +110 -110
  162. package/src/types/utility/typesSkipCheck.ts +69 -70
  163. package/src/types/utility/typesTag.ts +88 -82
  164. package/src/types/utility/typesUnchecked.ts +40 -40
  165. package/src/utils/AnyFunction.ts +4 -4
  166. package/src/utils/ModelPool.ts +59 -59
  167. package/src/utils/chainFns.ts +18 -18
  168. package/src/utils/decorators.ts +274 -274
  169. package/src/utils/errorDiagnostics.ts +204 -204
  170. package/src/utils/index.ts +443 -372
  171. package/src/wrappers/ArraySet.ts +156 -156
  172. package/src/wrappers/ObjectMap.ts +155 -136
  173. package/src/wrappers/asMap.ts +65 -30
  174. package/src/wrappers/asSet.ts +3 -3
@@ -1,134 +1,133 @@
1
- import { modelTypeKey } from "../../model/metadata"
2
- import { modelInfoByClass } from "../../modelShared/modelInfo"
3
- import { isObject } from "../../utils"
4
- import { withErrorPathSegment } from "../../utils/errorDiagnostics"
5
- import { ArraySet } from "../../wrappers/ArraySet"
6
- import { typesArray } from "../arrayBased/typesArray"
7
- import { getTypeInfo } from "../getTypeInfo"
8
- import { resolveStandardType, resolveTypeChecker } from "../resolveTypeChecker"
9
- import type { AnyStandardType, AnyType, ModelType, TypeToData } from "../schemas"
10
- import { TypeCheckError } from "../TypeCheckError"
11
- import {
12
- lateTypeChecker,
13
- TypeChecker,
14
- TypeCheckerBaseType,
15
- TypeInfo,
16
- TypeInfoGen,
17
- } from "../TypeChecker"
18
- import { resolveCodecSupport } from "../utility/typesCodec"
19
- import { typesObject } from "./typesObject"
20
-
21
- /**
22
- * A type that represents an array backed set ArraySet.
23
- *
24
- * Example:
25
- * ```ts
26
- * const numberSetType = types.arraySet(types.number)
27
- * ```
28
- *
29
- * @template T Value type.
30
- * @param valueType Value type.
31
- * @returns
32
- */
33
- export function typesArraySet<T extends AnyType>(valueType: T): ModelType<ArraySet<TypeToData<T>>> {
34
- const typeInfoGen: TypeInfoGen = (t) => new ArraySetTypeInfo(t, resolveStandardType(valueType))
35
-
36
- return lateTypeChecker(() => {
37
- const modelInfo = modelInfoByClass.get(ArraySet)!
38
-
39
- const valueChecker = resolveTypeChecker(valueType)
40
- const valueSupport = resolveCodecSupport(valueType)
41
- const storedValueChecker = resolveTypeChecker(valueSupport.storedType)
42
-
43
- const getTypeName = (...recursiveTypeCheckers: TypeChecker[]) =>
44
- `ArraySet<${valueChecker.getTypeName(...recursiveTypeCheckers, valueChecker)}>`
45
-
46
- const dataTypeChecker = typesObject(() => ({
47
- items: typesArray(valueSupport.storedType as any),
48
- }))
49
-
50
- const thisTc: TypeChecker = new TypeChecker(
51
- TypeCheckerBaseType.Object, // because it is really a model
52
-
53
- (obj, path, typeCheckedValue) => {
54
- if (!(obj instanceof ArraySet)) {
55
- return new TypeCheckError({
56
- path,
57
- expectedTypeName: getTypeName(thisTc),
58
- actualValue: obj,
59
- typeCheckedValue,
60
- })
61
- }
62
-
63
- const resolvedTc = resolveTypeChecker(dataTypeChecker)
64
- return resolvedTc.check(obj.$, path, typeCheckedValue)
65
- },
66
-
67
- getTypeName,
68
- typeInfoGen,
69
-
70
- (obj) => {
71
- if (!isObject(obj)) {
72
- return null
73
- }
74
-
75
- if (obj[modelTypeKey] !== undefined) {
76
- // fast check
77
- return obj[modelTypeKey] === modelInfo.name ? thisTc : null
78
- }
79
-
80
- const resolvedTc = resolveTypeChecker(dataTypeChecker)
81
- return resolvedTc.snapshotType(obj) ? thisTc : null
82
- },
83
-
84
- (sn: { items: unknown[] }) => {
85
- const items = withErrorPathSegment("items", () =>
86
- sn.items.map((v, i) =>
87
- withErrorPathSegment(i, () => storedValueChecker.fromSnapshotProcessor(v))
88
- )
89
- )
90
-
91
- return {
92
- ...sn,
93
- [modelTypeKey]: modelInfo.name,
94
- items,
95
- }
96
- },
97
-
98
- (sn: { items: unknown[]; [modelTypeKey]?: string }) => {
99
- const items = withErrorPathSegment("items", () =>
100
- sn.items.map((v, i) =>
101
- withErrorPathSegment(i, () => storedValueChecker.toSnapshotProcessor(v))
102
- )
103
- )
104
-
105
- const snCopy = {
106
- ...sn,
107
- items,
108
- }
109
-
110
- return snCopy
111
- }
112
- )
113
-
114
- return thisTc
115
- }, typeInfoGen) as any
116
- }
117
-
118
- /**
119
- * `types.arraySet` type info.
120
- */
121
- export class ArraySetTypeInfo extends TypeInfo {
122
- readonly kind = "arraySet"
123
-
124
- get valueTypeInfo(): TypeInfo {
125
- return getTypeInfo(this.valueType)
126
- }
127
-
128
- constructor(
129
- originalType: AnyStandardType,
130
- readonly valueType: AnyStandardType
131
- ) {
132
- super(originalType)
133
- }
134
- }
1
+ import { modelTypeKey } from "../../model/metadata"
2
+ import { modelInfoByClass } from "../../modelShared/modelInfo"
3
+ import { isObject } from "../../utils"
4
+ import { withErrorPathSegment } from "../../utils/errorDiagnostics"
5
+ import { ArraySet } from "../../wrappers/ArraySet"
6
+ import { typesArray } from "../arrayBased/typesArray"
7
+ import { getTypeInfo } from "../getTypeInfo"
8
+ import { resolveStandardType, resolveTypeChecker } from "../resolveTypeChecker"
9
+ import type { AnyStandardType, AnyType, ModelType, TypeToData } from "../schemas"
10
+ import { TypeCheckError } from "../TypeCheckError"
11
+ import {
12
+ lateTypeChecker,
13
+ TypeChecker,
14
+ TypeCheckerBaseType,
15
+ TypeInfo,
16
+ type TypeInfoGen,
17
+ } from "../TypeChecker"
18
+ import { resolveCodecSupport } from "../utility/typesCodec"
19
+ import { typesObject } from "./typesObject"
20
+
21
+ /**
22
+ * A type that represents an array backed set ArraySet.
23
+ *
24
+ * Example:
25
+ * ```ts
26
+ * const numberSetType = types.arraySet(types.number)
27
+ * ```
28
+ *
29
+ * @template T Value type.
30
+ * @param valueType Value type.
31
+ * @returns
32
+ */
33
+ export function typesArraySet<T extends AnyType>(valueType: T): ModelType<ArraySet<TypeToData<T>>> {
34
+ const typeInfoGen: TypeInfoGen = (t) => new ArraySetTypeInfo(t, resolveStandardType(valueType))
35
+
36
+ return lateTypeChecker(() => {
37
+ const modelInfo = modelInfoByClass.get(ArraySet)!
38
+
39
+ const valueChecker = resolveTypeChecker(valueType)
40
+ const valueSupport = resolveCodecSupport(valueType)
41
+ const storedValueChecker = resolveTypeChecker(valueSupport.storedType)
42
+
43
+ const getTypeName = (...recursiveTypeCheckers: TypeChecker[]) =>
44
+ `ArraySet<${valueChecker.getTypeName(...recursiveTypeCheckers, valueChecker)}>`
45
+
46
+ const dataTypeChecker = typesObject(() => ({
47
+ items: typesArray(valueSupport.storedType as any),
48
+ }))
49
+
50
+ const thisTc: TypeChecker = new TypeChecker(
51
+ TypeCheckerBaseType.Object, // because it is really a model
52
+
53
+ (obj, path, typeCheckedValue) => {
54
+ if (!(obj instanceof ArraySet)) {
55
+ return new TypeCheckError({
56
+ path,
57
+ expectedTypeName: getTypeName(thisTc),
58
+ actualValue: obj,
59
+ typeCheckedValue,
60
+ })
61
+ }
62
+
63
+ const resolvedTc = resolveTypeChecker(dataTypeChecker)
64
+ return resolvedTc.check(obj.$, path, typeCheckedValue)
65
+ },
66
+
67
+ getTypeName,
68
+ typeInfoGen,
69
+
70
+ (obj) => {
71
+ if (!isObject(obj)) {
72
+ return null
73
+ }
74
+
75
+ if (obj[modelTypeKey] !== undefined) {
76
+ // fast check
77
+ return obj[modelTypeKey] === modelInfo.name ? thisTc : null
78
+ }
79
+
80
+ const resolvedTc = resolveTypeChecker(dataTypeChecker)
81
+ return resolvedTc.snapshotType(obj) ? thisTc : null
82
+ },
83
+
84
+ (sn: { items: unknown[] }) => {
85
+ const items = withErrorPathSegment("items", () =>
86
+ sn.items.map((v, i) =>
87
+ withErrorPathSegment(i, () => storedValueChecker.fromSnapshotProcessor(v))
88
+ )
89
+ )
90
+
91
+ return {
92
+ ...sn,
93
+ [modelTypeKey]: modelInfo.name,
94
+ items,
95
+ }
96
+ },
97
+
98
+ (sn: { items: unknown[]; [modelTypeKey]?: string }) => {
99
+ const items = withErrorPathSegment("items", () =>
100
+ sn.items.map((v, i) =>
101
+ withErrorPathSegment(i, () => storedValueChecker.toSnapshotProcessor(v))
102
+ )
103
+ )
104
+
105
+ const snCopy = {
106
+ ...sn,
107
+ items,
108
+ }
109
+
110
+ return snCopy
111
+ }
112
+ )
113
+
114
+ return thisTc
115
+ }, typeInfoGen) as any
116
+ }
117
+
118
+ /**
119
+ * `types.arraySet` type info.
120
+ */
121
+ export class ArraySetTypeInfo extends TypeInfo {
122
+ readonly kind = "arraySet"
123
+ readonly valueType: AnyStandardType
124
+
125
+ get valueTypeInfo(): TypeInfo {
126
+ return getTypeInfo(this.valueType)
127
+ }
128
+
129
+ constructor(originalType: AnyStandardType, valueType: AnyStandardType) {
130
+ super(originalType)
131
+ this.valueType = valueType
132
+ }
133
+ }
@@ -1,204 +1,203 @@
1
- import type { O } from "ts-toolbelt"
2
- import type { AnyDataModel } from "../../dataModel/BaseDataModel"
3
- import { getDataModelMetadata } from "../../dataModel/getDataModelMetadata"
4
- import { isDataModelClass } from "../../dataModel/utils"
5
- import type {
6
- ModelClass,
7
- ModelData,
8
- ModelUntransformedData,
9
- } from "../../modelShared/BaseModelShared"
10
- import { modelInfoByClass } from "../../modelShared/modelInfo"
11
- import { getInternalModelClassPropsInfo } from "../../modelShared/modelPropsInfo"
12
- import { noDefaultValue } from "../../modelShared/prop"
13
- import { failure, lazy } from "../../utils"
14
- import { getTypeInfo } from "../getTypeInfo"
15
- import { registerStandardTypeResolver, resolveTypeChecker } from "../resolveTypeChecker"
16
- import type { AnyStandardType, IdentityType } from "../schemas"
17
- import {
18
- lateTypeChecker,
19
- TypeChecker,
20
- TypeCheckerBaseType,
21
- TypeInfo,
22
- TypeInfoGen,
23
- } from "../TypeChecker"
24
-
25
- const cachedDataModelTypeChecker = new WeakMap<ModelClass<AnyDataModel>, TypeChecker>()
26
- const dataModelDataStandardTypes = new WeakSet<object>()
27
-
28
- type _Class<T> = abstract new (...args: any[]) => T
29
- type _ClassOrObject<M, K> = K extends M ? object : _Class<K> | (() => _Class<K>)
30
-
31
- /**
32
- * A type that represents a data model data.
33
- * The type referenced in the model decorator will be used for type checking.
34
- *
35
- * Example:
36
- * ```ts
37
- * const someDataModelDataType = types.dataModelData(SomeModel)
38
- * // or for recursive models
39
- * const someDataModelDataType = types.dataModelData<SomeModel>(() => SomeModel)
40
- * ```
41
- *
42
- * @template M Data model type.
43
- * @param modelClass Model class.
44
- * @returns
45
- */
46
- export function typesDataModelData<M = never, K = M>(
47
- modelClass: _ClassOrObject<M, K>
48
- ): IdentityType<
49
- | ModelUntransformedData<
50
- K extends M ? (M extends AnyDataModel ? M : never) : K extends AnyDataModel ? K : never
51
- >
52
- | ModelData<
53
- K extends M ? (M extends AnyDataModel ? M : never) : K extends AnyDataModel ? K : never
54
- >
55
- > {
56
- // if we type it any stronger then recursive defs and so on stop working
57
-
58
- if (!isDataModelClass(modelClass) && typeof modelClass === "function") {
59
- // resolve later
60
- const modelClassFn = modelClass as () => ModelClass<AnyDataModel>
61
- const typeInfoGen: TypeInfoGen = (t) => new DataModelDataTypeInfo(t, modelClassFn())
62
- const tc = lateTypeChecker(() => typesDataModelData(modelClassFn()) as any, typeInfoGen) as any
63
- dataModelDataStandardTypes.add(tc as object)
64
- return tc
65
- } else {
66
- const modelClazz: ModelClass<AnyDataModel> = modelClass as any
67
-
68
- const cachedTypeChecker = cachedDataModelTypeChecker.get(modelClazz)
69
- if (cachedTypeChecker) {
70
- return cachedTypeChecker as any
71
- }
72
-
73
- const typeInfoGen: TypeInfoGen = (t) => new DataModelDataTypeInfo(t, modelClazz)
74
-
75
- const tc = lateTypeChecker(() => {
76
- const modelInfo = modelInfoByClass.get(modelClazz)!
77
- const typeName = `DataModelData(${modelInfo.name})`
78
-
79
- const dataTypeChecker = getDataModelMetadata(modelClazz).dataType
80
- if (!dataTypeChecker) {
81
- throw failure(
82
- `type checking cannot be performed over data model data of type '${modelInfo.name}' since that model type has no data type declared, consider adding a data type or using types.unchecked() instead`
83
- )
84
- }
85
-
86
- const resolvedDataTypeChecker = resolveTypeChecker(dataTypeChecker)
87
-
88
- const thisTc: TypeChecker = new TypeChecker(
89
- TypeCheckerBaseType.Object,
90
-
91
- (value, path, typeCheckedValue) => {
92
- return resolvedDataTypeChecker.check(value, path, typeCheckedValue)
93
- },
94
-
95
- () => typeName,
96
- typeInfoGen,
97
-
98
- (value) => {
99
- return resolvedDataTypeChecker.snapshotType(value) ? thisTc : null
100
- },
101
-
102
- (sn: Record<string, unknown>) => {
103
- return resolvedDataTypeChecker.fromSnapshotProcessor(sn)
104
- },
105
-
106
- (sn: Record<string, unknown>) => {
107
- return resolvedDataTypeChecker.toSnapshotProcessor(sn)
108
- }
109
- )
110
-
111
- return thisTc
112
- }, typeInfoGen) as any
113
-
114
- cachedDataModelTypeChecker.set(modelClazz, tc)
115
- dataModelDataStandardTypes.add(tc as object)
116
-
117
- return tc
118
- }
119
- }
120
-
121
- /**
122
- * `types.dataModelData` type info for a model props.
123
- */
124
- export interface DataModelDataTypeInfoProps {
125
- readonly [propName: string]: Readonly<{
126
- type: AnyStandardType | undefined
127
- typeInfo: TypeInfo | undefined
128
- hasDefault: boolean
129
- default: any
130
- }>
131
- }
132
-
133
- /**
134
- * `types.dataModelData` type info.
135
- */
136
- export class DataModelDataTypeInfo extends TypeInfo {
137
- readonly kind = "dataModelData"
138
-
139
- private _props = lazy(() => {
140
- const objSchema = getInternalModelClassPropsInfo(this.modelClass)
141
-
142
- const propTypes: O.Writable<DataModelDataTypeInfoProps> = {}
143
- Object.keys(objSchema).forEach((propName) => {
144
- const propData = objSchema[propName]
145
-
146
- const type = propData._typeChecker
147
-
148
- let typeInfo: TypeInfo | undefined
149
- if (type) {
150
- typeInfo = getTypeInfo(type)
151
- }
152
-
153
- let hasDefault = false
154
- let defaultValue: any
155
- if (propData._defaultFn !== noDefaultValue) {
156
- defaultValue = propData._defaultFn
157
- hasDefault = true
158
- } else if (propData._defaultValue !== noDefaultValue) {
159
- defaultValue = propData._defaultValue
160
- hasDefault = true
161
- }
162
-
163
- propTypes[propName] = {
164
- type,
165
- typeInfo,
166
- hasDefault,
167
- default: defaultValue,
168
- }
169
- })
170
- return propTypes
171
- })
172
-
173
- get props(): DataModelDataTypeInfoProps {
174
- return this._props()
175
- }
176
-
177
- get modelType(): string {
178
- const modelInfo = modelInfoByClass.get(this.modelClass)!
179
- return modelInfo.name
180
- }
181
-
182
- constructor(
183
- thisType: AnyStandardType,
184
- readonly modelClass: ModelClass<AnyDataModel>
185
- ) {
186
- super(thisType)
187
- }
188
- }
189
-
190
- /**
191
- * @internal
192
- */
193
- export function registerDataModelDataStandardTypeResolver() {
194
- registerStandardTypeResolver((v) => (isDataModelClass(v) ? typesDataModelData(v) : undefined))
195
- }
196
-
197
- /**
198
- * @internal
199
- */
200
- export function isDataModelDataStandardType(value: unknown): boolean {
201
- return typeof value === "object" || typeof value === "function"
202
- ? dataModelDataStandardTypes.has(value as object)
203
- : false
204
- }
1
+ import type { O } from "ts-toolbelt"
2
+ import type { AnyDataModel } from "../../dataModel/BaseDataModel"
3
+ import { getDataModelMetadata } from "../../dataModel/getDataModelMetadata"
4
+ import { isDataModelClass } from "../../dataModel/utils"
5
+ import type {
6
+ ModelClass,
7
+ ModelData,
8
+ ModelUntransformedData,
9
+ } from "../../modelShared/BaseModelShared"
10
+ import { modelInfoByClass } from "../../modelShared/modelInfo"
11
+ import { getInternalModelClassPropsInfo } from "../../modelShared/modelPropsInfo"
12
+ import { noDefaultValue } from "../../modelShared/prop"
13
+ import { failure, lazy } from "../../utils"
14
+ import { getTypeInfo } from "../getTypeInfo"
15
+ import { registerStandardTypeResolver, resolveTypeChecker } from "../resolveTypeChecker"
16
+ import type { AnyStandardType, IdentityType } from "../schemas"
17
+ import {
18
+ lateTypeChecker,
19
+ TypeChecker,
20
+ TypeCheckerBaseType,
21
+ TypeInfo,
22
+ type TypeInfoGen,
23
+ } from "../TypeChecker"
24
+
25
+ const cachedDataModelTypeChecker = new WeakMap<ModelClass<AnyDataModel>, TypeChecker>()
26
+ const dataModelDataStandardTypes = new WeakSet<object>()
27
+
28
+ type _Class<T> = abstract new (...args: any[]) => T
29
+ type _ClassOrObject<M, K> = K extends M ? object : _Class<K> | (() => _Class<K>)
30
+
31
+ /**
32
+ * A type that represents a data model data.
33
+ * The type referenced in the model decorator will be used for type checking.
34
+ *
35
+ * Example:
36
+ * ```ts
37
+ * const someDataModelDataType = types.dataModelData(SomeModel)
38
+ * // or for recursive models
39
+ * const someDataModelDataType = types.dataModelData<SomeModel>(() => SomeModel)
40
+ * ```
41
+ *
42
+ * @template M Data model type.
43
+ * @param modelClass Model class.
44
+ * @returns
45
+ */
46
+ export function typesDataModelData<M = never, K = M>(
47
+ modelClass: _ClassOrObject<M, K>
48
+ ): IdentityType<
49
+ | ModelUntransformedData<
50
+ K extends M ? (M extends AnyDataModel ? M : never) : K extends AnyDataModel ? K : never
51
+ >
52
+ | ModelData<
53
+ K extends M ? (M extends AnyDataModel ? M : never) : K extends AnyDataModel ? K : never
54
+ >
55
+ > {
56
+ // if we type it any stronger then recursive defs and so on stop working
57
+
58
+ if (!isDataModelClass(modelClass) && typeof modelClass === "function") {
59
+ // resolve later
60
+ const modelClassFn = modelClass as () => ModelClass<AnyDataModel>
61
+ const typeInfoGen: TypeInfoGen = (t) => new DataModelDataTypeInfo(t, modelClassFn())
62
+ const tc = lateTypeChecker(() => typesDataModelData(modelClassFn()) as any, typeInfoGen) as any
63
+ dataModelDataStandardTypes.add(tc as object)
64
+ return tc
65
+ } else {
66
+ const modelClazz: ModelClass<AnyDataModel> = modelClass as any
67
+
68
+ const cachedTypeChecker = cachedDataModelTypeChecker.get(modelClazz)
69
+ if (cachedTypeChecker) {
70
+ return cachedTypeChecker as any
71
+ }
72
+
73
+ const typeInfoGen: TypeInfoGen = (t) => new DataModelDataTypeInfo(t, modelClazz)
74
+
75
+ const tc = lateTypeChecker(() => {
76
+ const modelInfo = modelInfoByClass.get(modelClazz)!
77
+ const typeName = `DataModelData(${modelInfo.name})`
78
+
79
+ const dataTypeChecker = getDataModelMetadata(modelClazz).dataType
80
+ if (!dataTypeChecker) {
81
+ throw failure(
82
+ `type checking cannot be performed over data model data of type '${modelInfo.name}' since that model type has no data type declared, consider adding a data type or using types.unchecked() instead`
83
+ )
84
+ }
85
+
86
+ const resolvedDataTypeChecker = resolveTypeChecker(dataTypeChecker)
87
+
88
+ const thisTc: TypeChecker = new TypeChecker(
89
+ TypeCheckerBaseType.Object,
90
+
91
+ (value, path, typeCheckedValue) => {
92
+ return resolvedDataTypeChecker.check(value, path, typeCheckedValue)
93
+ },
94
+
95
+ () => typeName,
96
+ typeInfoGen,
97
+
98
+ (value) => {
99
+ return resolvedDataTypeChecker.snapshotType(value) ? thisTc : null
100
+ },
101
+
102
+ (sn: Record<string, unknown>) => {
103
+ return resolvedDataTypeChecker.fromSnapshotProcessor(sn)
104
+ },
105
+
106
+ (sn: Record<string, unknown>) => {
107
+ return resolvedDataTypeChecker.toSnapshotProcessor(sn)
108
+ }
109
+ )
110
+
111
+ return thisTc
112
+ }, typeInfoGen) as any
113
+
114
+ cachedDataModelTypeChecker.set(modelClazz, tc)
115
+ dataModelDataStandardTypes.add(tc as object)
116
+
117
+ return tc
118
+ }
119
+ }
120
+
121
+ /**
122
+ * `types.dataModelData` type info for a model props.
123
+ */
124
+ export interface DataModelDataTypeInfoProps {
125
+ readonly [propName: string]: Readonly<{
126
+ type: AnyStandardType | undefined
127
+ typeInfo: TypeInfo | undefined
128
+ hasDefault: boolean
129
+ default: any
130
+ }>
131
+ }
132
+
133
+ /**
134
+ * `types.dataModelData` type info.
135
+ */
136
+ export class DataModelDataTypeInfo extends TypeInfo {
137
+ readonly kind = "dataModelData"
138
+ readonly modelClass: ModelClass<AnyDataModel>
139
+
140
+ private _props = lazy(() => {
141
+ const objSchema = getInternalModelClassPropsInfo(this.modelClass)
142
+
143
+ const propTypes: O.Writable<DataModelDataTypeInfoProps> = {}
144
+ Object.keys(objSchema).forEach((propName) => {
145
+ const propData = objSchema[propName]
146
+
147
+ const type = propData._typeChecker
148
+
149
+ let typeInfo: TypeInfo | undefined
150
+ if (type) {
151
+ typeInfo = getTypeInfo(type)
152
+ }
153
+
154
+ let hasDefault = false
155
+ let defaultValue: any
156
+ if (propData._defaultFn !== noDefaultValue) {
157
+ defaultValue = propData._defaultFn
158
+ hasDefault = true
159
+ } else if (propData._defaultValue !== noDefaultValue) {
160
+ defaultValue = propData._defaultValue
161
+ hasDefault = true
162
+ }
163
+
164
+ propTypes[propName] = {
165
+ type,
166
+ typeInfo,
167
+ hasDefault,
168
+ default: defaultValue,
169
+ }
170
+ })
171
+ return propTypes
172
+ })
173
+
174
+ get props(): DataModelDataTypeInfoProps {
175
+ return this._props()
176
+ }
177
+
178
+ get modelType(): string {
179
+ const modelInfo = modelInfoByClass.get(this.modelClass)!
180
+ return modelInfo.name
181
+ }
182
+
183
+ constructor(thisType: AnyStandardType, modelClass: ModelClass<AnyDataModel>) {
184
+ super(thisType)
185
+ this.modelClass = modelClass
186
+ }
187
+ }
188
+
189
+ /**
190
+ * @internal
191
+ */
192
+ export function registerDataModelDataStandardTypeResolver() {
193
+ registerStandardTypeResolver((v) => (isDataModelClass(v) ? typesDataModelData(v) : undefined))
194
+ }
195
+
196
+ /**
197
+ * @internal
198
+ */
199
+ export function isDataModelDataStandardType(value: unknown): boolean {
200
+ return typeof value === "object" || typeof value === "function"
201
+ ? dataModelDataStandardTypes.has(value as object)
202
+ : false
203
+ }