mobx-keystone 1.25.0 → 2.1.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 +145 -0
- package/dist/mobx-keystone.esm.js +3627 -1540
- package/dist/mobx-keystone.esm.mjs +3627 -1540
- package/dist/mobx-keystone.umd.js +3638 -1543
- package/dist/types/actionMiddlewares/actionSerialization/dateSerializer.d.ts +1 -1
- package/dist/types/actionMiddlewares/transactionMiddleware.d.ts +1 -1
- package/dist/types/actionMiddlewares/undoMiddleware.d.ts +17 -10
- package/dist/types/dataModel/dataModelInstanceCache.d.ts +1 -0
- package/dist/types/deepChange/onDeepChange.d.ts +9 -0
- package/dist/types/parent/arrayPaths.d.ts +1 -0
- package/dist/types/parent/detach.d.ts +1 -1
- package/dist/types/parent/findChildren.d.ts +1 -1
- package/dist/types/parent/treeOrder.d.ts +1 -0
- package/dist/types/patch/applyPatches.d.ts +3 -0
- package/dist/types/redux/connectReduxDevTools.d.ts +2 -1
- package/dist/types/ref/modelRefIdIndex.d.ts +1 -0
- package/dist/types/ref/nodesById.d.ts +1 -0
- package/dist/types/ref/refIdIndex.d.ts +1 -0
- package/dist/types/snapshot/SnapshotOf.d.ts +2 -2
- package/dist/types/snapshot/applySnapshot.d.ts +1 -0
- package/dist/types/snapshot/fromSnapshot.d.ts +0 -3
- package/dist/types/standardActions/arrayActions.d.ts +1 -1
- package/dist/types/treeUtils/sandbox.d.ts +0 -4
- package/dist/types/tweaker/changeRollback.d.ts +1 -0
- package/dist/types/tweaker/tweakedChangeListeners.d.ts +1 -0
- package/dist/types/types/TypeCheckError.d.ts +1 -0
- package/dist/types/types/utility/typesRefinement.d.ts +2 -2
- package/dist/types/utils/ModelPool.d.ts +7 -1
- package/dist/types/utils/chunks.d.ts +1 -0
- package/dist/types/utils/forEachWithDelayedThrow.d.ts +1 -0
- package/dist/types/utils/index.d.ts +13 -0
- package/dist/types/utils/mapUtils.d.ts +2 -2
- package/dist/types/utils/setLike.d.ts +1 -0
- package/package.json +2 -2
- package/src/action/applyAction.ts +1 -1
- package/src/action/middleware.ts +17 -36
- package/src/action/modelFlow.ts +4 -5
- package/src/action/mutationBatch.ts +10 -10
- package/src/action/pendingActions.ts +3 -4
- package/src/actionMiddlewares/actionSerialization/actionSerialization.ts +19 -14
- package/src/actionMiddlewares/actionSerialization/applySerializedAction.ts +29 -20
- package/src/actionMiddlewares/actionSerialization/arraySerializer.ts +1 -1
- package/src/actionMiddlewares/actionSerialization/dateSerializer.ts +4 -3
- package/src/actionMiddlewares/actionSerialization/mapSerializer.ts +4 -12
- package/src/actionMiddlewares/actionSerialization/setSerializer.ts +4 -13
- package/src/actionMiddlewares/actionTrackingMiddleware.ts +11 -13
- package/src/actionMiddlewares/transactionMiddleware.ts +55 -25
- package/src/actionMiddlewares/undoMiddleware.ts +112 -59
- package/src/actionMiddlewares/utils.ts +2 -1
- package/src/computedTree/computedTree.ts +14 -3
- package/src/context/context.ts +17 -45
- package/src/dataModel/BaseDataModel.ts +20 -16
- package/src/dataModel/dataModelInstanceCache.ts +8 -0
- package/src/deepChange/onDeepChange.ts +179 -24
- package/src/frozen/Frozen.ts +50 -33
- package/src/model/BaseModel.ts +10 -13
- package/src/model/newModel.ts +21 -24
- package/src/model/utils.ts +2 -2
- package/src/modelShared/modelClassInitializer.ts +3 -2
- package/src/modelShared/modelDecorator.ts +39 -39
- package/src/modelShared/modelInfo.ts +1 -1
- package/src/modelShared/prop.ts +6 -9
- package/src/modelShared/sharedInternalModel.ts +16 -3
- package/src/parent/arrayPaths.ts +242 -0
- package/src/parent/coreObjectChildren.ts +300 -48
- package/src/parent/detach.ts +1 -1
- package/src/parent/findChildren.ts +4 -7
- package/src/parent/onChildAttachedTo.ts +157 -55
- package/src/parent/path.ts +15 -5
- package/src/parent/setParent.ts +34 -15
- package/src/parent/treeOrder.ts +53 -0
- package/src/parent/walkTree.ts +12 -101
- package/src/patch/applyPatches.ts +74 -34
- package/src/patch/emitPatch.ts +142 -26
- package/src/patch/jsonPatch.ts +5 -0
- package/src/patch/patchRecorder.ts +18 -14
- package/src/redux/connectReduxDevTools.ts +24 -18
- package/src/redux/redux.ts +5 -21
- package/src/ref/core.ts +81 -29
- package/src/ref/modelRefIdIndex.ts +131 -0
- package/src/ref/nodesById.ts +60 -0
- package/src/ref/refIdIndex.ts +209 -0
- package/src/rootStore/attachDetach.ts +27 -16
- package/src/rootStore/rootStore.ts +10 -6
- package/src/snapshot/SnapshotOf.ts +2 -2
- package/src/snapshot/applySnapshot.ts +27 -19
- package/src/snapshot/clone.ts +1 -2
- package/src/snapshot/cloneTreeValue.ts +1 -2
- package/src/snapshot/fromModelSnapshot.ts +6 -2
- package/src/snapshot/fromPlainObjectSnapshot.ts +3 -8
- package/src/snapshot/fromSnapshot.ts +2 -6
- package/src/snapshot/internal.ts +89 -19
- package/src/snapshot/onSnapshot.ts +12 -1
- package/src/snapshot/reconcileModelSnapshot.ts +6 -6
- package/src/snapshot/reconcilePlainObjectSnapshot.ts +5 -4
- package/src/standardActions/arrayActions.ts +12 -2
- package/src/standardActions/objectActions.ts +3 -2
- package/src/transforms/ImmutableDate.ts +4 -0
- package/src/transforms/asMap.ts +3 -1
- package/src/treeUtils/deepEquals.ts +15 -13
- package/src/treeUtils/draft.ts +8 -0
- package/src/treeUtils/sandbox.ts +31 -27
- package/src/tweaker/changeRollback.ts +218 -0
- package/src/tweaker/core.ts +33 -22
- package/src/tweaker/treeNodeMetadata.ts +12 -2
- package/src/tweaker/tweak.ts +183 -19
- package/src/tweaker/tweakArray.ts +176 -33
- package/src/tweaker/tweakPlainObject.ts +117 -39
- package/src/tweaker/tweakedChangeListeners.ts +61 -0
- package/src/tweaker/typeChecking.ts +25 -15
- package/src/types/TypeCheckError.ts +17 -19
- package/src/types/arrayBased/typesArray.ts +10 -11
- package/src/types/createCachedTypeCheck.ts +541 -88
- package/src/types/objectBased/typesDataModelData.ts +4 -2
- package/src/types/objectBased/typesModel.ts +4 -2
- package/src/types/objectBased/typesObject.ts +20 -16
- package/src/types/objectBased/typesRecord.ts +8 -18
- package/src/types/objectBased/typesRef.ts +2 -2
- package/src/types/primitiveBased/typesEnum.ts +4 -2
- package/src/types/primitiveBased/typesPrimitive.ts +9 -4
- package/src/types/typeCheckErrorUtils.ts +1 -0
- package/src/types/utility/typesCodecSupport.ts +97 -56
- package/src/types/utility/typesMap.ts +24 -41
- package/src/types/utility/typesRefinement.ts +3 -2
- package/src/types/utility/typesSet.ts +24 -0
- package/src/utils/ModelPool.ts +78 -22
- package/src/utils/chainFns.ts +4 -0
- package/src/utils/chunks.ts +271 -0
- package/src/utils/decorators.ts +1 -1
- package/src/utils/errorDiagnostics.ts +6 -2
- package/src/utils/forEachWithDelayedThrow.ts +83 -0
- package/src/utils/index.ts +71 -2
- package/src/utils/mapUtils.ts +3 -7
- package/src/utils/setIfDifferent.ts +3 -2
- package/src/utils/setLike.ts +134 -0
- package/src/wrappers/ArraySet.ts +5 -9
- package/src/wrappers/ObjectMap.ts +15 -11
- package/src/wrappers/asMap.ts +30 -18
- package/src/wrappers/asSet.ts +36 -12
- package/dist/types/action/modelFlowPromiseGenerator.d.ts +0 -1
- package/src/action/modelFlowPromiseGenerator.ts +0 -127
|
@@ -7,6 +7,7 @@ import { fastGetParent } from "../parent/path"
|
|
|
7
7
|
import { internalApplyPatches } from "../patch/applyPatches"
|
|
8
8
|
import type { InternalPatchRecorder } from "../patch/emitPatch"
|
|
9
9
|
import { internalApplySnapshot } from "../snapshot/applySnapshot"
|
|
10
|
+
import { deferModelTypeCheckToBatch } from "./changeRollback"
|
|
10
11
|
import { runWithoutSnapshotOrPatches } from "./core"
|
|
11
12
|
import { isTypeCheckingAllowed } from "./withoutTypeChecking"
|
|
12
13
|
|
|
@@ -34,14 +35,15 @@ function isModelWithTypeChecker(obj: object): obj is AnyModel {
|
|
|
34
35
|
* @internal
|
|
35
36
|
*
|
|
36
37
|
* Walks up parent chain from `obj`, calling `callback` for each typed model
|
|
37
|
-
*
|
|
38
|
+
* including the target itself (nearest-first / bottom-up). Stops if the callback throws.
|
|
38
39
|
*/
|
|
39
|
-
function forEachTypedModelAncestor(obj: object, callback: (model: AnyModel) => void): void {
|
|
40
|
+
export function forEachTypedModelAncestor(obj: object, callback: (model: AnyModel) => void): void {
|
|
40
41
|
// obj might be a $ data object, so resolve to the model if applicable
|
|
41
42
|
const start = dataToModelNode(obj)
|
|
42
43
|
|
|
43
|
-
//
|
|
44
|
-
|
|
44
|
+
// Both model-data mutations and whole-model reconciliation must validate
|
|
45
|
+
// the model itself before checking its ancestors.
|
|
46
|
+
if (isModelWithTypeChecker(start)) {
|
|
45
47
|
callback(start)
|
|
46
48
|
}
|
|
47
49
|
|
|
@@ -76,20 +78,19 @@ export function runTypeCheckingAfterChange(
|
|
|
76
78
|
forEachTypedModelAncestor(obj, (model) => {
|
|
77
79
|
const err = model.typeCheck()
|
|
78
80
|
if (err) {
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
// intermediate state and attempt another rollback, causing infinite recursion.
|
|
81
|
+
// A rejected individual mutation has not updated its snapshot yet,
|
|
82
|
+
// so inverse patches must stay quiet. Snapshot reconciliation has
|
|
83
|
+
// already published changes: its rollback must update snapshots and
|
|
84
|
+
// emit compensating patches as well.
|
|
84
85
|
isRollingBackTypeCheckFailure = true
|
|
85
86
|
try {
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
if (patchRecorder) {
|
|
88
|
+
runWithoutSnapshotOrPatches(() => {
|
|
88
89
|
internalApplyPatches.call(obj, patchRecorder.invPatches, true)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
90
|
+
})
|
|
91
|
+
} else if (snapshotBeforeChanges) {
|
|
92
|
+
internalApplySnapshot.call(obj, snapshotBeforeChanges)
|
|
93
|
+
}
|
|
93
94
|
} finally {
|
|
94
95
|
isRollingBackTypeCheckFailure = false
|
|
95
96
|
}
|
|
@@ -98,3 +99,12 @@ export function runTypeCheckingAfterChange(
|
|
|
98
99
|
})
|
|
99
100
|
}
|
|
100
101
|
}
|
|
102
|
+
|
|
103
|
+
/** @internal Called only when automatic type checking is enabled. */
|
|
104
|
+
export function typeCheckAfterCreation(model: AnyModel): void {
|
|
105
|
+
// a change batch validates it once it completes
|
|
106
|
+
if (!deferModelTypeCheckToBatch(model)) {
|
|
107
|
+
const error = model.typeCheck()
|
|
108
|
+
if (error) error.throw()
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { dataToModelNode } from "../parent/core"
|
|
2
|
+
import { fastGetParent, fastGetRootPath } from "../parent/path"
|
|
2
3
|
import type { Path } from "../parent/pathTypes"
|
|
3
4
|
import { getSnapshot } from "../snapshot/getSnapshot"
|
|
4
5
|
import { isTweakedObject } from "../tweaker/core"
|
|
@@ -10,6 +11,7 @@ import {
|
|
|
10
11
|
} from "../utils/errorDiagnostics"
|
|
11
12
|
|
|
12
13
|
export interface TypeCheckErrorData {
|
|
14
|
+
/** Path relative to the value being type checked. */
|
|
13
15
|
path: Path
|
|
14
16
|
expectedTypeName: string
|
|
15
17
|
actualValue: any
|
|
@@ -71,8 +73,15 @@ export class TypeCheckError {
|
|
|
71
73
|
*/
|
|
72
74
|
throw(): never {
|
|
73
75
|
const diagnosticsPath = getErrorPathSnapshot()
|
|
76
|
+
const hasTreeParent =
|
|
77
|
+
isTweakedObject(this.typeCheckedValue, true) &&
|
|
78
|
+
fastGetParent(dataToModelNode(this.typeCheckedValue), false) !== undefined
|
|
79
|
+
// Attached values supply their location through the tree. Context supplies
|
|
80
|
+
// the location for detached values, such as models being hydrated.
|
|
74
81
|
const path =
|
|
75
|
-
diagnosticsPath && diagnosticsPath.length > 0
|
|
82
|
+
diagnosticsPath && diagnosticsPath.length > 0 && !hasTreeParent
|
|
83
|
+
? [...diagnosticsPath, ...this.path]
|
|
84
|
+
: this.path
|
|
76
85
|
|
|
77
86
|
throw new TypeCheckErrorFailure({
|
|
78
87
|
path,
|
|
@@ -146,7 +155,7 @@ function resolveTypeCheckErrorData(data: TypeCheckErrorData): {
|
|
|
146
155
|
const modelTrail = data.modelTrail ?? getErrorModelTrailSnapshot()
|
|
147
156
|
const fullPath = resolveFullPath(data.path, data.typeCheckedValue)
|
|
148
157
|
const actualValueSnapshot = isTweakedObject(data.actualValue, true)
|
|
149
|
-
? getSnapshot(data.actualValue)
|
|
158
|
+
? getSnapshot(dataToModelNode(data.actualValue))
|
|
150
159
|
: data.actualValue
|
|
151
160
|
|
|
152
161
|
return {
|
|
@@ -162,22 +171,11 @@ function resolveTypeCheckErrorData(data: TypeCheckErrorData): {
|
|
|
162
171
|
}
|
|
163
172
|
|
|
164
173
|
function resolveFullPath(path: Path, typeCheckedValue: any): Path {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
rootPath
|
|
168
|
-
|
|
169
|
-
return rootPath.length > 0 && !pathStartsWith(path, rootPath) ? [...rootPath, ...path] : path
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function pathStartsWith(path: Path, prefix: Path): boolean {
|
|
173
|
-
if (prefix.length > path.length) {
|
|
174
|
-
return false
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
for (let i = 0; i < prefix.length; i++) {
|
|
178
|
-
if (path[i] !== prefix[i]) {
|
|
179
|
-
return false
|
|
174
|
+
if (isTweakedObject(typeCheckedValue, true)) {
|
|
175
|
+
const rootPath = fastGetRootPath(dataToModelNode(typeCheckedValue), false).path
|
|
176
|
+
if (rootPath.length > 0) {
|
|
177
|
+
return [...rootPath, ...path]
|
|
180
178
|
}
|
|
181
179
|
}
|
|
182
|
-
return
|
|
180
|
+
return path
|
|
183
181
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Path } from "../../parent/pathTypes"
|
|
2
2
|
import { isArray } from "../../utils"
|
|
3
3
|
import { withErrorPathSegment } from "../../utils/errorDiagnostics"
|
|
4
|
-
import {
|
|
4
|
+
import { createChunkedArrayCachedCheck } from "../createCachedTypeCheck"
|
|
5
5
|
import { getTypeInfo } from "../getTypeInfo"
|
|
6
6
|
import { resolveStandardType, resolveTypeChecker } from "../resolveTypeChecker"
|
|
7
7
|
import type { AnyStandardType, AnyType, ArrayType } from "../schemas"
|
|
@@ -38,18 +38,17 @@ export function typesArray<T extends AnyType>(itemType: T): ArrayType<T[]> {
|
|
|
38
38
|
const getTypeName = (...recursiveTypeCheckers: TypeChecker[]) =>
|
|
39
39
|
`Array<${itemChecker.getTypeName(...recursiveTypeCheckers, itemChecker)}>`
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return prependPathElementToTypeCheckError(error, path, index, typeCheckedValue)
|
|
41
|
+
const checkArrayItems = createChunkedArrayCachedCheck(
|
|
42
|
+
(items, firstIndex, path, typeCheckedValue) => {
|
|
43
|
+
for (let i = 0; i < items.length; i++) {
|
|
44
|
+
const error = itemChecker.check(items[i], emptyChildPath, typeCheckedValue)
|
|
45
|
+
if (error) {
|
|
46
|
+
return prependPathElementToTypeCheckError(error, path, firstIndex + i, typeCheckedValue)
|
|
47
|
+
}
|
|
49
48
|
}
|
|
49
|
+
return null
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
})
|
|
51
|
+
)
|
|
53
52
|
|
|
54
53
|
const thisTc: TypeChecker = new TypeChecker(
|
|
55
54
|
TypeCheckerBaseType.Array,
|