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.
- package/CHANGELOG.md +864 -853
- package/README.md +61 -61
- package/dist/mobx-keystone.esm.js +11336 -11148
- package/dist/mobx-keystone.esm.mjs +11336 -11148
- package/dist/mobx-keystone.umd.js +12229 -11738
- package/dist/types/actionMiddlewares/undoMiddleware.d.ts +1 -1
- package/dist/types/modelShared/prop.d.ts +5 -0
- package/dist/types/redux/connectReduxDevTools.d.ts +17 -4
- package/dist/types/ref/Ref.d.ts +1 -1
- package/dist/types/treeUtils/sandbox.d.ts +1 -1
- package/dist/types/types/TypeChecker.d.ts +1 -1
- package/dist/types/types/arrayBased/typesArray.d.ts +1 -1
- package/dist/types/types/arrayBased/typesTuple.d.ts +1 -1
- package/dist/types/types/objectBased/typesArraySet.d.ts +1 -1
- package/dist/types/types/objectBased/typesDataModelData.d.ts +1 -1
- package/dist/types/types/objectBased/typesModel.d.ts +1 -1
- package/dist/types/types/objectBased/typesObject.d.ts +3 -3
- package/dist/types/types/objectBased/typesObjectMap.d.ts +1 -1
- package/dist/types/types/objectBased/typesRecord.d.ts +1 -1
- package/dist/types/types/primitiveBased/typesPrimitive.d.ts +1 -1
- package/dist/types/types/types.d.ts +3 -3
- package/dist/types/types/utility/typesCodec.d.ts +1 -6
- package/dist/types/types/utility/typesCodecCore.d.ts +1 -1
- package/dist/types/types/utility/typesOr.d.ts +1 -1
- package/dist/types/types/utility/typesRefinement.d.ts +1 -1
- package/dist/types/types/utility/typesSkipCheck.d.ts +1 -1
- package/dist/types/types/utility/typesTag.d.ts +1 -1
- package/dist/types/wrappers/ObjectMap.d.ts +2 -0
- package/dist/types/wrappers/asMap.d.ts +10 -6
- package/package.json +14 -12
- package/src/action/applyAction.ts +125 -114
- package/src/action/applyMethodCall.ts +37 -37
- package/src/action/isModelAction.ts +16 -16
- package/src/action/middleware.ts +137 -137
- package/src/action/modelFlow.ts +240 -240
- package/src/action/modelFlowPromiseGenerator.ts +127 -125
- package/src/action/pendingActions.ts +42 -42
- package/src/action/wrapInAction.ts +156 -156
- package/src/actionMiddlewares/actionSerialization/actionSerialization.ts +1 -1
- package/src/actionMiddlewares/actionSerialization/applySerializedAction.ts +172 -172
- package/src/actionMiddlewares/actionSerialization/arraySerializer.ts +20 -20
- package/src/actionMiddlewares/actionSerialization/dateSerializer.ts +17 -17
- package/src/actionMiddlewares/actionSerialization/mapSerializer.ts +42 -42
- package/src/actionMiddlewares/actionSerialization/objectPathSerializer.ts +50 -50
- package/src/actionMiddlewares/actionSerialization/objectSnapshotSerializer.ts +21 -21
- package/src/actionMiddlewares/actionSerialization/plainObjectSerializer.ts +24 -32
- package/src/actionMiddlewares/actionSerialization/primitiveSerializer.ts +51 -51
- package/src/actionMiddlewares/actionSerialization/setSerializer.ts +37 -37
- package/src/actionMiddlewares/actionTrackingMiddleware.ts +3 -3
- package/src/actionMiddlewares/onActionMiddleware.ts +2 -2
- package/src/actionMiddlewares/readonlyMiddleware.ts +2 -2
- package/src/actionMiddlewares/transactionMiddleware.ts +4 -4
- package/src/actionMiddlewares/undoMiddleware.ts +804 -796
- package/src/actionMiddlewares/utils.ts +2 -2
- package/src/computedTree/computedTree.ts +143 -143
- package/src/context/context.ts +1 -1
- package/src/dataModel/BaseDataModel.ts +194 -192
- package/src/dataModel/actions.ts +1 -1
- package/src/dataModel/newDataModel.ts +57 -57
- package/src/deepChange/index.ts +1 -1
- package/src/deepChange/onDeepChange.ts +244 -244
- package/src/frozen/Frozen.ts +146 -146
- package/src/globalConfig/globalConfig.ts +107 -107
- package/src/index.ts +24 -24
- package/src/model/BaseModel.ts +275 -273
- package/src/model/ModelConstructorOptions.ts +15 -15
- package/src/model/getModelMetadata.ts +51 -51
- package/src/model/index.ts +6 -6
- package/src/model/mixins.ts +288 -288
- package/src/model/newModel.ts +301 -301
- package/src/model/utils.ts +249 -249
- package/src/modelShared/modelDecorator.ts +260 -253
- package/src/modelShared/modelInfo.ts +50 -50
- package/src/modelShared/modelSymbols.ts +3 -3
- package/src/modelShared/newModel.ts +25 -25
- package/src/modelShared/prop.ts +713 -684
- package/src/modelShared/sharedInternalModel.ts +427 -417
- package/src/modelShared/utils.ts +24 -24
- package/src/parent/core.ts +65 -65
- package/src/parent/coreObjectChildren.ts +180 -180
- package/src/parent/detach.ts +47 -47
- package/src/parent/findParent.ts +1 -1
- package/src/parent/getChildrenObjects.ts +25 -25
- package/src/parent/path.ts +386 -381
- package/src/parent/setParent.ts +149 -149
- package/src/parent/walkTree.ts +1 -1
- package/src/patch/applyPatches.ts +187 -187
- package/src/patch/jsonPatch.ts +108 -108
- package/src/patch/patchRecorder.ts +6 -1
- package/src/redux/connectReduxDevTools.ts +39 -7
- package/src/redux/redux.ts +6 -2
- package/src/ref/Ref.ts +1 -1
- package/src/ref/core.ts +339 -345
- package/src/ref/customRef.ts +3 -3
- package/src/ref/rootRef.ts +100 -100
- package/src/rootStore/attachDetach.ts +89 -89
- package/src/rootStore/rootStore.ts +1 -1
- package/src/snapshot/SnapshotOf.ts +104 -104
- package/src/snapshot/SnapshotProcessingError.ts +45 -45
- package/src/snapshot/applySnapshot.ts +177 -181
- package/src/snapshot/cloneTreeValue.ts +30 -30
- package/src/snapshot/fromArraySnapshot.ts +27 -33
- package/src/snapshot/fromModelSnapshot.ts +70 -70
- package/src/snapshot/fromPlainObjectSnapshot.ts +47 -42
- package/src/snapshot/fromSnapshot.ts +198 -198
- package/src/snapshot/getSnapshot.ts +80 -79
- package/src/snapshot/index.ts +8 -8
- package/src/snapshot/internal.ts +230 -230
- package/src/snapshot/reconcileArraySnapshot.ts +70 -70
- package/src/snapshot/reconcileModelSnapshot.ts +155 -150
- package/src/snapshot/reconcilePlainObjectSnapshot.ts +72 -72
- package/src/snapshot/reconcileSnapshot.ts +88 -88
- package/src/standardActions/actions.ts +64 -64
- package/src/standardActions/objectActions.ts +60 -60
- package/src/transforms/ImmutableDate.ts +93 -93
- package/src/transforms/asMap.ts +50 -50
- package/src/transforms/asSet.ts +22 -22
- package/src/transforms/bigint.ts +20 -20
- package/src/transforms/date.ts +40 -40
- package/src/treeUtils/deepEquals.ts +55 -55
- package/src/treeUtils/sandbox.ts +6 -3
- package/src/tweaker/TweakerPriority.ts +9 -9
- package/src/tweaker/tweak.ts +4 -3
- package/src/tweaker/tweakArray.ts +530 -475
- package/src/tweaker/tweakFrozen.ts +42 -42
- package/src/tweaker/tweakModel.ts +1 -1
- package/src/tweaker/tweakPlainObject.ts +355 -355
- package/src/tweaker/typeChecking.ts +101 -101
- package/src/types/SnapshotTypeMismatchError.ts +46 -46
- package/src/types/TypeCheckError.ts +183 -184
- package/src/types/TypeChecker.ts +202 -185
- package/src/types/arrayBased/typesArray.ts +136 -137
- package/src/types/arrayBased/typesTuple.ts +138 -139
- package/src/types/createPerEntryCachedCheck.ts +166 -160
- package/src/types/index.ts +6 -6
- package/src/types/objectBased/typesArraySet.ts +133 -134
- package/src/types/objectBased/typesDataModelData.ts +203 -204
- package/src/types/objectBased/typesModel.ts +220 -221
- package/src/types/objectBased/typesObject.ts +308 -310
- package/src/types/objectBased/typesObjectMap.ts +142 -143
- package/src/types/objectBased/typesRecord.ts +156 -157
- package/src/types/objectBased/typesRef.ts +89 -89
- package/src/types/primitiveBased/typesEnum.ts +63 -63
- package/src/types/primitiveBased/typesPrimitive.ts +219 -220
- package/src/types/registerDefaultStandardTypeResolvers.ts +21 -21
- package/src/types/resolveTypeChecker.ts +78 -78
- package/src/types/schemas.ts +208 -208
- package/src/types/tProp.ts +277 -268
- package/src/types/typeCheck.ts +21 -21
- package/src/types/typeCheckErrorUtils.ts +23 -23
- package/src/types/types.ts +142 -142
- package/src/types/utility/typeToStoredData.ts +37 -37
- package/src/types/utility/typesBigInt.ts +15 -15
- package/src/types/utility/typesCodec.ts +41 -38
- package/src/types/utility/typesCodecCore.ts +178 -178
- package/src/types/utility/typesCodecSupport.ts +806 -806
- package/src/types/utility/typesDate.ts +27 -27
- package/src/types/utility/typesMap.ts +253 -222
- package/src/types/utility/typesOr.ts +263 -259
- package/src/types/utility/typesRefinement.ts +131 -125
- package/src/types/utility/typesSet.ts +110 -110
- package/src/types/utility/typesSkipCheck.ts +69 -70
- package/src/types/utility/typesTag.ts +88 -82
- package/src/types/utility/typesUnchecked.ts +40 -40
- package/src/utils/AnyFunction.ts +4 -4
- package/src/utils/ModelPool.ts +59 -59
- package/src/utils/chainFns.ts +18 -18
- package/src/utils/decorators.ts +274 -274
- package/src/utils/errorDiagnostics.ts +204 -204
- package/src/utils/index.ts +443 -372
- package/src/wrappers/ArraySet.ts +156 -156
- package/src/wrappers/ObjectMap.ts +155 -136
- package/src/wrappers/asMap.ts +65 -30
- package/src/wrappers/asSet.ts +3 -3
package/src/modelShared/prop.ts
CHANGED
|
@@ -1,684 +1,713 @@
|
|
|
1
|
-
import type { SnapshotInOf, SnapshotOutOf } from "../snapshot/SnapshotOf"
|
|
2
|
-
import type { AnyStandardType } from "../types/schemas"
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
$
|
|
31
|
-
$
|
|
32
|
-
$
|
|
33
|
-
$
|
|
34
|
-
$
|
|
35
|
-
$
|
|
36
|
-
$
|
|
37
|
-
$
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
TTransformedValue
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
>
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
>
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
$
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
export
|
|
232
|
-
[
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
export type
|
|
236
|
-
[
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
export type
|
|
240
|
-
[k in keyof MP]:
|
|
241
|
-
}>
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
>
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
[k in
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* Enables generation of a setter method for the ID prop
|
|
307
|
-
*/
|
|
308
|
-
withSetter(
|
|
309
|
-
/**
|
|
310
|
-
*
|
|
311
|
-
*/
|
|
312
|
-
withSetter(
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
return
|
|
352
|
-
},
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
| "$
|
|
390
|
-
| "$
|
|
391
|
-
| "$
|
|
392
|
-
| "$
|
|
393
|
-
| "$
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
obj
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
*
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
*
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
*
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
*
|
|
493
|
-
*
|
|
494
|
-
*
|
|
495
|
-
*
|
|
496
|
-
*
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
if (
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
const outerValue =
|
|
666
|
-
return
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
}
|
|
1
|
+
import type { SnapshotInOf, SnapshotOutOf } from "../snapshot/SnapshotOf"
|
|
2
|
+
import type { AnyStandardType } from "../types/schemas"
|
|
3
|
+
import { runWithErrorDiagnosticsContext, withErrorPathSegment } from "../utils/errorDiagnostics"
|
|
4
|
+
import { getOrCreate } from "../utils/mapUtils"
|
|
5
|
+
import type { Flatten, IsNeverType, IsOptionalValue } from "../utils/types"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @ignore
|
|
9
|
+
*/
|
|
10
|
+
export const noDefaultValue = Symbol("noDefaultValue")
|
|
11
|
+
|
|
12
|
+
type SetterMode = boolean | "assign"
|
|
13
|
+
|
|
14
|
+
export type ModelPropSetterValueTransform<T> = (value: T) => T
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A model property.
|
|
18
|
+
*/
|
|
19
|
+
export interface ModelProp<
|
|
20
|
+
TPropValue,
|
|
21
|
+
TPropCreationValue,
|
|
22
|
+
TTransformedValue,
|
|
23
|
+
TTransformedCreationValue,
|
|
24
|
+
TIsRequired,
|
|
25
|
+
TIsId extends boolean = false,
|
|
26
|
+
THasSetter = never,
|
|
27
|
+
TFromSnapshotOverride = never,
|
|
28
|
+
TToSnapshotOverride = never,
|
|
29
|
+
> {
|
|
30
|
+
$valueType: TPropValue
|
|
31
|
+
$creationValueType: TPropCreationValue
|
|
32
|
+
$transformedValueType: TTransformedValue
|
|
33
|
+
$transformedCreationValueType: TTransformedCreationValue
|
|
34
|
+
$isRequired: TIsRequired
|
|
35
|
+
$isId: TIsId
|
|
36
|
+
$hasSetter: THasSetter
|
|
37
|
+
$fromSnapshotOverride: TFromSnapshotOverride
|
|
38
|
+
$toSnapshotOverride: TToSnapshotOverride
|
|
39
|
+
|
|
40
|
+
_defaultFn: (() => TPropValue) | typeof noDefaultValue
|
|
41
|
+
_defaultValue: TPropValue | typeof noDefaultValue
|
|
42
|
+
// True when the declared default is a runtime/transformed value and must be
|
|
43
|
+
// converted before it can be stored in `$`.
|
|
44
|
+
_defaultValueIsTransformed: boolean
|
|
45
|
+
_typeChecker: AnyStandardType | undefined
|
|
46
|
+
_setter: SetterMode
|
|
47
|
+
_setterValueTransform: ((value: unknown) => unknown) | undefined
|
|
48
|
+
_isId: boolean
|
|
49
|
+
_idGenerator?: (() => string) | undefined
|
|
50
|
+
_transform:
|
|
51
|
+
| {
|
|
52
|
+
transform: (
|
|
53
|
+
original: unknown,
|
|
54
|
+
model: object,
|
|
55
|
+
propName: PropertyKey,
|
|
56
|
+
setOriginalValue: (newOriginalValue: unknown) => void
|
|
57
|
+
) => unknown
|
|
58
|
+
untransform: (transformed: unknown, model: object, propName: PropertyKey) => unknown
|
|
59
|
+
}
|
|
60
|
+
| undefined
|
|
61
|
+
_fromSnapshotProcessor?: (sn: unknown) => unknown
|
|
62
|
+
_toSnapshotProcessor?: (sn: unknown) => unknown
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Adds a setter to the property. The setter will be named `set${CapitalizedPropName}`
|
|
66
|
+
* and will be available in the model instance.
|
|
67
|
+
*/
|
|
68
|
+
withSetter(): ModelProp<
|
|
69
|
+
TPropValue,
|
|
70
|
+
TPropCreationValue,
|
|
71
|
+
TTransformedValue,
|
|
72
|
+
TTransformedCreationValue,
|
|
73
|
+
TIsRequired,
|
|
74
|
+
TIsId,
|
|
75
|
+
string,
|
|
76
|
+
TFromSnapshotOverride,
|
|
77
|
+
TToSnapshotOverride
|
|
78
|
+
>
|
|
79
|
+
/**
|
|
80
|
+
* Adds a setter with a transform to the property. The setter will be named `set${CapitalizedPropName}`
|
|
81
|
+
* and will be available in the model instance.
|
|
82
|
+
*/
|
|
83
|
+
withSetter(
|
|
84
|
+
valueTransform: ModelPropSetterValueTransform<TTransformedValue>
|
|
85
|
+
): ModelProp<
|
|
86
|
+
TPropValue,
|
|
87
|
+
TPropCreationValue,
|
|
88
|
+
TTransformedValue,
|
|
89
|
+
TTransformedCreationValue,
|
|
90
|
+
TIsRequired,
|
|
91
|
+
TIsId,
|
|
92
|
+
string,
|
|
93
|
+
TFromSnapshotOverride,
|
|
94
|
+
TToSnapshotOverride
|
|
95
|
+
>
|
|
96
|
+
/**
|
|
97
|
+
* @deprecated Setter methods are preferred.
|
|
98
|
+
*/
|
|
99
|
+
withSetter(
|
|
100
|
+
mode: "assign"
|
|
101
|
+
): ModelProp<
|
|
102
|
+
TPropValue,
|
|
103
|
+
TPropCreationValue,
|
|
104
|
+
TTransformedValue,
|
|
105
|
+
TTransformedCreationValue,
|
|
106
|
+
TIsRequired,
|
|
107
|
+
TIsId,
|
|
108
|
+
string,
|
|
109
|
+
TFromSnapshotOverride,
|
|
110
|
+
TToSnapshotOverride
|
|
111
|
+
>
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Sets a transform for the property instance value.
|
|
115
|
+
*
|
|
116
|
+
* @deprecated Prefer using `tProp(types.codec(...))` or one of the built-in codec types
|
|
117
|
+
* (e.g. `types.dateAsTimestamp`, `types.bigint`, `types.mapFromObject(...)`) instead.
|
|
118
|
+
* Wrap with `types.skipCheck(...)` if you don't need runtime validation.
|
|
119
|
+
* Use `.withTransform(...)` only for one-off custom transforms without a codec equivalent.
|
|
120
|
+
*
|
|
121
|
+
* @template TTV Transformed value type.
|
|
122
|
+
* @param transform Transform to be used.
|
|
123
|
+
* @returns
|
|
124
|
+
*/
|
|
125
|
+
withTransform<TTV>(
|
|
126
|
+
transform: ModelPropTransform<NonNullable<TPropValue>, TTV>
|
|
127
|
+
): ModelProp<
|
|
128
|
+
TPropValue,
|
|
129
|
+
TPropCreationValue,
|
|
130
|
+
TTV | Extract<TPropValue, null | undefined>,
|
|
131
|
+
TTV | Extract<TPropCreationValue, null | undefined>,
|
|
132
|
+
TIsRequired,
|
|
133
|
+
TIsId,
|
|
134
|
+
THasSetter,
|
|
135
|
+
TFromSnapshotOverride,
|
|
136
|
+
TToSnapshotOverride
|
|
137
|
+
>
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Sets snapshot processors for this property.
|
|
141
|
+
*
|
|
142
|
+
* `fromSnapshot` runs before assigning snapshot data into the model prop.
|
|
143
|
+
* `toSnapshot` runs when exporting model data back to snapshot form.
|
|
144
|
+
*/
|
|
145
|
+
withSnapshotProcessor<
|
|
146
|
+
FS = TFromSnapshotOverride,
|
|
147
|
+
TS = TToSnapshotOverride,
|
|
148
|
+
This extends AnyModelProp = this,
|
|
149
|
+
>(processor: {
|
|
150
|
+
fromSnapshot?: (sn: FS) => ModelPropFromSnapshot<This>
|
|
151
|
+
toSnapshot?: (sn: ModelPropToSnapshot<This>) => TS
|
|
152
|
+
}): ModelProp<
|
|
153
|
+
TPropValue,
|
|
154
|
+
TPropCreationValue,
|
|
155
|
+
TTransformedValue,
|
|
156
|
+
TTransformedCreationValue,
|
|
157
|
+
TIsRequired,
|
|
158
|
+
TIsId,
|
|
159
|
+
THasSetter,
|
|
160
|
+
FS,
|
|
161
|
+
TS
|
|
162
|
+
>
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* The snapshot in type of a model property.
|
|
167
|
+
*/
|
|
168
|
+
export type ModelPropFromSnapshot<MP extends AnyModelProp> = IsNeverType<
|
|
169
|
+
ModelPropFromSnapshotOverride<MP>,
|
|
170
|
+
SnapshotInOf<ModelPropStoredCreationValue<MP>>,
|
|
171
|
+
ModelPropFromSnapshotOverride<MP>
|
|
172
|
+
>
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* The snapshot out type of a model property.
|
|
176
|
+
*/
|
|
177
|
+
export type ModelPropToSnapshot<MP extends AnyModelProp> = IsNeverType<
|
|
178
|
+
MP["$toSnapshotOverride"],
|
|
179
|
+
SnapshotOutOf<ModelPropStoredValue<MP>>,
|
|
180
|
+
MP["$toSnapshotOverride"]
|
|
181
|
+
>
|
|
182
|
+
|
|
183
|
+
export type ModelPropStoredValue<MP extends AnyModelProp> = MP extends {
|
|
184
|
+
$storedValueType: infer TStoredValue
|
|
185
|
+
}
|
|
186
|
+
? TStoredValue
|
|
187
|
+
: MP["$valueType"]
|
|
188
|
+
|
|
189
|
+
export type ModelPropStoredCreationValue<MP extends AnyModelProp> = MP extends {
|
|
190
|
+
$storedCreationValueType: infer TStoredCreationValue
|
|
191
|
+
}
|
|
192
|
+
? TStoredCreationValue
|
|
193
|
+
: MP["$creationValueType"]
|
|
194
|
+
|
|
195
|
+
export type ModelPropFromSnapshotOverride<MP extends AnyModelProp> = MP extends {
|
|
196
|
+
$typedFromSnapshotOverride: infer TFromSnapshotOverride
|
|
197
|
+
}
|
|
198
|
+
? TFromSnapshotOverride
|
|
199
|
+
: MP["$fromSnapshotOverride"]
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* A model prop transform.
|
|
203
|
+
*/
|
|
204
|
+
export interface ModelPropTransform<TOriginal, TTransformed> {
|
|
205
|
+
/**
|
|
206
|
+
* Converts the stored/original value into the transformed value exposed by the model prop.
|
|
207
|
+
*/
|
|
208
|
+
transform(params: {
|
|
209
|
+
originalValue: TOriginal
|
|
210
|
+
cachedTransformedValue: TTransformed | undefined
|
|
211
|
+
setOriginalValue(value: TOriginal): void
|
|
212
|
+
}): TTransformed
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Converts the transformed model value back into the original stored value.
|
|
216
|
+
*/
|
|
217
|
+
untransform(params: {
|
|
218
|
+
transformedValue: TTransformed
|
|
219
|
+
cacheTransformedValue: () => void
|
|
220
|
+
}): TOriginal
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Any model property.
|
|
225
|
+
*/
|
|
226
|
+
export type AnyModelProp = ModelProp<any, any, any, any, any, any, any, any, any>
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Model properties.
|
|
230
|
+
*/
|
|
231
|
+
export interface ModelProps {
|
|
232
|
+
[k: string]: AnyModelProp
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export type RequiredModelProps<MP extends ModelProps> = {
|
|
236
|
+
[K in keyof MP]: MP[K]["$isRequired"] & K
|
|
237
|
+
}[keyof MP]
|
|
238
|
+
|
|
239
|
+
export type ModelPropsToUntransformedData<MP extends ModelProps> = Flatten<{
|
|
240
|
+
[k in keyof MP]: ModelPropStoredValue<MP[k]>
|
|
241
|
+
}>
|
|
242
|
+
|
|
243
|
+
export type ModelPropsToSnapshotData<MP extends ModelProps> = Flatten<{
|
|
244
|
+
[k in keyof MP]: ModelPropToSnapshot<MP[k]> extends infer R ? R : never
|
|
245
|
+
}>
|
|
246
|
+
|
|
247
|
+
// we don't use O.Optional anymore since it generates unions too heavy
|
|
248
|
+
// also if we use Pick over the optional props we will loose the ability to infer generics
|
|
249
|
+
// we also don't use Flatten because if we do some generics won't work
|
|
250
|
+
export type ModelPropsToUntransformedCreationData<MP extends ModelProps> = {
|
|
251
|
+
[k in keyof MP]?: ModelPropStoredCreationValue<MP[k]>
|
|
252
|
+
} & {
|
|
253
|
+
[k in RequiredModelProps<MP>]: ModelPropStoredCreationValue<MP[k]>
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// we don't use O.Optional anymore since it generates unions too heavy
|
|
257
|
+
// also if we use Pick over the optional props we will loose the ability to infer generics
|
|
258
|
+
export type ModelPropsToSnapshotCreationData<MP extends ModelProps> = Flatten<
|
|
259
|
+
{
|
|
260
|
+
[k in keyof MP]?: ModelPropFromSnapshot<MP[k]> extends infer R ? R : never
|
|
261
|
+
} & {
|
|
262
|
+
[k in {
|
|
263
|
+
[K in keyof MP]: IsNeverType<
|
|
264
|
+
ModelPropFromSnapshotOverride<MP[K]>,
|
|
265
|
+
MP[K]["$isRequired"] & K, // no override
|
|
266
|
+
IsOptionalValue<ModelPropFromSnapshotOverride<MP[K]>, never, K> // with override
|
|
267
|
+
>
|
|
268
|
+
}[keyof MP]]: ModelPropFromSnapshot<MP[k]> extends infer R ? R : never
|
|
269
|
+
}
|
|
270
|
+
>
|
|
271
|
+
|
|
272
|
+
export type ModelPropsToTransformedData<MP extends ModelProps> = Flatten<{
|
|
273
|
+
[k in keyof MP]: MP[k]["$transformedValueType"]
|
|
274
|
+
}>
|
|
275
|
+
|
|
276
|
+
// we don't use O.Optional anymore since it generates unions too heavy
|
|
277
|
+
// also if we use Pick over the optional props we will loose the ability to infer generics
|
|
278
|
+
// we also don't use Flatten because if we do some generics won't work
|
|
279
|
+
// we also don't use Omit because if we do some generics won't work
|
|
280
|
+
export type ModelPropsToTransformedCreationData<MP extends ModelProps> = {
|
|
281
|
+
[k in keyof MP]?: MP[k]["$transformedCreationValueType"]
|
|
282
|
+
} & {
|
|
283
|
+
[k in RequiredModelProps<MP>]: MP[k]["$transformedCreationValueType"]
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export type ModelPropsToSetter<MP extends ModelProps> = Flatten<{
|
|
287
|
+
[k in keyof MP as MP[k]["$hasSetter"] & `set${Capitalize<k & string>}`]: (
|
|
288
|
+
value: MP[k]["$transformedValueType"]
|
|
289
|
+
) => void
|
|
290
|
+
}>
|
|
291
|
+
|
|
292
|
+
export type ModelIdProp<T extends string = string> = ModelProp<
|
|
293
|
+
T,
|
|
294
|
+
T | undefined,
|
|
295
|
+
T,
|
|
296
|
+
T | undefined,
|
|
297
|
+
never, // not required
|
|
298
|
+
true
|
|
299
|
+
>
|
|
300
|
+
|
|
301
|
+
type TypedModelIdProp<T extends string = string, THasSetter = never> = Omit<
|
|
302
|
+
ModelProp<T, T | undefined, T, T | undefined, never, true, THasSetter>,
|
|
303
|
+
"withSetter"
|
|
304
|
+
> & {
|
|
305
|
+
/**
|
|
306
|
+
* Enables generation of a setter method for the ID prop (`setId` for `id`, `setCustomId` for `customId`).
|
|
307
|
+
*/
|
|
308
|
+
withSetter(): TypedModelIdProp<T, string>
|
|
309
|
+
/**
|
|
310
|
+
* Enables generation of a setter method for the ID prop and applies a value transform to setter input.
|
|
311
|
+
*/
|
|
312
|
+
withSetter(valueTransform: ModelPropSetterValueTransform<T>): TypedModelIdProp<T, string>
|
|
313
|
+
/**
|
|
314
|
+
* @deprecated Setter methods are preferred.
|
|
315
|
+
*/
|
|
316
|
+
withSetter(mode: "assign"): TypedModelIdProp<T, string>
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Sets a custom generator for missing model IDs in this `idProp`.
|
|
320
|
+
*/
|
|
321
|
+
withGenerator(generator: () => T): TypedModelIdProp<T, THasSetter>
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Same as `idProp`, except that it might have a specific TypeScript string template as type.
|
|
325
|
+
* E.g. `idProp.typedAs<`custom-${string}`>()`
|
|
326
|
+
*/
|
|
327
|
+
typedAs<U extends string>(): TypedModelIdProp<U, THasSetter>
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* A property that will be used as model id, accessible through $modelId.
|
|
332
|
+
* Can only be used in models and there can be only one per model.
|
|
333
|
+
*/
|
|
334
|
+
export const idProp = {
|
|
335
|
+
_setter: false,
|
|
336
|
+
_setterValueTransform: undefined,
|
|
337
|
+
_isId: true,
|
|
338
|
+
_idGenerator: undefined,
|
|
339
|
+
|
|
340
|
+
withSetter(modeOrValueTransform?: SetterMode | ModelPropSetterValueTransform<unknown>) {
|
|
341
|
+
const obj: AnyModelProp = Object.create(this)
|
|
342
|
+
const setterConfig = parseSetterConfig(modeOrValueTransform)
|
|
343
|
+
obj._setter = setterConfig.mode
|
|
344
|
+
obj._setterValueTransform = setterConfig.valueTransform
|
|
345
|
+
return obj
|
|
346
|
+
},
|
|
347
|
+
|
|
348
|
+
withGenerator(generator: () => string) {
|
|
349
|
+
const obj: AnyModelProp = Object.create(this)
|
|
350
|
+
obj._idGenerator = generator
|
|
351
|
+
return obj
|
|
352
|
+
},
|
|
353
|
+
|
|
354
|
+
typedAs() {
|
|
355
|
+
return this
|
|
356
|
+
},
|
|
357
|
+
} as unknown as TypedModelIdProp
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* @ignore
|
|
361
|
+
*/
|
|
362
|
+
export type OnlyPrimitives<T> = Exclude<T, object>
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* A model prop that maybe / maybe not is optional, depending on if the value can take undefined.
|
|
366
|
+
*/
|
|
367
|
+
export type MaybeOptionalModelProp<TPropValue> = ModelProp<
|
|
368
|
+
TPropValue,
|
|
369
|
+
TPropValue,
|
|
370
|
+
TPropValue,
|
|
371
|
+
TPropValue,
|
|
372
|
+
IsOptionalValue<TPropValue, never, string> // calculate if required
|
|
373
|
+
>
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* A model prop that is definitely optional.
|
|
377
|
+
*/
|
|
378
|
+
export type OptionalModelProp<TPropValue> = ModelProp<
|
|
379
|
+
TPropValue,
|
|
380
|
+
TPropValue | null | undefined,
|
|
381
|
+
TPropValue,
|
|
382
|
+
TPropValue | null | undefined,
|
|
383
|
+
never // not required
|
|
384
|
+
>
|
|
385
|
+
|
|
386
|
+
const baseProp: AnyModelProp = {
|
|
387
|
+
...({} as Pick<
|
|
388
|
+
AnyModelProp,
|
|
389
|
+
| "$valueType"
|
|
390
|
+
| "$creationValueType"
|
|
391
|
+
| "$transformedValueType"
|
|
392
|
+
| "$transformedCreationValueType"
|
|
393
|
+
| "$isRequired"
|
|
394
|
+
| "$isId"
|
|
395
|
+
| "$hasSetter"
|
|
396
|
+
| "$fromSnapshotOverride"
|
|
397
|
+
| "$toSnapshotOverride"
|
|
398
|
+
>),
|
|
399
|
+
|
|
400
|
+
_defaultFn: noDefaultValue,
|
|
401
|
+
_defaultValue: noDefaultValue,
|
|
402
|
+
_defaultValueIsTransformed: false,
|
|
403
|
+
_typeChecker: undefined,
|
|
404
|
+
_setter: false,
|
|
405
|
+
_setterValueTransform: undefined,
|
|
406
|
+
_isId: false,
|
|
407
|
+
_transform: undefined,
|
|
408
|
+
_fromSnapshotProcessor: undefined,
|
|
409
|
+
_toSnapshotProcessor: undefined,
|
|
410
|
+
|
|
411
|
+
withSetter(modeOrValueTransform?: SetterMode | ModelPropSetterValueTransform<unknown>) {
|
|
412
|
+
const obj: AnyModelProp = Object.create(this)
|
|
413
|
+
const setterConfig = parseSetterConfig(modeOrValueTransform)
|
|
414
|
+
obj._setter = setterConfig.mode
|
|
415
|
+
obj._setterValueTransform = setterConfig.valueTransform
|
|
416
|
+
return obj
|
|
417
|
+
},
|
|
418
|
+
|
|
419
|
+
withTransform(transform: ModelPropTransform<unknown, unknown>) {
|
|
420
|
+
const obj: AnyModelProp = Object.create(this)
|
|
421
|
+
obj._transform = composeFullTransforms(this._transform, toFullTransform(transform))
|
|
422
|
+
return obj
|
|
423
|
+
},
|
|
424
|
+
|
|
425
|
+
withSnapshotProcessor({ fromSnapshot, toSnapshot }) {
|
|
426
|
+
let newFromSnapshot: ((sn: any) => any) | undefined
|
|
427
|
+
|
|
428
|
+
if (this._fromSnapshotProcessor && fromSnapshot) {
|
|
429
|
+
const oldFn = this._fromSnapshotProcessor
|
|
430
|
+
const newFn = fromSnapshot
|
|
431
|
+
newFromSnapshot = (sn: any) => oldFn(newFn(sn))
|
|
432
|
+
} else if (fromSnapshot) {
|
|
433
|
+
newFromSnapshot = fromSnapshot
|
|
434
|
+
} else {
|
|
435
|
+
newFromSnapshot = this._fromSnapshotProcessor
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
let newToSnapshot: ((sn: any) => any) | undefined
|
|
439
|
+
|
|
440
|
+
if (this._toSnapshotProcessor && toSnapshot) {
|
|
441
|
+
const oldFn: (sn: unknown) => any = this._toSnapshotProcessor
|
|
442
|
+
const newFn = toSnapshot
|
|
443
|
+
newToSnapshot = (sn: unknown) => newFn(oldFn(sn))
|
|
444
|
+
} else if (toSnapshot) {
|
|
445
|
+
newToSnapshot = toSnapshot
|
|
446
|
+
} else {
|
|
447
|
+
newToSnapshot = this._toSnapshotProcessor
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const obj: AnyModelProp = Object.create(this)
|
|
451
|
+
obj._fromSnapshotProcessor = newFromSnapshot
|
|
452
|
+
obj._toSnapshotProcessor = newToSnapshot
|
|
453
|
+
|
|
454
|
+
return obj
|
|
455
|
+
},
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Defines a model property, with an optional function to generate a default value
|
|
460
|
+
* if the input snapshot / model creation data is `null` or `undefined`.
|
|
461
|
+
*
|
|
462
|
+
* Example:
|
|
463
|
+
* ```ts
|
|
464
|
+
* x: prop(() => 10) // an optional number, with a default value of 10
|
|
465
|
+
* x: prop<number[]>(() => []) // an optional number array, with a default empty array
|
|
466
|
+
* ```
|
|
467
|
+
*
|
|
468
|
+
* @template TValue Value type.
|
|
469
|
+
* @param defaultFn Default value generator function.
|
|
470
|
+
* @returns
|
|
471
|
+
*/
|
|
472
|
+
export function prop<TValue>(defaultFn: () => TValue): OptionalModelProp<TValue>
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Defines a model property, with an optional default value
|
|
476
|
+
* if the input snapshot / model creation data is `null` or `undefined`.
|
|
477
|
+
* You should only use this with primitive values and never with object values
|
|
478
|
+
* (array, model, object, etc).
|
|
479
|
+
*
|
|
480
|
+
* Example:
|
|
481
|
+
* ```ts
|
|
482
|
+
* x: prop(10) // an optional number, with a default value of 10
|
|
483
|
+
* ```
|
|
484
|
+
*
|
|
485
|
+
* @template TValue Value type.
|
|
486
|
+
* @param defaultValue Default primitive value.
|
|
487
|
+
* @returns
|
|
488
|
+
*/
|
|
489
|
+
export function prop<TValue>(defaultValue: OnlyPrimitives<TValue>): OptionalModelProp<TValue>
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Defines a model property with no default value.
|
|
493
|
+
*
|
|
494
|
+
* Example:
|
|
495
|
+
* ```ts
|
|
496
|
+
* x: prop<number>() // a required number
|
|
497
|
+
* x: prop<number | undefined>() // an optional number, which defaults to undefined
|
|
498
|
+
* ```
|
|
499
|
+
*
|
|
500
|
+
* @template TValue Value type.
|
|
501
|
+
* @returns
|
|
502
|
+
*/
|
|
503
|
+
export function prop<TValue>(): MaybeOptionalModelProp<TValue>
|
|
504
|
+
|
|
505
|
+
// base
|
|
506
|
+
export function prop(...args: [] | [def: any]): AnyModelProp {
|
|
507
|
+
const hasDefaultValue = args.length > 0
|
|
508
|
+
if (!hasDefaultValue) {
|
|
509
|
+
return baseProp
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const [def] = args
|
|
513
|
+
|
|
514
|
+
let p = propCache.get(def)
|
|
515
|
+
|
|
516
|
+
if (!p) {
|
|
517
|
+
p = Object.create(baseProp)
|
|
518
|
+
|
|
519
|
+
if (typeof def === "function") {
|
|
520
|
+
p!._defaultFn = def
|
|
521
|
+
} else {
|
|
522
|
+
p!._defaultValue = def
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
propCache.set(def, p!)
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
return p!
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
function parseSetterConfig(
|
|
532
|
+
modeOrValueTransform?: SetterMode | ModelPropSetterValueTransform<unknown>
|
|
533
|
+
): {
|
|
534
|
+
mode: SetterMode
|
|
535
|
+
valueTransform: ((value: unknown) => unknown) | undefined
|
|
536
|
+
} {
|
|
537
|
+
if (typeof modeOrValueTransform === "function") {
|
|
538
|
+
return {
|
|
539
|
+
mode: true,
|
|
540
|
+
valueTransform: modeOrValueTransform,
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
if (
|
|
545
|
+
modeOrValueTransform === undefined ||
|
|
546
|
+
typeof modeOrValueTransform === "boolean" ||
|
|
547
|
+
modeOrValueTransform === "assign"
|
|
548
|
+
) {
|
|
549
|
+
return {
|
|
550
|
+
mode: modeOrValueTransform ?? true,
|
|
551
|
+
valueTransform: undefined,
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return {
|
|
556
|
+
mode: true,
|
|
557
|
+
valueTransform: undefined,
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
const propCache = new Map<unknown, AnyModelProp>()
|
|
562
|
+
|
|
563
|
+
let cacheTransformResult = false
|
|
564
|
+
const cacheTransformedValueFn = () => {
|
|
565
|
+
cacheTransformResult = true
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
function toFullTransform(transformObject: ModelPropTransform<unknown, unknown>) {
|
|
569
|
+
const cache = new WeakMap<
|
|
570
|
+
object,
|
|
571
|
+
Map<PropertyKey, { originalValue: unknown; transformedValue: unknown }>
|
|
572
|
+
>()
|
|
573
|
+
|
|
574
|
+
const transform = (params: {
|
|
575
|
+
originalValue: unknown
|
|
576
|
+
cachedTransformedValue: unknown
|
|
577
|
+
setOriginalValue(newOriginalValue: unknown): void
|
|
578
|
+
}) => (params.originalValue == null ? params.originalValue : transformObject.transform(params))
|
|
579
|
+
|
|
580
|
+
const untransform = (params: { transformedValue: unknown; cacheTransformedValue(): void }) =>
|
|
581
|
+
params.transformedValue == null ? params.transformedValue : transformObject.untransform(params)
|
|
582
|
+
|
|
583
|
+
return {
|
|
584
|
+
transform(
|
|
585
|
+
originalValue: unknown,
|
|
586
|
+
model: object,
|
|
587
|
+
propName: PropertyKey,
|
|
588
|
+
setOriginalValue: (newOriginalValue: unknown) => void
|
|
589
|
+
) {
|
|
590
|
+
const modelCache = getOrCreate(cache, model, () => new Map())
|
|
591
|
+
|
|
592
|
+
let propCache = modelCache.get(propName)
|
|
593
|
+
if (propCache?.originalValue !== originalValue) {
|
|
594
|
+
// original changed, invalidate cache
|
|
595
|
+
modelCache.delete(propName)
|
|
596
|
+
propCache = undefined
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
const transformedValue = transform({
|
|
600
|
+
originalValue,
|
|
601
|
+
cachedTransformedValue: propCache?.transformedValue,
|
|
602
|
+
setOriginalValue,
|
|
603
|
+
})
|
|
604
|
+
|
|
605
|
+
modelCache.set(propName, {
|
|
606
|
+
originalValue,
|
|
607
|
+
transformedValue,
|
|
608
|
+
})
|
|
609
|
+
|
|
610
|
+
return transformedValue
|
|
611
|
+
},
|
|
612
|
+
|
|
613
|
+
untransform(transformedValue: unknown, model: object, propName: PropertyKey) {
|
|
614
|
+
const modelCache = getOrCreate(cache, model, () => new Map())
|
|
615
|
+
|
|
616
|
+
cacheTransformResult = false
|
|
617
|
+
const originalValue = untransform({
|
|
618
|
+
transformedValue,
|
|
619
|
+
cacheTransformedValue: cacheTransformedValueFn,
|
|
620
|
+
})
|
|
621
|
+
if (cacheTransformResult) {
|
|
622
|
+
modelCache.set(propName, { originalValue, transformedValue })
|
|
623
|
+
} else {
|
|
624
|
+
modelCache.delete(propName)
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
return originalValue
|
|
628
|
+
},
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
function composeFullTransforms(
|
|
633
|
+
outerTransform:
|
|
634
|
+
| {
|
|
635
|
+
transform(
|
|
636
|
+
originalValue: unknown,
|
|
637
|
+
model: object,
|
|
638
|
+
propName: PropertyKey,
|
|
639
|
+
setOriginalValue: (newOriginalValue: unknown) => void
|
|
640
|
+
): unknown
|
|
641
|
+
untransform(transformedValue: unknown, model: object, propName: PropertyKey): unknown
|
|
642
|
+
}
|
|
643
|
+
| undefined,
|
|
644
|
+
innerTransform: {
|
|
645
|
+
transform(
|
|
646
|
+
originalValue: unknown,
|
|
647
|
+
model: object,
|
|
648
|
+
propName: PropertyKey,
|
|
649
|
+
setOriginalValue: (newOriginalValue: unknown) => void
|
|
650
|
+
): unknown
|
|
651
|
+
untransform(transformedValue: unknown, model: object, propName: PropertyKey): unknown
|
|
652
|
+
}
|
|
653
|
+
) {
|
|
654
|
+
if (!outerTransform) {
|
|
655
|
+
return innerTransform
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
return {
|
|
659
|
+
transform(
|
|
660
|
+
originalValue: unknown,
|
|
661
|
+
model: object,
|
|
662
|
+
propName: PropertyKey,
|
|
663
|
+
setOriginalValue: (newOriginalValue: unknown) => void
|
|
664
|
+
) {
|
|
665
|
+
const outerValue = outerTransform.transform(originalValue, model, propName, setOriginalValue)
|
|
666
|
+
return innerTransform.transform(outerValue, model, propName, (newOuterValue) => {
|
|
667
|
+
setOriginalValue(outerTransform.untransform(newOuterValue, model, propName))
|
|
668
|
+
})
|
|
669
|
+
},
|
|
670
|
+
|
|
671
|
+
untransform(transformedValue: unknown, model: object, propName: PropertyKey) {
|
|
672
|
+
const outerValue = innerTransform.untransform(transformedValue, model, propName)
|
|
673
|
+
return outerTransform.untransform(outerValue, model, propName)
|
|
674
|
+
},
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* @ignore
|
|
680
|
+
*/
|
|
681
|
+
export function getModelPropDefaultValue(propData: AnyModelProp): unknown | typeof noDefaultValue {
|
|
682
|
+
if (propData._defaultFn !== noDefaultValue) {
|
|
683
|
+
return propData._defaultFn()
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
if (propData._defaultValue !== noDefaultValue) {
|
|
687
|
+
return propData._defaultValue
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
return noDefaultValue
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* @ignore
|
|
695
|
+
*/
|
|
696
|
+
export function getModelPropStoredDefaultValue(
|
|
697
|
+
propData: AnyModelProp,
|
|
698
|
+
model: object,
|
|
699
|
+
propName: string
|
|
700
|
+
): unknown | typeof noDefaultValue {
|
|
701
|
+
const defaultValue = getModelPropDefaultValue(propData)
|
|
702
|
+
if (defaultValue === noDefaultValue || !propData._defaultValueIsTransformed) {
|
|
703
|
+
return defaultValue
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
return propData._transform
|
|
707
|
+
? runWithErrorDiagnosticsContext(() =>
|
|
708
|
+
withErrorPathSegment(propName, () =>
|
|
709
|
+
propData._transform!.untransform(defaultValue, model, propName)
|
|
710
|
+
)
|
|
711
|
+
)
|
|
712
|
+
: defaultValue
|
|
713
|
+
}
|