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
|
@@ -1,475 +1,530 @@
|
|
|
1
|
-
import {
|
|
2
|
-
IArrayDidChange,
|
|
3
|
-
IArrayWillChange,
|
|
4
|
-
IArrayWillSplice,
|
|
5
|
-
IObservableArray,
|
|
6
|
-
intercept,
|
|
7
|
-
isObservableArray,
|
|
8
|
-
observable,
|
|
9
|
-
observe,
|
|
10
|
-
} from "mobx"
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import type {
|
|
16
|
-
import { setParent } from "../parent/setParent"
|
|
17
|
-
import { InternalPatchRecorder } from "../patch/emitPatch"
|
|
18
|
-
import type { Patch } from "../patch/Patch"
|
|
19
|
-
import {
|
|
20
|
-
freezeInternalSnapshot,
|
|
21
|
-
getInternalSnapshot,
|
|
22
|
-
setNewInternalSnapshot,
|
|
23
|
-
updateInternalSnapshot,
|
|
24
|
-
} from "../snapshot/internal"
|
|
25
|
-
import { failure, inDevMode, isArray, isPrimitive } from "../utils"
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
const
|
|
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
|
-
|
|
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
|
-
const
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
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
|
-
}
|
|
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
|
-
|
|
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
|
-
|
|
1
|
+
import {
|
|
2
|
+
type IArrayDidChange,
|
|
3
|
+
type IArrayWillChange,
|
|
4
|
+
type IArrayWillSplice,
|
|
5
|
+
type IObservableArray,
|
|
6
|
+
intercept,
|
|
7
|
+
isObservableArray,
|
|
8
|
+
observable,
|
|
9
|
+
observe,
|
|
10
|
+
} from "mobx"
|
|
11
|
+
import { assertCanWrite } from "../action/protection"
|
|
12
|
+
import { DeepChangeType, emitDeepChange, getIsInInitPhase } from "../deepChange/onDeepChange"
|
|
13
|
+
import { getGlobalConfig } from "../globalConfig"
|
|
14
|
+
import type { ParentPath } from "../parent/path"
|
|
15
|
+
import type { Path } from "../parent/pathTypes"
|
|
16
|
+
import { setParent } from "../parent/setParent"
|
|
17
|
+
import { InternalPatchRecorder } from "../patch/emitPatch"
|
|
18
|
+
import type { Patch } from "../patch/Patch"
|
|
19
|
+
import {
|
|
20
|
+
freezeInternalSnapshot,
|
|
21
|
+
getInternalSnapshot,
|
|
22
|
+
setNewInternalSnapshot,
|
|
23
|
+
updateInternalSnapshot,
|
|
24
|
+
} from "../snapshot/internal"
|
|
25
|
+
import { failure, inDevMode, isArray, isPrimitive } from "../utils"
|
|
26
|
+
import { runningWithoutSnapshotOrPatches, tweakedObjects } from "./core"
|
|
27
|
+
import { TweakerPriority } from "./TweakerPriority"
|
|
28
|
+
import { registerTweaker, tweak } from "./tweak"
|
|
29
|
+
import { runTypeCheckingAfterChange } from "./typeChecking"
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
export function tweakArray<T extends any[]>(
|
|
35
|
+
value: T,
|
|
36
|
+
parentPath: ParentPath<any> | undefined,
|
|
37
|
+
childrenAlreadyTweaked: boolean
|
|
38
|
+
): T {
|
|
39
|
+
const originalArr: ReadonlyArray<any> = value
|
|
40
|
+
const arrLn = originalArr.length
|
|
41
|
+
const originalArrIsObservable = isObservableArray(originalArr)
|
|
42
|
+
let tweakedArr: IObservableArray<any>
|
|
43
|
+
// Fresh arrays whose children still need tweaking are collected into a plain
|
|
44
|
+
// buffer and inserted in one bulk replace at the end.
|
|
45
|
+
let buffer: any[] | undefined
|
|
46
|
+
|
|
47
|
+
if (originalArrIsObservable) {
|
|
48
|
+
tweakedArr = originalArr as IObservableArray<any>
|
|
49
|
+
} else if (childrenAlreadyTweaked) {
|
|
50
|
+
// Snapshot arrays already contain tweaked children, so MobX can initialize
|
|
51
|
+
// the observable array directly from the source values.
|
|
52
|
+
tweakedArr = observable.array(originalArr as any[], observableOptions)
|
|
53
|
+
} else {
|
|
54
|
+
tweakedArr = observable.array(undefined, observableOptions)
|
|
55
|
+
buffer = new Array(arrLn)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let interceptDisposer: () => void
|
|
59
|
+
let observeDisposer: () => void
|
|
60
|
+
|
|
61
|
+
const untweak = () => {
|
|
62
|
+
interceptDisposer()
|
|
63
|
+
observeDisposer()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
tweakedObjects.set(tweakedArr, untweak)
|
|
67
|
+
setParent(
|
|
68
|
+
tweakedArr, // value
|
|
69
|
+
parentPath,
|
|
70
|
+
false, // indexChangeAllowed
|
|
71
|
+
false, // isDataObject
|
|
72
|
+
// arrays shouldn't be cloned anyway
|
|
73
|
+
false // cloneIfApplicable
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
const untransformedSn: any[] = []
|
|
77
|
+
untransformedSn.length = arrLn
|
|
78
|
+
|
|
79
|
+
// externally provided observable arrays keep unchanged slots untouched, but
|
|
80
|
+
// consecutive child replacements can still be applied as single splice ranges
|
|
81
|
+
let replacementRangeStart = -1
|
|
82
|
+
let replacementRangeItems: any[] | undefined
|
|
83
|
+
|
|
84
|
+
const flushReplacementRange = () => {
|
|
85
|
+
if (replacementRangeStart >= 0) {
|
|
86
|
+
tweakedArr.spliceWithArray(
|
|
87
|
+
replacementRangeStart,
|
|
88
|
+
replacementRangeItems!.length,
|
|
89
|
+
replacementRangeItems!
|
|
90
|
+
)
|
|
91
|
+
replacementRangeStart = -1
|
|
92
|
+
replacementRangeItems = undefined
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const queueReplacementIfDifferent = (index: number, value: unknown) => {
|
|
97
|
+
if (tweakedArr[index] === value && index in tweakedArr) {
|
|
98
|
+
flushReplacementRange()
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (replacementRangeStart + (replacementRangeItems?.length ?? 0) === index) {
|
|
103
|
+
replacementRangeItems!.push(value)
|
|
104
|
+
} else {
|
|
105
|
+
flushReplacementRange()
|
|
106
|
+
replacementRangeStart = index
|
|
107
|
+
replacementRangeItems = [value]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// substitute initial values by proxied values
|
|
112
|
+
for (let i = 0; i < arrLn; i++) {
|
|
113
|
+
const v = originalArr[i]
|
|
114
|
+
|
|
115
|
+
if (isPrimitive(v)) {
|
|
116
|
+
if (buffer) {
|
|
117
|
+
buffer[i] = v
|
|
118
|
+
} else if (!childrenAlreadyTweaked) {
|
|
119
|
+
queueReplacementIfDifferent(i, v)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
untransformedSn[i] = v
|
|
123
|
+
} else {
|
|
124
|
+
const path = { parent: tweakedArr, path: i }
|
|
125
|
+
|
|
126
|
+
let tweakedValue: any
|
|
127
|
+
if (childrenAlreadyTweaked) {
|
|
128
|
+
tweakedValue = v
|
|
129
|
+
setParent(
|
|
130
|
+
tweakedValue, // value
|
|
131
|
+
path, // parentPath
|
|
132
|
+
false, // indexChangeAllowed
|
|
133
|
+
false, // isDataObject
|
|
134
|
+
// the value is already a new value (the result of a fromSnapshot)
|
|
135
|
+
false // cloneIfApplicable
|
|
136
|
+
)
|
|
137
|
+
} else {
|
|
138
|
+
tweakedValue = tweak(v, path)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (buffer) {
|
|
142
|
+
buffer[i] = tweakedValue
|
|
143
|
+
} else if (!childrenAlreadyTweaked) {
|
|
144
|
+
queueReplacementIfDifferent(i, tweakedValue)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const valueSn = getInternalSnapshot(tweakedValue)!
|
|
148
|
+
untransformedSn[i] = valueSn.transformed
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (buffer) {
|
|
153
|
+
// done before the intercept/observe handlers are installed, so this
|
|
154
|
+
// is a single plain mobx bulk insertion
|
|
155
|
+
tweakedArr.replace(buffer)
|
|
156
|
+
} else {
|
|
157
|
+
flushReplacementRange()
|
|
158
|
+
}
|
|
159
|
+
setNewInternalSnapshot(tweakedArr, untransformedSn, undefined)
|
|
160
|
+
|
|
161
|
+
interceptDisposer = intercept(tweakedArr, interceptArrayMutation.bind(undefined, tweakedArr))
|
|
162
|
+
observeDisposer = observe(tweakedArr, arrayDidChange)
|
|
163
|
+
|
|
164
|
+
return tweakedArr as any
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function mutateSet(k: number, v: unknown, sn: unknown[]) {
|
|
168
|
+
sn[k] = v
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function mutateSplice(index: number, removedCount: number, addedItems: any[], sn: any[]) {
|
|
172
|
+
sn.splice(index, removedCount, ...addedItems)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const patchRecorder = new InternalPatchRecorder()
|
|
176
|
+
|
|
177
|
+
const emptyPath: Path = Object.freeze([])
|
|
178
|
+
|
|
179
|
+
function arrayDidChange(change: IArrayDidChange) {
|
|
180
|
+
const arr = change.object
|
|
181
|
+
const oldSnapshot = getInternalSnapshot(arr as Array<unknown>)!.untransformed
|
|
182
|
+
|
|
183
|
+
patchRecorder.reset()
|
|
184
|
+
|
|
185
|
+
let mutate: ((sn: any[]) => void) | undefined
|
|
186
|
+
|
|
187
|
+
switch (change.type) {
|
|
188
|
+
case "splice":
|
|
189
|
+
mutate = arrayDidChangeSplice(change, oldSnapshot)
|
|
190
|
+
// Emit deep change for splice
|
|
191
|
+
emitDeepChange(arr, {
|
|
192
|
+
type: DeepChangeType.ArraySplice,
|
|
193
|
+
target: arr,
|
|
194
|
+
path: emptyPath,
|
|
195
|
+
index: change.index as number,
|
|
196
|
+
addedValues: change.added,
|
|
197
|
+
removedValues: change.removed,
|
|
198
|
+
isInit: getIsInInitPhase(),
|
|
199
|
+
})
|
|
200
|
+
break
|
|
201
|
+
|
|
202
|
+
case "update":
|
|
203
|
+
mutate = arrayDidChangeUpdate(change, oldSnapshot)
|
|
204
|
+
// Emit deep change for update
|
|
205
|
+
emitDeepChange(arr, {
|
|
206
|
+
type: DeepChangeType.ArrayUpdate,
|
|
207
|
+
target: arr,
|
|
208
|
+
path: emptyPath,
|
|
209
|
+
index: change.index as number,
|
|
210
|
+
newValue: change.newValue,
|
|
211
|
+
oldValue: change.oldValue,
|
|
212
|
+
isInit: getIsInInitPhase(),
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
break
|
|
216
|
+
|
|
217
|
+
default:
|
|
218
|
+
break
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
runTypeCheckingAfterChange(arr, patchRecorder)
|
|
222
|
+
|
|
223
|
+
if (!runningWithoutSnapshotOrPatches && mutate) {
|
|
224
|
+
updateInternalSnapshot(arr, mutate)
|
|
225
|
+
patchRecorder.emit(arr)
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const undefinedInsideArrayErrorMsg =
|
|
230
|
+
"undefined is not supported inside arrays since it is not serializable in JSON, consider using null instead"
|
|
231
|
+
|
|
232
|
+
function arrayDidChangeUpdate(change: any /*IArrayDidChange*/, oldSnapshot: any) {
|
|
233
|
+
const k = change.index
|
|
234
|
+
const val = change.newValue
|
|
235
|
+
const oldVal = oldSnapshot[k]
|
|
236
|
+
let newVal: any
|
|
237
|
+
if (isPrimitive(val)) {
|
|
238
|
+
newVal = val
|
|
239
|
+
} else {
|
|
240
|
+
const valueSn = getInternalSnapshot(val)!
|
|
241
|
+
newVal = valueSn.transformed
|
|
242
|
+
}
|
|
243
|
+
const mutate = mutateSet.bind(undefined, k, newVal)
|
|
244
|
+
|
|
245
|
+
const path = [k]
|
|
246
|
+
|
|
247
|
+
patchRecorder.record(
|
|
248
|
+
[
|
|
249
|
+
{
|
|
250
|
+
op: "replace",
|
|
251
|
+
path,
|
|
252
|
+
value: freezeInternalSnapshot(newVal),
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
[
|
|
256
|
+
{
|
|
257
|
+
op: "replace",
|
|
258
|
+
path,
|
|
259
|
+
value: freezeInternalSnapshot(oldVal),
|
|
260
|
+
},
|
|
261
|
+
]
|
|
262
|
+
)
|
|
263
|
+
return mutate
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function arrayDidChangeSplice(change: any /*IArrayDidChange*/, oldSnapshot: any) {
|
|
267
|
+
const index = change.index as number
|
|
268
|
+
const addedCount = change.addedCount as number
|
|
269
|
+
const removedCount = change.removedCount as number
|
|
270
|
+
|
|
271
|
+
const addedItems: any[] = []
|
|
272
|
+
addedItems.length = addedCount
|
|
273
|
+
for (let i = 0; i < addedCount; i++) {
|
|
274
|
+
const v = change.added[i]
|
|
275
|
+
if (isPrimitive(v)) {
|
|
276
|
+
addedItems[i] = v
|
|
277
|
+
} else {
|
|
278
|
+
addedItems[i] = getInternalSnapshot(v)!.transformed
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const oldLen = oldSnapshot.length
|
|
283
|
+
const mutate = mutateSplice.bind(undefined, index, removedCount, addedItems)
|
|
284
|
+
|
|
285
|
+
const patches: Patch[] = []
|
|
286
|
+
const invPatches: Patch[] = []
|
|
287
|
+
|
|
288
|
+
// optimization: if we add as many as we remove then remove/readd instead
|
|
289
|
+
|
|
290
|
+
// we cannot replace since we might end up in a situation where the same node
|
|
291
|
+
// might attempt to be temporarily twice inside the same tree (e.g. sorting)
|
|
292
|
+
|
|
293
|
+
// it would be faster to keep holes rather than remove/readd, but if we do that then
|
|
294
|
+
// validation might fail
|
|
295
|
+
|
|
296
|
+
if (addedCount === removedCount) {
|
|
297
|
+
const readdPatches: Patch[] = []
|
|
298
|
+
const readdInvPatches: Patch[] = []
|
|
299
|
+
let removed = 0
|
|
300
|
+
|
|
301
|
+
for (let i = 0; i < addedCount; i++) {
|
|
302
|
+
const realIndex = index + i
|
|
303
|
+
|
|
304
|
+
const newVal = getValueAfterSplice(oldSnapshot, realIndex, index, removedCount, addedItems)
|
|
305
|
+
const oldVal = oldSnapshot[realIndex]
|
|
306
|
+
|
|
307
|
+
if (newVal !== oldVal) {
|
|
308
|
+
const removePath = [realIndex - removed]
|
|
309
|
+
patches.push({
|
|
310
|
+
op: "remove",
|
|
311
|
+
path: removePath,
|
|
312
|
+
})
|
|
313
|
+
invPatches.push({
|
|
314
|
+
op: "remove",
|
|
315
|
+
path: removePath,
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
removed++
|
|
319
|
+
|
|
320
|
+
const readdPath = [realIndex]
|
|
321
|
+
readdPatches.push({
|
|
322
|
+
op: "add",
|
|
323
|
+
path: readdPath,
|
|
324
|
+
value: freezeInternalSnapshot(newVal),
|
|
325
|
+
})
|
|
326
|
+
|
|
327
|
+
readdInvPatches.push({
|
|
328
|
+
op: "add",
|
|
329
|
+
path: readdPath,
|
|
330
|
+
value: freezeInternalSnapshot(oldVal),
|
|
331
|
+
})
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
patches.push(...readdPatches)
|
|
336
|
+
invPatches.push(...readdInvPatches)
|
|
337
|
+
// we need to reverse since inverse patches are applied in reverse
|
|
338
|
+
invPatches.reverse()
|
|
339
|
+
} else {
|
|
340
|
+
const interimLen = oldLen - removedCount
|
|
341
|
+
|
|
342
|
+
// first remove items
|
|
343
|
+
if (removedCount > 0) {
|
|
344
|
+
// optimization, when removing from the end set the length instead
|
|
345
|
+
const removeUsingSetLength = index >= interimLen
|
|
346
|
+
if (removeUsingSetLength) {
|
|
347
|
+
patches.push({
|
|
348
|
+
op: "replace",
|
|
349
|
+
path: ["length"],
|
|
350
|
+
value: interimLen,
|
|
351
|
+
})
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
for (let i = removedCount - 1; i >= 0; i--) {
|
|
355
|
+
const realIndex = index + i
|
|
356
|
+
const path = [realIndex]
|
|
357
|
+
|
|
358
|
+
if (!removeUsingSetLength) {
|
|
359
|
+
// remove ...2, 1, 0
|
|
360
|
+
patches.push({
|
|
361
|
+
op: "remove",
|
|
362
|
+
path,
|
|
363
|
+
})
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// add 0, 1, 2... since inverse patches are applied in reverse
|
|
367
|
+
invPatches.push({
|
|
368
|
+
op: "add",
|
|
369
|
+
path,
|
|
370
|
+
value: freezeInternalSnapshot(oldSnapshot[realIndex]),
|
|
371
|
+
})
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// then add items
|
|
376
|
+
if (addedCount > 0) {
|
|
377
|
+
// optimization, for inverse patches, when adding from the end set the length to restore instead
|
|
378
|
+
const restoreUsingSetLength = index >= interimLen
|
|
379
|
+
if (restoreUsingSetLength) {
|
|
380
|
+
invPatches.push({
|
|
381
|
+
op: "replace",
|
|
382
|
+
path: ["length"],
|
|
383
|
+
value: interimLen,
|
|
384
|
+
})
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
for (let i = 0; i < addedCount; i++) {
|
|
388
|
+
const realIndex = index + i
|
|
389
|
+
const path = [realIndex]
|
|
390
|
+
|
|
391
|
+
// add 0, 1, 2...
|
|
392
|
+
patches.push({
|
|
393
|
+
op: "add",
|
|
394
|
+
path,
|
|
395
|
+
value: freezeInternalSnapshot(
|
|
396
|
+
getValueAfterSplice(oldSnapshot, realIndex, index, removedCount, addedItems)
|
|
397
|
+
),
|
|
398
|
+
})
|
|
399
|
+
|
|
400
|
+
// remove ...2, 1, 0 since inverse patches are applied in reverse
|
|
401
|
+
if (!restoreUsingSetLength) {
|
|
402
|
+
invPatches.push({
|
|
403
|
+
op: "remove",
|
|
404
|
+
path,
|
|
405
|
+
})
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
patchRecorder.record(patches, invPatches)
|
|
412
|
+
return mutate
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// TODO: remove array parameter and just use change.object once mobx update event is fixed
|
|
416
|
+
function interceptArrayMutation(
|
|
417
|
+
array: IObservableArray,
|
|
418
|
+
change: IArrayWillChange | IArrayWillSplice
|
|
419
|
+
) {
|
|
420
|
+
assertCanWrite()
|
|
421
|
+
|
|
422
|
+
switch (change.type) {
|
|
423
|
+
case "splice":
|
|
424
|
+
interceptArrayMutationSplice(change)
|
|
425
|
+
break
|
|
426
|
+
|
|
427
|
+
case "update":
|
|
428
|
+
interceptArrayMutationUpdate(change, array)
|
|
429
|
+
break
|
|
430
|
+
|
|
431
|
+
default:
|
|
432
|
+
break
|
|
433
|
+
}
|
|
434
|
+
return change
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function interceptArrayMutationUpdate(change: IArrayWillChange, array: IObservableArray) {
|
|
438
|
+
if (
|
|
439
|
+
inDevMode &&
|
|
440
|
+
!getGlobalConfig().allowUndefinedArrayElements &&
|
|
441
|
+
change.newValue === undefined
|
|
442
|
+
) {
|
|
443
|
+
throw failure(undefinedInsideArrayErrorMsg)
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// TODO: should be change.object, but mobx is bugged and doesn't send the proxy
|
|
447
|
+
const oldVal = array[change.index]
|
|
448
|
+
tweak(oldVal, undefined) // set old prop obj parent to undefined
|
|
449
|
+
|
|
450
|
+
change.newValue = tweak(change.newValue, { parent: array, path: change.index })
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function interceptArrayMutationSplice(change: IArrayWillSplice) {
|
|
454
|
+
if (inDevMode && !getGlobalConfig().allowUndefinedArrayElements) {
|
|
455
|
+
const len = change.added.length
|
|
456
|
+
for (let i = 0; i < len; i++) {
|
|
457
|
+
const v = change.added[i]
|
|
458
|
+
if (v === undefined) {
|
|
459
|
+
throw failure(undefinedInsideArrayErrorMsg)
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
for (let i = 0; i < change.removedCount; i++) {
|
|
465
|
+
const removedValue = change.object[change.index + i]
|
|
466
|
+
tweak(removedValue, undefined)
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
for (let i = 0; i < change.added.length; i++) {
|
|
470
|
+
change.added[i] = tweak(change.added[i], {
|
|
471
|
+
parent: change.object,
|
|
472
|
+
path: change.index + i,
|
|
473
|
+
})
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// we might also need to update the parent of the next indexes
|
|
477
|
+
const oldNextIndex = change.index + change.removedCount
|
|
478
|
+
const newNextIndex = change.index + change.added.length
|
|
479
|
+
|
|
480
|
+
if (oldNextIndex !== newNextIndex) {
|
|
481
|
+
for (let i = oldNextIndex, j = newNextIndex; i < change.object.length; i++, j++) {
|
|
482
|
+
setParent(
|
|
483
|
+
change.object[i], // value
|
|
484
|
+
{
|
|
485
|
+
parent: change.object,
|
|
486
|
+
path: j,
|
|
487
|
+
}, // parentPath
|
|
488
|
+
true, // indexChangeAllowed
|
|
489
|
+
false, // isDataObject
|
|
490
|
+
// just re-indexing
|
|
491
|
+
false // cloneIfApplicable
|
|
492
|
+
)
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* @internal
|
|
499
|
+
*/
|
|
500
|
+
export function registerArrayTweaker() {
|
|
501
|
+
registerTweaker(TweakerPriority.Array, (value, parentPath) => {
|
|
502
|
+
if (isArray(value)) {
|
|
503
|
+
return tweakArray(value, parentPath, false)
|
|
504
|
+
}
|
|
505
|
+
return undefined
|
|
506
|
+
})
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
const observableOptions = {
|
|
510
|
+
deep: false,
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
function getValueAfterSplice<T>(
|
|
514
|
+
array: readonly T[],
|
|
515
|
+
i: number,
|
|
516
|
+
index: number,
|
|
517
|
+
remove: number,
|
|
518
|
+
addedItems: readonly T[]
|
|
519
|
+
) {
|
|
520
|
+
const base = i - index
|
|
521
|
+
if (base < 0) {
|
|
522
|
+
return array[i]
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (base < addedItems.length) {
|
|
526
|
+
return addedItems[base]
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
return array[i - addedItems.length + remove]
|
|
530
|
+
}
|