mobx-keystone 2.1.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +1 -1
- package/dist/mobx-keystone.esm.js +555 -516
- package/dist/mobx-keystone.esm.mjs +555 -516
- package/dist/mobx-keystone.umd.js +558 -519
- package/dist/types/actionMiddlewares/undoMiddleware.d.ts +2 -10
- package/dist/types/modelShared/modelDecorator.d.ts +5 -2
- package/dist/types/modelShared/prop.d.ts +42 -29
- package/dist/types/ref/Ref.d.ts +1 -4
- package/dist/types/snapshot/SnapshotOf.d.ts +4 -4
- package/dist/types/snapshot/applySnapshot.d.ts +1 -1
- package/dist/types/snapshot/fromSnapshot.d.ts +2 -2
- package/dist/types/snapshot/getSnapshot.d.ts +1 -1
- package/dist/types/types/SnapshotTypeMismatchError.d.ts +3 -1
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/modelTypeMatching.d.ts +1 -0
- package/dist/types/types/schemas.d.ts +41 -37
- package/dist/types/types/tProp.d.ts +12 -6
- package/dist/types/types/types.d.ts +6 -6
- package/dist/types/types/utility/typeToStoredData.d.ts +14 -10
- package/dist/types/types/utility/typesCodecCore.d.ts +3 -0
- package/dist/types/utils/ModelPool.d.ts +0 -1
- package/dist/types/utils/types.d.ts +6 -0
- package/dist/types/wrappers/ArraySet.d.ts +1 -0
- package/package.json +13 -11
- package/src/action/modelFlow.ts +35 -66
- package/src/actionMiddlewares/actionTrackingMiddleware.ts +41 -71
- package/src/actionMiddlewares/transactionMiddleware.ts +1 -1
- package/src/actionMiddlewares/undoMiddleware.ts +16 -22
- package/src/context/context.ts +15 -36
- package/src/dataModel/utils.ts +5 -28
- package/src/deepChange/onDeepChange.ts +44 -126
- package/src/model/BaseModel.ts +1 -1
- package/src/model/utils.ts +5 -10
- package/src/modelShared/modelDecorator.ts +13 -10
- package/src/modelShared/modelInfo.ts +75 -0
- package/src/modelShared/prop.ts +115 -111
- package/src/modelShared/sharedInternalModel.ts +2 -2
- package/src/parent/arrayPaths.ts +1 -4
- package/src/parent/path.ts +0 -10
- package/src/patch/patchRecorder.ts +13 -28
- package/src/ref/core.ts +6 -19
- package/src/rootStore/rootStore.ts +1 -3
- package/src/snapshot/SnapshotOf.ts +24 -48
- package/src/snapshot/applySnapshot.ts +1 -1
- package/src/snapshot/fromSnapshot.ts +10 -3
- package/src/snapshot/getSnapshot.ts +1 -1
- package/src/snapshot/internal.ts +0 -2
- package/src/snapshot/reconcileModelSnapshot.ts +5 -3
- package/src/snapshot/reconcilePlainObjectSnapshot.ts +3 -1
- package/src/treeUtils/draft.ts +6 -1
- package/src/treeUtils/sandbox.ts +10 -7
- package/src/tweaker/tweakArray.ts +20 -50
- package/src/tweaker/tweakPlainObject.ts +9 -15
- package/src/types/SnapshotTypeMismatchError.ts +3 -1
- package/src/types/arrayBased/typesArray.ts +13 -19
- package/src/types/arrayBased/typesTuple.ts +16 -25
- package/src/types/createCachedTypeCheck.ts +17 -30
- package/src/types/index.ts +1 -0
- package/src/types/modelTypeMatching.ts +276 -0
- package/src/types/objectBased/typesDataModelData.ts +7 -8
- package/src/types/objectBased/typesModel.ts +23 -6
- package/src/types/objectBased/typesObject.ts +11 -15
- package/src/types/objectBased/typesRecord.ts +11 -15
- package/src/types/objectBased/typesRef.ts +23 -4
- package/src/types/schemas.ts +59 -71
- package/src/types/tProp.ts +29 -29
- package/src/types/utility/typeToStoredData.ts +22 -21
- package/src/types/utility/typesCodecCore.ts +8 -1
- package/src/types/utility/typesCodecSupport.ts +16 -10
- package/src/types/utility/typesMap.ts +43 -51
- package/src/types/utility/typesOr.ts +38 -8
- package/src/types/utility/typesRefinement.ts +7 -8
- package/src/types/utility/typesSkipCheck.ts +7 -8
- package/src/types/utility/typesTag.ts +7 -8
- package/src/utils/ModelPool.ts +1 -18
- package/src/utils/decorators.ts +5 -5
- package/src/utils/index.ts +1 -20
- package/src/utils/types.ts +5 -0
- package/src/wrappers/ArraySet.ts +27 -14
- package/src/wrappers/ObjectMap.ts +1 -6
- package/src/wrappers/asMap.ts +1 -21
- package/src/wrappers/asSet.ts +0 -8
package/src/action/modelFlow.ts
CHANGED
|
@@ -65,68 +65,53 @@ export function flow<R, Args extends any[]>({
|
|
|
65
65
|
const genThrow = gen.throw!.bind(gen)
|
|
66
66
|
|
|
67
67
|
const promise = new Promise<R>((resolve, reject) => {
|
|
68
|
-
function
|
|
68
|
+
function finish(
|
|
69
|
+
stepType: ActionContextAsyncStepType,
|
|
70
|
+
resolution: FlowFinisher["resolution"],
|
|
71
|
+
value: unknown
|
|
72
|
+
): void {
|
|
73
|
+
wrapInAction({
|
|
74
|
+
nameOrNameFn: name,
|
|
75
|
+
// we use a flow finisher to allow middlewares to tweak the return value before resolution
|
|
76
|
+
fn: (val: any): FlowFinisher => ({
|
|
77
|
+
value: val,
|
|
78
|
+
resolution,
|
|
79
|
+
accepter: resolve,
|
|
80
|
+
rejecter: reject,
|
|
81
|
+
}),
|
|
82
|
+
actionType: ActionContextActionType.Async,
|
|
83
|
+
overrideContext: ctxOverride(stepType),
|
|
84
|
+
isFlowFinisher: true,
|
|
85
|
+
}).call(target, value)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function resume(
|
|
89
|
+
genFn: (value: any) => IteratorResult<any>,
|
|
90
|
+
stepType: ActionContextAsyncStepType,
|
|
91
|
+
value: unknown
|
|
92
|
+
): void {
|
|
69
93
|
let ret: unknown
|
|
70
94
|
try {
|
|
71
95
|
ret = wrapInAction({
|
|
72
96
|
nameOrNameFn: name,
|
|
73
|
-
fn:
|
|
97
|
+
fn: genFn,
|
|
74
98
|
actionType: ActionContextActionType.Async,
|
|
75
|
-
overrideContext: ctxOverride(
|
|
76
|
-
}).call(target,
|
|
99
|
+
overrideContext: ctxOverride(stepType),
|
|
100
|
+
}).call(target, value)
|
|
77
101
|
} catch (e) {
|
|
78
|
-
|
|
79
|
-
nameOrNameFn: name,
|
|
80
|
-
fn: (err: any) => {
|
|
81
|
-
// we use a flow finisher to allow middlewares to tweak the return value before resolution
|
|
82
|
-
return {
|
|
83
|
-
value: err,
|
|
84
|
-
resolution: "reject",
|
|
85
|
-
|
|
86
|
-
accepter: resolve,
|
|
87
|
-
rejecter: reject,
|
|
88
|
-
} as FlowFinisher
|
|
89
|
-
},
|
|
90
|
-
actionType: ActionContextActionType.Async,
|
|
91
|
-
overrideContext: ctxOverride(ActionContextAsyncStepType.Throw),
|
|
92
|
-
isFlowFinisher: true,
|
|
93
|
-
}).call(target, e)
|
|
102
|
+
finish(ActionContextAsyncStepType.Throw, "reject", e)
|
|
94
103
|
return
|
|
95
104
|
}
|
|
96
105
|
|
|
97
106
|
next(ret)
|
|
98
107
|
}
|
|
99
108
|
|
|
100
|
-
function
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
ret = wrapInAction({
|
|
104
|
-
nameOrNameFn: name,
|
|
105
|
-
fn: genThrow,
|
|
106
|
-
actionType: ActionContextActionType.Async,
|
|
107
|
-
overrideContext: ctxOverride(ActionContextAsyncStepType.ResumeError),
|
|
108
|
-
}).call(target, err)
|
|
109
|
-
} catch (e) {
|
|
110
|
-
wrapInAction({
|
|
111
|
-
nameOrNameFn: name,
|
|
112
|
-
fn: (err: any) => {
|
|
113
|
-
// we use a flow finisher to allow middlewares to tweak the return value before resolution
|
|
114
|
-
return {
|
|
115
|
-
value: err,
|
|
116
|
-
resolution: "reject",
|
|
117
|
-
|
|
118
|
-
accepter: resolve,
|
|
119
|
-
rejecter: reject,
|
|
120
|
-
} as FlowFinisher
|
|
121
|
-
},
|
|
122
|
-
actionType: ActionContextActionType.Async,
|
|
123
|
-
overrideContext: ctxOverride(ActionContextAsyncStepType.Throw),
|
|
124
|
-
isFlowFinisher: true,
|
|
125
|
-
}).call(target, e)
|
|
126
|
-
return
|
|
127
|
-
}
|
|
109
|
+
function onFulfilled(res: unknown): void {
|
|
110
|
+
resume(genNext, ActionContextAsyncStepType.Resume, res)
|
|
111
|
+
}
|
|
128
112
|
|
|
129
|
-
|
|
113
|
+
function onRejected(err: unknown): void {
|
|
114
|
+
resume(genThrow, ActionContextAsyncStepType.ResumeError, err)
|
|
130
115
|
}
|
|
131
116
|
|
|
132
117
|
function next(ret: any): void {
|
|
@@ -134,23 +119,7 @@ export function flow<R, Args extends any[]>({
|
|
|
134
119
|
// an async iterator
|
|
135
120
|
Promise.resolve(ret).then(next, reject).catch(reject)
|
|
136
121
|
} else if (ret.done) {
|
|
137
|
-
|
|
138
|
-
wrapInAction({
|
|
139
|
-
nameOrNameFn: name,
|
|
140
|
-
fn: (val: any) => {
|
|
141
|
-
// we use a flow finisher to allow middlewares to tweak the return value before resolution
|
|
142
|
-
return {
|
|
143
|
-
value: val,
|
|
144
|
-
resolution: "accept",
|
|
145
|
-
|
|
146
|
-
accepter: resolve,
|
|
147
|
-
rejecter: reject,
|
|
148
|
-
} as FlowFinisher
|
|
149
|
-
},
|
|
150
|
-
actionType: ActionContextActionType.Async,
|
|
151
|
-
overrideContext: ctxOverride(ActionContextAsyncStepType.Return),
|
|
152
|
-
isFlowFinisher: true,
|
|
153
|
-
}).call(target, ret.value)
|
|
122
|
+
finish(ActionContextAsyncStepType.Return, "accept", ret.value)
|
|
154
123
|
} else {
|
|
155
124
|
// continue
|
|
156
125
|
Promise.resolve(ret.value).then(onFulfilled, onRejected).catch(reject)
|
|
@@ -178,8 +178,11 @@ export function actionTrackingMiddleware(
|
|
|
178
178
|
const resumeSuspendSupport = !!hooks.onResume || !!hooks.onSuspend
|
|
179
179
|
|
|
180
180
|
const filter: ActionMiddleware["filter"] = (ctx) => {
|
|
181
|
-
if (
|
|
182
|
-
|
|
181
|
+
if (
|
|
182
|
+
ctx.type === ActionContextActionType.Sync ||
|
|
183
|
+
ctx.asyncStepType === ActionContextAsyncStepType.Spawn
|
|
184
|
+
) {
|
|
185
|
+
// (for sync actions start and finish are on the same context)
|
|
183
186
|
const accepted = userFilter(ctx)
|
|
184
187
|
if (accepted) {
|
|
185
188
|
setCtxData(ctx, {
|
|
@@ -188,39 +191,21 @@ export function actionTrackingMiddleware(
|
|
|
188
191
|
})
|
|
189
192
|
}
|
|
190
193
|
return accepted
|
|
191
|
-
}
|
|
192
|
-
switch (ctx.asyncStepType) {
|
|
193
|
-
case ActionContextAsyncStepType.Spawn: {
|
|
194
|
-
const accepted = userFilter(ctx)
|
|
195
|
-
if (accepted) {
|
|
196
|
-
setCtxData(ctx, {
|
|
197
|
-
startAccepted: true,
|
|
198
|
-
state: State.Idle,
|
|
199
|
-
})
|
|
200
|
-
}
|
|
201
|
-
return accepted
|
|
202
|
-
}
|
|
194
|
+
}
|
|
203
195
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
196
|
+
// the other steps depend on whether the spawn one was accepted or not
|
|
197
|
+
const spawnAccepted = () => !!getCtxData(ctx.spawnAsyncStepContext!)?.startAccepted
|
|
198
|
+
switch (ctx.asyncStepType) {
|
|
199
|
+
case ActionContextAsyncStepType.Return:
|
|
200
|
+
case ActionContextAsyncStepType.Throw:
|
|
201
|
+
return spawnAccepted()
|
|
210
202
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
// depends if the spawn one was accepted or not
|
|
215
|
-
const data = getCtxData(ctx.spawnAsyncStepContext!)
|
|
216
|
-
return data ? data.startAccepted : false
|
|
217
|
-
} else {
|
|
218
|
-
return false
|
|
219
|
-
}
|
|
203
|
+
case ActionContextAsyncStepType.Resume:
|
|
204
|
+
case ActionContextAsyncStepType.ResumeError:
|
|
205
|
+
return resumeSuspendSupport && spawnAccepted()
|
|
220
206
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
207
|
+
default:
|
|
208
|
+
return false
|
|
224
209
|
}
|
|
225
210
|
}
|
|
226
211
|
|
|
@@ -311,57 +296,42 @@ export function actionTrackingMiddleware(
|
|
|
311
296
|
}
|
|
312
297
|
}
|
|
313
298
|
|
|
314
|
-
if (
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
299
|
+
if (
|
|
300
|
+
ctx.type === ActionContextActionType.Sync ||
|
|
301
|
+
ctx.asyncStepType === ActionContextAsyncStepType.Spawn
|
|
302
|
+
) {
|
|
303
|
+
const overriddenRetObj = start(simpleCtx)
|
|
304
|
+
if (overriddenRetObj) {
|
|
318
305
|
// action canceled / overridden by onStart
|
|
319
306
|
resume(simpleCtx, true)
|
|
320
307
|
suspend(simpleCtx)
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
retObj = finish(simpleCtx, retObj)
|
|
308
|
+
return returnOrThrowActionTrackingReturn(finish(simpleCtx, overriddenRetObj))
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (ctx.type !== ActionContextActionType.Sync) {
|
|
312
|
+
// a flow finishes in its return / throw step
|
|
313
|
+
return next()
|
|
329
314
|
}
|
|
330
315
|
|
|
331
|
-
|
|
316
|
+
let retObj: ActionTrackingReturn
|
|
317
|
+
try {
|
|
318
|
+
retObj = { result: ActionTrackingResult.Return, value: next() }
|
|
319
|
+
} catch (err) {
|
|
320
|
+
retObj = { result: ActionTrackingResult.Throw, value: err }
|
|
321
|
+
}
|
|
322
|
+
return returnOrThrowActionTrackingReturn(finish(simpleCtx, retObj))
|
|
332
323
|
} else {
|
|
333
324
|
// async
|
|
334
325
|
|
|
335
326
|
switch (ctx.asyncStepType) {
|
|
336
|
-
case ActionContextAsyncStepType.
|
|
337
|
-
let retObj = start(simpleCtx)
|
|
338
|
-
if (retObj) {
|
|
339
|
-
// action canceled / overridden by onStart
|
|
340
|
-
resume(simpleCtx, true)
|
|
341
|
-
suspend(simpleCtx)
|
|
342
|
-
retObj = finish(simpleCtx, retObj)
|
|
343
|
-
return returnOrThrowActionTrackingReturn(retObj)
|
|
344
|
-
} else {
|
|
345
|
-
return next()
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
case ActionContextAsyncStepType.Return: {
|
|
350
|
-
const flowFinisher: FlowFinisher = next()
|
|
351
|
-
const retObj = finish(simpleCtx, {
|
|
352
|
-
result: ActionTrackingResult.Return,
|
|
353
|
-
value: flowFinisher.value,
|
|
354
|
-
})
|
|
355
|
-
flowFinisher.resolution =
|
|
356
|
-
retObj.result === ActionTrackingResult.Return ? "accept" : "reject"
|
|
357
|
-
flowFinisher.value = retObj.value
|
|
358
|
-
return flowFinisher
|
|
359
|
-
}
|
|
360
|
-
|
|
327
|
+
case ActionContextAsyncStepType.Return:
|
|
361
328
|
case ActionContextAsyncStepType.Throw: {
|
|
362
329
|
const flowFinisher: FlowFinisher = next()
|
|
363
330
|
const retObj = finish(simpleCtx, {
|
|
364
|
-
result:
|
|
331
|
+
result:
|
|
332
|
+
ctx.asyncStepType === ActionContextAsyncStepType.Return
|
|
333
|
+
? ActionTrackingResult.Return
|
|
334
|
+
: ActionTrackingResult.Throw,
|
|
365
335
|
value: flowFinisher.value,
|
|
366
336
|
})
|
|
367
337
|
flowFinisher.resolution =
|
|
@@ -122,7 +122,7 @@ export function transaction(...args: any[]): void {
|
|
|
122
122
|
|
|
123
123
|
checkDecoratorContext("transaction", ctx.name, ctx.static)
|
|
124
124
|
if (ctx.kind !== "method" && ctx.kind !== "field") {
|
|
125
|
-
throw failure(`@transaction can only be used on fields or methods
|
|
125
|
+
throw failure(`@transaction can only be used on fields or methods`)
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
ctx.addInitializer(function (this: any) {
|
|
@@ -428,11 +428,11 @@ export class UndoManager {
|
|
|
428
428
|
const event = events[events.length - 1].data
|
|
429
429
|
|
|
430
430
|
withoutUndo(() => {
|
|
431
|
-
|
|
432
|
-
.
|
|
433
|
-
.
|
|
434
|
-
|
|
435
|
-
|
|
431
|
+
applyPatches(
|
|
432
|
+
this.subtreeRoot,
|
|
433
|
+
toSingleEvents(event).map((e) => e.inversePatches),
|
|
434
|
+
true
|
|
435
|
+
)
|
|
436
436
|
|
|
437
437
|
// restore the attached state before the operation was made
|
|
438
438
|
if (event.attachedState) {
|
|
@@ -456,9 +456,10 @@ export class UndoManager {
|
|
|
456
456
|
const event = events[events.length - 1].data
|
|
457
457
|
|
|
458
458
|
withoutUndo(() => {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
459
|
+
applyPatches(
|
|
460
|
+
this.subtreeRoot,
|
|
461
|
+
toSingleEvents(event).map((e) => e.patches)
|
|
462
|
+
)
|
|
462
463
|
|
|
463
464
|
// restore the attached state after the operation was made
|
|
464
465
|
if (event.attachedState) {
|
|
@@ -601,11 +602,11 @@ export class UndoManager {
|
|
|
601
602
|
const genThrow = gen.throw.bind(gen)
|
|
602
603
|
|
|
603
604
|
const promise = new Promise<R>((resolve, reject) => {
|
|
604
|
-
function
|
|
605
|
+
function resume(genFn: (value: any) => IteratorResult<any>, value: unknown): void {
|
|
605
606
|
group.resume()
|
|
606
607
|
let ret: unknown
|
|
607
608
|
try {
|
|
608
|
-
ret =
|
|
609
|
+
ret = genFn(value)
|
|
609
610
|
} catch (e) {
|
|
610
611
|
group.end()
|
|
611
612
|
reject(e as Error)
|
|
@@ -616,19 +617,12 @@ export class UndoManager {
|
|
|
616
617
|
next(ret)
|
|
617
618
|
}
|
|
618
619
|
|
|
619
|
-
function
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
try {
|
|
623
|
-
ret = genThrow(err)
|
|
624
|
-
} catch (e) {
|
|
625
|
-
group.end()
|
|
626
|
-
reject(e as Error)
|
|
627
|
-
return
|
|
628
|
-
}
|
|
620
|
+
function onFulfilled(res: unknown): void {
|
|
621
|
+
resume(genNext, res)
|
|
622
|
+
}
|
|
629
623
|
|
|
630
|
-
|
|
631
|
-
|
|
624
|
+
function onRejected(err: unknown): void {
|
|
625
|
+
resume(genThrow, err)
|
|
632
626
|
}
|
|
633
627
|
|
|
634
628
|
function next(ret: any): void {
|
package/src/context/context.ts
CHANGED
|
@@ -162,25 +162,19 @@ class ContextClass<T> implements Context<T> {
|
|
|
162
162
|
})
|
|
163
163
|
})
|
|
164
164
|
|
|
165
|
-
|
|
166
|
-
assertTweakedObject(node, "node")
|
|
167
|
-
|
|
168
|
-
this.nodeContextValue.set(node, {
|
|
169
|
-
type: "value",
|
|
170
|
-
value,
|
|
171
|
-
})
|
|
172
|
-
this.reportNodeAtomChanged(node)
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
private _setComputed(node: object, computedValueFn: IComputedValue<T>) {
|
|
165
|
+
private setNodeContextValue(node: object, contextValue: ContextValue<T>) {
|
|
176
166
|
assertTweakedObject(node, "node")
|
|
177
167
|
|
|
178
|
-
this.nodeContextValue.set(node,
|
|
168
|
+
this.nodeContextValue.set(node, contextValue)
|
|
179
169
|
this.reportNodeAtomChanged(node)
|
|
180
170
|
}
|
|
181
171
|
|
|
172
|
+
set = action((node: object, value: T) => {
|
|
173
|
+
this.setNodeContextValue(node, { type: "value", value })
|
|
174
|
+
})
|
|
175
|
+
|
|
182
176
|
setComputed = action((node: object, valueFn: () => T) => {
|
|
183
|
-
this.
|
|
177
|
+
this.setNodeContextValue(node, { type: "computed", value: computed(valueFn) })
|
|
184
178
|
})
|
|
185
179
|
|
|
186
180
|
unset = action((node: object) => {
|
|
@@ -190,42 +184,27 @@ class ContextClass<T> implements Context<T> {
|
|
|
190
184
|
this.reportNodeAtomChanged(node)
|
|
191
185
|
})
|
|
192
186
|
|
|
193
|
-
|
|
187
|
+
private applyOverride<R>(fn: () => R, contextValue: ContextValue<T>): R {
|
|
194
188
|
const old = this.overrideContextValue.get()
|
|
195
|
-
this.overrideContextValue.set(
|
|
196
|
-
type: "value",
|
|
197
|
-
value,
|
|
198
|
-
})
|
|
189
|
+
this.overrideContextValue.set(contextValue)
|
|
199
190
|
|
|
200
191
|
try {
|
|
201
192
|
const ret = fn()
|
|
202
193
|
if (isTweakedObject(ret, false)) {
|
|
203
|
-
this.
|
|
194
|
+
this.setNodeContextValue(ret, contextValue)
|
|
204
195
|
}
|
|
205
196
|
return ret
|
|
206
197
|
} finally {
|
|
207
198
|
this.overrideContextValue.set(old)
|
|
208
199
|
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
apply = action(<R>(fn: () => R, value: T): R => {
|
|
203
|
+
return this.applyOverride(fn, { type: "value", value })
|
|
209
204
|
})
|
|
210
205
|
|
|
211
206
|
applyComputed = action(<R>(fn: () => R, valueFn: () => T): R => {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const old = this.overrideContextValue.get()
|
|
215
|
-
this.overrideContextValue.set({
|
|
216
|
-
type: "computed",
|
|
217
|
-
value: computedValueFn,
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
try {
|
|
221
|
-
const ret = fn()
|
|
222
|
-
if (isTweakedObject(ret, false)) {
|
|
223
|
-
this._setComputed(ret, computedValueFn)
|
|
224
|
-
}
|
|
225
|
-
return ret
|
|
226
|
-
} finally {
|
|
227
|
-
this.overrideContextValue.set(old)
|
|
228
|
-
}
|
|
207
|
+
return this.applyOverride(fn, { type: "computed", value: computed(valueFn) })
|
|
229
208
|
})
|
|
230
209
|
|
|
231
210
|
constructor(defaultValue?: T) {
|
package/src/dataModel/utils.ts
CHANGED
|
@@ -13,37 +13,14 @@ export function isDataModel(model: unknown): model is AnyDataModel {
|
|
|
13
13
|
return model instanceof BaseDataModel
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
/**
|
|
17
|
-
* @internal
|
|
18
|
-
*
|
|
19
|
-
* Asserts something is actually a data model.
|
|
20
|
-
*
|
|
21
|
-
* @param model
|
|
22
|
-
* @param argName
|
|
23
|
-
*/
|
|
24
|
-
export function assertIsDataModel(
|
|
25
|
-
model: unknown,
|
|
26
|
-
argName: string,
|
|
27
|
-
customErrMsg = "must be a data model instance"
|
|
28
|
-
): asserts model is AnyDataModel {
|
|
29
|
-
if (!isDataModel(model)) {
|
|
30
|
-
throw failure(`${argName} ${customErrMsg}`)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
16
|
/**
|
|
35
17
|
* @internal
|
|
36
18
|
*/
|
|
37
19
|
export function isDataModelClass(modelClass: unknown): modelClass is ModelClass<AnyDataModel> {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (modelClass !== BaseDataModel && !(modelClass.prototype instanceof BaseDataModel)) {
|
|
43
|
-
return false
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return true
|
|
20
|
+
return (
|
|
21
|
+
typeof modelClass === "function" &&
|
|
22
|
+
(modelClass === BaseDataModel || modelClass.prototype instanceof BaseDataModel)
|
|
23
|
+
)
|
|
47
24
|
}
|
|
48
25
|
|
|
49
26
|
/**
|
|
@@ -57,7 +34,7 @@ export function assertIsDataModelClass(
|
|
|
57
34
|
throw failure(`${argName} must be a class`)
|
|
58
35
|
}
|
|
59
36
|
|
|
60
|
-
if (
|
|
37
|
+
if (!isDataModelClass(modelClass)) {
|
|
61
38
|
throw failure(`${argName} must extend DataModel`)
|
|
62
39
|
}
|
|
63
40
|
}
|