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,45 +1,45 @@
1
- import { Path } from "../parent/pathTypes"
2
- import { MobxKeystoneError } from "../utils"
3
- import {
4
- buildErrorMessageWithDiagnostics,
5
- getErrorModelTrailSnapshot,
6
- getErrorPathSnapshot,
7
- noErrorValuePreview,
8
- } from "../utils/errorDiagnostics"
9
-
10
- export interface SnapshotProcessingErrorData {
11
- message: string
12
- path?: Path
13
- actualSnapshot?: any
14
- modelTrail?: readonly string[]
15
- }
16
-
17
- /**
18
- * Thrown when a structural issue is encountered while processing a snapshot (extends `MobxKeystoneError`).
19
- *
20
- * Use `instanceof SnapshotProcessingError` to distinguish snapshot processing errors
21
- * from other `MobxKeystoneError` instances.
22
- */
23
- export class SnapshotProcessingError extends MobxKeystoneError {
24
- readonly path: Path
25
- readonly actualSnapshot?: any
26
- readonly modelTrail?: readonly string[]
27
-
28
- constructor(data: SnapshotProcessingErrorData) {
29
- const path = data.path ?? getErrorPathSnapshot() ?? []
30
- const modelTrail = data.modelTrail ?? getErrorModelTrailSnapshot()
31
-
32
- super(
33
- buildErrorMessageWithDiagnostics({
34
- message: data.message,
35
- path,
36
- previewValue: "actualSnapshot" in data ? data.actualSnapshot : noErrorValuePreview,
37
- modelTrail,
38
- })
39
- )
40
-
41
- this.path = path
42
- this.actualSnapshot = data.actualSnapshot
43
- this.modelTrail = modelTrail
44
- }
45
- }
1
+ import type { Path } from "../parent/pathTypes"
2
+ import { MobxKeystoneError } from "../utils"
3
+ import {
4
+ buildErrorMessageWithDiagnostics,
5
+ getErrorModelTrailSnapshot,
6
+ getErrorPathSnapshot,
7
+ noErrorValuePreview,
8
+ } from "../utils/errorDiagnostics"
9
+
10
+ export interface SnapshotProcessingErrorData {
11
+ message: string
12
+ path?: Path
13
+ actualSnapshot?: any
14
+ modelTrail?: readonly string[]
15
+ }
16
+
17
+ /**
18
+ * Thrown when a structural issue is encountered while processing a snapshot (extends `MobxKeystoneError`).
19
+ *
20
+ * Use `instanceof SnapshotProcessingError` to distinguish snapshot processing errors
21
+ * from other `MobxKeystoneError` instances.
22
+ */
23
+ export class SnapshotProcessingError extends MobxKeystoneError {
24
+ readonly path: Path
25
+ readonly actualSnapshot?: any
26
+ readonly modelTrail?: readonly string[]
27
+
28
+ constructor(data: SnapshotProcessingErrorData) {
29
+ const path = data.path ?? getErrorPathSnapshot() ?? []
30
+ const modelTrail = data.modelTrail ?? getErrorModelTrailSnapshot()
31
+
32
+ super(
33
+ buildErrorMessageWithDiagnostics({
34
+ message: data.message,
35
+ path,
36
+ previewValue: "actualSnapshot" in data ? data.actualSnapshot : noErrorValuePreview,
37
+ modelTrail,
38
+ })
39
+ )
40
+
41
+ this.path = path
42
+ this.actualSnapshot = data.actualSnapshot
43
+ this.modelTrail = modelTrail
44
+ }
45
+ }
@@ -1,181 +1,177 @@
1
- import { isObservableObject } from "mobx"
2
- import { BuiltInAction } from "../action/builtInActions"
3
- import { ActionContextActionType } from "../action/context"
4
- import { wrapInAction } from "../action/wrapInAction"
5
- import { isFrozenSnapshot } from "../frozen/Frozen"
6
- import type { AnyModel } from "../model/BaseModel"
7
- import { getModelIdPropertyName } from "../model/getModelMetadata"
8
- import { modelIdKey, modelTypeKey } from "../model/metadata"
9
- import { getSnapshotModelType, isModel } from "../model/utils"
10
- import type { ModelClass } from "../modelShared/BaseModelShared"
11
- import {
12
- getModelInfoForName,
13
- getModelNotRegisteredErrorMessage,
14
- modelInfoByClass,
15
- } from "../modelShared/modelInfo"
16
- import { assertTweakedObject } from "../tweaker/core"
17
- import { assertIsObject, inDevMode, isArray, isMap, isPlainObject, isSet, lazy } from "../utils"
18
- import {
19
- runWithErrorDiagnosticsContext,
20
- } from "../utils/errorDiagnostics"
21
- import { ModelPool } from "../utils/ModelPool"
22
- import { reconcileSnapshot } from "./reconcileSnapshot"
23
- import type { SnapshotInOf, SnapshotOutOf } from "./SnapshotOf"
24
- import { SnapshotProcessingError } from "./SnapshotProcessingError"
25
-
26
- /**
27
- * Applies a full snapshot over an object, reconciling it with the current contents of the object.
28
- *
29
- * @template T Object type.
30
- * @param node Target object (model object, object or array).
31
- * @param snapshot Snapshot to apply.
32
- */
33
- export function applySnapshot<T extends object>(
34
- node: T,
35
- snapshot: SnapshotInOf<T> | SnapshotOutOf<T>
36
- ): void
37
-
38
- export function applySnapshot(node: object, snapshot: unknown): void {
39
- assertTweakedObject(node, "node")
40
- assertIsObject(snapshot, "snapshot")
41
-
42
- runWithErrorDiagnosticsContext(() => {
43
- wrappedInternalApplySnapshot().call(node, snapshot)
44
- })
45
- }
46
-
47
- /**
48
- * @internal
49
- */
50
- export function internalApplySnapshot<T extends object>(
51
- this: T,
52
- sn: SnapshotInOf<T> | SnapshotOutOf<T>
53
- ): void {
54
- const obj = this
55
-
56
- const reconcile = () => {
57
- const modelPool = new ModelPool(obj)
58
- const ret = reconcileSnapshot(obj, sn, modelPool, undefined)
59
-
60
- if (inDevMode) {
61
- if (ret !== obj) {
62
- throw new SnapshotProcessingError({
63
- message: "assertion failed: reconciled object has to be the same",
64
- actualSnapshot: sn,
65
- })
66
- }
67
- }
68
- }
69
-
70
- if (isArray(sn)) {
71
- if (!isArray(obj)) {
72
- throw new SnapshotProcessingError({
73
- message: "if the snapshot is an array the target must be an array too",
74
- actualSnapshot: sn,
75
- })
76
- }
77
-
78
- reconcile()
79
- return
80
- }
81
-
82
- if (isFrozenSnapshot(sn)) {
83
- throw new SnapshotProcessingError({
84
- message: "applySnapshot cannot be used over frozen objects",
85
- actualSnapshot: sn,
86
- })
87
- }
88
-
89
- // adapt snapshot to target model if possible
90
- if (isPlainObject(sn) && (sn as any)[modelTypeKey] === undefined && isModel(obj)) {
91
- const modelInfo = modelInfoByClass.get((obj as any).constructor)!
92
- sn = { ...sn, [modelTypeKey]: modelInfo.name }
93
- }
94
-
95
- const modelType = getSnapshotModelType(sn)
96
- if (modelType !== undefined) {
97
- const modelInfo = getModelInfoForName(modelType)
98
- if (!modelInfo) {
99
- throw new SnapshotProcessingError({
100
- message: getModelNotRegisteredErrorMessage(modelType),
101
- actualSnapshot: sn,
102
- })
103
- }
104
-
105
- // we don't check by actual instance since the class might be a different one due to hot reloading
106
- if (!isModel(obj)) {
107
- // not a model instance, no reconciliation possible
108
- throw new SnapshotProcessingError({
109
- message: "the target for a model snapshot must be a model instance",
110
- actualSnapshot: sn,
111
- })
112
- }
113
-
114
- if (obj[modelTypeKey] !== modelType) {
115
- // different kind of model, no reconciliation possible
116
- throw new SnapshotProcessingError({
117
- message: `snapshot model type '${modelType}' does not match target model type '${
118
- (obj as any)[modelTypeKey]
119
- }'`,
120
- actualSnapshot: sn,
121
- })
122
- }
123
-
124
- const modelIdPropertyName = getModelIdPropertyName(modelInfo.class as ModelClass<AnyModel>)
125
- if (modelIdPropertyName) {
126
- const id = (sn as any)[modelIdPropertyName]
127
- if (obj[modelIdKey] !== id) {
128
- // different id, no reconciliation possible
129
- throw new SnapshotProcessingError({
130
- message: `snapshot model id '${id}' does not match target model id '${
131
- obj[modelIdKey]
132
- }'`,
133
- actualSnapshot: sn,
134
- })
135
- }
136
- }
137
-
138
- reconcile()
139
- return
140
- }
141
-
142
- if (isPlainObject(sn)) {
143
- if (!(isPlainObject(obj) || isObservableObject(obj))) {
144
- // no reconciliation possible
145
- throw new SnapshotProcessingError({
146
- message: "if the snapshot is an object the target must be an object too",
147
- actualSnapshot: sn,
148
- })
149
- }
150
-
151
- reconcile()
152
- return
153
- }
154
-
155
- if (isMap(sn)) {
156
- throw new SnapshotProcessingError({
157
- message: "a snapshot must not contain maps",
158
- actualSnapshot: sn,
159
- })
160
- }
161
-
162
- if (isSet(sn)) {
163
- throw new SnapshotProcessingError({
164
- message: "a snapshot must not contain sets",
165
- actualSnapshot: sn,
166
- })
167
- }
168
-
169
- throw new SnapshotProcessingError({
170
- message: "unsupported snapshot",
171
- actualSnapshot: sn,
172
- })
173
- }
174
-
175
- const wrappedInternalApplySnapshot = lazy(() =>
176
- wrapInAction({
177
- nameOrNameFn: BuiltInAction.ApplySnapshot,
178
- fn: internalApplySnapshot,
179
- actionType: ActionContextActionType.Sync,
180
- })
181
- )
1
+ import { isObservableObject } from "mobx"
2
+ import { BuiltInAction } from "../action/builtInActions"
3
+ import { ActionContextActionType } from "../action/context"
4
+ import { wrapInAction } from "../action/wrapInAction"
5
+ import { isFrozenSnapshot } from "../frozen/Frozen"
6
+ import type { AnyModel } from "../model/BaseModel"
7
+ import { getModelIdPropertyName } from "../model/getModelMetadata"
8
+ import { modelIdKey, modelTypeKey } from "../model/metadata"
9
+ import { getSnapshotModelType, isModel } from "../model/utils"
10
+ import type { ModelClass } from "../modelShared/BaseModelShared"
11
+ import {
12
+ getModelInfoForName,
13
+ getModelNotRegisteredErrorMessage,
14
+ modelInfoByClass,
15
+ } from "../modelShared/modelInfo"
16
+ import { assertTweakedObject } from "../tweaker/core"
17
+ import { assertIsObject, inDevMode, isArray, isMap, isPlainObject, isSet, lazy } from "../utils"
18
+ import { runWithErrorDiagnosticsContext } from "../utils/errorDiagnostics"
19
+ import { ModelPool } from "../utils/ModelPool"
20
+ import { reconcileSnapshot } from "./reconcileSnapshot"
21
+ import type { SnapshotInOf, SnapshotOutOf } from "./SnapshotOf"
22
+ import { SnapshotProcessingError } from "./SnapshotProcessingError"
23
+
24
+ /**
25
+ * Applies a full snapshot over an object, reconciling it with the current contents of the object.
26
+ *
27
+ * @template T Object type.
28
+ * @param node Target object (model object, object or array).
29
+ * @param snapshot Snapshot to apply.
30
+ */
31
+ export function applySnapshot<T extends object>(
32
+ node: T,
33
+ snapshot: SnapshotInOf<T> | SnapshotOutOf<T>
34
+ ): void
35
+
36
+ export function applySnapshot(node: object, snapshot: unknown): void {
37
+ assertTweakedObject(node, "node")
38
+ assertIsObject(snapshot, "snapshot")
39
+
40
+ runWithErrorDiagnosticsContext(() => {
41
+ wrappedInternalApplySnapshot().call(node, snapshot)
42
+ })
43
+ }
44
+
45
+ /**
46
+ * @internal
47
+ */
48
+ export function internalApplySnapshot<T extends object>(
49
+ this: T,
50
+ sn: SnapshotInOf<T> | SnapshotOutOf<T>
51
+ ): void {
52
+ const obj = this
53
+
54
+ const reconcile = () => {
55
+ const modelPool = new ModelPool(obj)
56
+ const ret = reconcileSnapshot(obj, sn, modelPool, undefined)
57
+
58
+ if (inDevMode) {
59
+ if (ret !== obj) {
60
+ throw new SnapshotProcessingError({
61
+ message: "assertion failed: reconciled object has to be the same",
62
+ actualSnapshot: sn,
63
+ })
64
+ }
65
+ }
66
+ }
67
+
68
+ if (isArray(sn)) {
69
+ if (!isArray(obj)) {
70
+ throw new SnapshotProcessingError({
71
+ message: "if the snapshot is an array the target must be an array too",
72
+ actualSnapshot: sn,
73
+ })
74
+ }
75
+
76
+ reconcile()
77
+ return
78
+ }
79
+
80
+ if (isFrozenSnapshot(sn)) {
81
+ throw new SnapshotProcessingError({
82
+ message: "applySnapshot cannot be used over frozen objects",
83
+ actualSnapshot: sn,
84
+ })
85
+ }
86
+
87
+ // adapt snapshot to target model if possible
88
+ if (isPlainObject(sn) && (sn as any)[modelTypeKey] === undefined && isModel(obj)) {
89
+ const modelInfo = modelInfoByClass.get((obj as any).constructor)!
90
+ sn = { ...sn, [modelTypeKey]: modelInfo.name }
91
+ }
92
+
93
+ const modelType = getSnapshotModelType(sn)
94
+ if (modelType !== undefined) {
95
+ const modelInfo = getModelInfoForName(modelType)
96
+ if (!modelInfo) {
97
+ throw new SnapshotProcessingError({
98
+ message: getModelNotRegisteredErrorMessage(modelType),
99
+ actualSnapshot: sn,
100
+ })
101
+ }
102
+
103
+ // we don't check by actual instance since the class might be a different one due to hot reloading
104
+ if (!isModel(obj)) {
105
+ // not a model instance, no reconciliation possible
106
+ throw new SnapshotProcessingError({
107
+ message: "the target for a model snapshot must be a model instance",
108
+ actualSnapshot: sn,
109
+ })
110
+ }
111
+
112
+ if (obj[modelTypeKey] !== modelType) {
113
+ // different kind of model, no reconciliation possible
114
+ throw new SnapshotProcessingError({
115
+ message: `snapshot model type '${modelType}' does not match target model type '${
116
+ (obj as any)[modelTypeKey]
117
+ }'`,
118
+ actualSnapshot: sn,
119
+ })
120
+ }
121
+
122
+ const modelIdPropertyName = getModelIdPropertyName(modelInfo.class as ModelClass<AnyModel>)
123
+ if (modelIdPropertyName) {
124
+ const id = (sn as any)[modelIdPropertyName]
125
+ if (obj[modelIdKey] !== id) {
126
+ // different id, no reconciliation possible
127
+ throw new SnapshotProcessingError({
128
+ message: `snapshot model id '${id}' does not match target model id '${obj[modelIdKey]}'`,
129
+ actualSnapshot: sn,
130
+ })
131
+ }
132
+ }
133
+
134
+ reconcile()
135
+ return
136
+ }
137
+
138
+ if (isPlainObject(sn)) {
139
+ if (!(isPlainObject(obj) || isObservableObject(obj))) {
140
+ // no reconciliation possible
141
+ throw new SnapshotProcessingError({
142
+ message: "if the snapshot is an object the target must be an object too",
143
+ actualSnapshot: sn,
144
+ })
145
+ }
146
+
147
+ reconcile()
148
+ return
149
+ }
150
+
151
+ if (isMap(sn)) {
152
+ throw new SnapshotProcessingError({
153
+ message: "a snapshot must not contain maps",
154
+ actualSnapshot: sn,
155
+ })
156
+ }
157
+
158
+ if (isSet(sn)) {
159
+ throw new SnapshotProcessingError({
160
+ message: "a snapshot must not contain sets",
161
+ actualSnapshot: sn,
162
+ })
163
+ }
164
+
165
+ throw new SnapshotProcessingError({
166
+ message: "unsupported snapshot",
167
+ actualSnapshot: sn,
168
+ })
169
+ }
170
+
171
+ const wrappedInternalApplySnapshot = lazy(() =>
172
+ wrapInAction({
173
+ nameOrNameFn: BuiltInAction.ApplySnapshot,
174
+ fn: internalApplySnapshot,
175
+ actionType: ActionContextActionType.Sync,
176
+ })
177
+ )
@@ -1,30 +1,30 @@
1
- import { isTweakedObject } from "../tweaker/core"
2
- import { isArray, isPlainObject, isPrimitive } from "../utils"
3
- import type { CloneOptions } from "./clone"
4
- import { clone } from "./clone"
5
- import { fromSnapshot } from "./fromSnapshot"
6
-
7
- /**
8
- * Clones non-primitive tree-compatible values.
9
- * Intended to be used with `withSetter(cloneTreeValue)`.
10
- */
11
- export function cloneTreeValue<T>(value: T, options?: Partial<CloneOptions>): T {
12
- const cloneOptions: CloneOptions = {
13
- generateNewIds: true,
14
- ...options,
15
- }
16
-
17
- if (isPrimitive(value)) {
18
- return value
19
- }
20
-
21
- if (isTweakedObject(value, false)) {
22
- return clone(value, cloneOptions) as T
23
- }
24
-
25
- if (isArray(value) || isPlainObject(value)) {
26
- return fromSnapshot(value as any, cloneOptions) as T
27
- }
28
-
29
- return value
30
- }
1
+ import { isTweakedObject } from "../tweaker/core"
2
+ import { isArray, isPlainObject, isPrimitive } from "../utils"
3
+ import type { CloneOptions } from "./clone"
4
+ import { clone } from "./clone"
5
+ import { fromSnapshot } from "./fromSnapshot"
6
+
7
+ /**
8
+ * Clones non-primitive tree-compatible values.
9
+ * Intended to be used with `withSetter(cloneTreeValue)`.
10
+ */
11
+ export function cloneTreeValue<T>(value: T, options?: Partial<CloneOptions>): T {
12
+ const cloneOptions: CloneOptions = {
13
+ generateNewIds: true,
14
+ ...options,
15
+ }
16
+
17
+ if (isPrimitive(value)) {
18
+ return value
19
+ }
20
+
21
+ if (isTweakedObject(value, false)) {
22
+ return clone(value, cloneOptions) as T
23
+ }
24
+
25
+ if (isArray(value) || isPlainObject(value)) {
26
+ return fromSnapshot(value as any, cloneOptions) as T
27
+ }
28
+
29
+ return value
30
+ }
@@ -1,33 +1,27 @@
1
- import { observable } from "mobx"
2
- import { tweakArray } from "../tweaker/tweakArray"
3
- import { isArray } from "../utils"
4
- import { withErrorPathSegment } from "../utils/errorDiagnostics"
5
- import {
6
- FromSnapshotContext,
7
- internalFromSnapshot,
8
- observableOptions,
9
- registerSnapshotter,
10
- } from "./fromSnapshot"
11
- import { SnapshotInOfObject } from "./SnapshotOf"
12
- import { SnapshotterAndReconcilerPriority } from "./SnapshotterAndReconcilerPriority"
13
-
14
- function fromArraySnapshot(sn: SnapshotInOfObject<any>, ctx: FromSnapshotContext): any[] {
15
- const arr = observable.array([] as any[], observableOptions)
16
- const ln = sn.length
17
- for (let i = 0; i < ln; i++) {
18
- arr.push(withErrorPathSegment(i, () => internalFromSnapshot(sn[i], ctx)))
19
- }
20
- return tweakArray(arr, undefined, true)
21
- }
22
-
23
- /**
24
- * @internal
25
- */
26
- export function registerFromArraySnapshotter() {
27
- registerSnapshotter(SnapshotterAndReconcilerPriority.Array, (sn, ctx) => {
28
- if (isArray(sn)) {
29
- return fromArraySnapshot(sn, ctx)
30
- }
31
- return undefined
32
- })
33
- }
1
+ import { tweakArray } from "../tweaker/tweakArray"
2
+ import { isArray } from "../utils"
3
+ import { withErrorPathSegment } from "../utils/errorDiagnostics"
4
+ import { type FromSnapshotContext, internalFromSnapshot, registerSnapshotter } from "./fromSnapshot"
5
+ import type { SnapshotInOfObject } from "./SnapshotOf"
6
+ import { SnapshotterAndReconcilerPriority } from "./SnapshotterAndReconcilerPriority"
7
+
8
+ function fromArraySnapshot(sn: SnapshotInOfObject<any>, ctx: FromSnapshotContext): any[] {
9
+ const ln = sn.length
10
+ const arr: any[] = new Array(ln)
11
+ for (let i = 0; i < ln; i++) {
12
+ arr[i] = withErrorPathSegment(i, () => internalFromSnapshot(sn[i], ctx))
13
+ }
14
+ return tweakArray(arr, undefined, true)
15
+ }
16
+
17
+ /**
18
+ * @internal
19
+ */
20
+ export function registerFromArraySnapshotter() {
21
+ registerSnapshotter(SnapshotterAndReconcilerPriority.Array, (sn, ctx) => {
22
+ if (isArray(sn)) {
23
+ return fromArraySnapshot(sn, ctx)
24
+ }
25
+ return undefined
26
+ })
27
+ }