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.
Files changed (83) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +1 -1
  3. package/dist/mobx-keystone.esm.js +555 -516
  4. package/dist/mobx-keystone.esm.mjs +555 -516
  5. package/dist/mobx-keystone.umd.js +558 -519
  6. package/dist/types/actionMiddlewares/undoMiddleware.d.ts +2 -10
  7. package/dist/types/modelShared/modelDecorator.d.ts +5 -2
  8. package/dist/types/modelShared/prop.d.ts +42 -29
  9. package/dist/types/ref/Ref.d.ts +1 -4
  10. package/dist/types/snapshot/SnapshotOf.d.ts +4 -4
  11. package/dist/types/snapshot/applySnapshot.d.ts +1 -1
  12. package/dist/types/snapshot/fromSnapshot.d.ts +2 -2
  13. package/dist/types/snapshot/getSnapshot.d.ts +1 -1
  14. package/dist/types/types/SnapshotTypeMismatchError.d.ts +3 -1
  15. package/dist/types/types/index.d.ts +1 -0
  16. package/dist/types/types/modelTypeMatching.d.ts +1 -0
  17. package/dist/types/types/schemas.d.ts +41 -37
  18. package/dist/types/types/tProp.d.ts +12 -6
  19. package/dist/types/types/types.d.ts +6 -6
  20. package/dist/types/types/utility/typeToStoredData.d.ts +14 -10
  21. package/dist/types/types/utility/typesCodecCore.d.ts +3 -0
  22. package/dist/types/utils/ModelPool.d.ts +0 -1
  23. package/dist/types/utils/types.d.ts +6 -0
  24. package/dist/types/wrappers/ArraySet.d.ts +1 -0
  25. package/package.json +13 -11
  26. package/src/action/modelFlow.ts +35 -66
  27. package/src/actionMiddlewares/actionTrackingMiddleware.ts +41 -71
  28. package/src/actionMiddlewares/transactionMiddleware.ts +1 -1
  29. package/src/actionMiddlewares/undoMiddleware.ts +16 -22
  30. package/src/context/context.ts +15 -36
  31. package/src/dataModel/utils.ts +5 -28
  32. package/src/deepChange/onDeepChange.ts +44 -126
  33. package/src/model/BaseModel.ts +1 -1
  34. package/src/model/utils.ts +5 -10
  35. package/src/modelShared/modelDecorator.ts +13 -10
  36. package/src/modelShared/modelInfo.ts +75 -0
  37. package/src/modelShared/prop.ts +115 -111
  38. package/src/modelShared/sharedInternalModel.ts +2 -2
  39. package/src/parent/arrayPaths.ts +1 -4
  40. package/src/parent/path.ts +0 -10
  41. package/src/patch/patchRecorder.ts +13 -28
  42. package/src/ref/core.ts +6 -19
  43. package/src/rootStore/rootStore.ts +1 -3
  44. package/src/snapshot/SnapshotOf.ts +24 -48
  45. package/src/snapshot/applySnapshot.ts +1 -1
  46. package/src/snapshot/fromSnapshot.ts +10 -3
  47. package/src/snapshot/getSnapshot.ts +1 -1
  48. package/src/snapshot/internal.ts +0 -2
  49. package/src/snapshot/reconcileModelSnapshot.ts +5 -3
  50. package/src/snapshot/reconcilePlainObjectSnapshot.ts +3 -1
  51. package/src/treeUtils/draft.ts +6 -1
  52. package/src/treeUtils/sandbox.ts +10 -7
  53. package/src/tweaker/tweakArray.ts +20 -50
  54. package/src/tweaker/tweakPlainObject.ts +9 -15
  55. package/src/types/SnapshotTypeMismatchError.ts +3 -1
  56. package/src/types/arrayBased/typesArray.ts +13 -19
  57. package/src/types/arrayBased/typesTuple.ts +16 -25
  58. package/src/types/createCachedTypeCheck.ts +17 -30
  59. package/src/types/index.ts +1 -0
  60. package/src/types/modelTypeMatching.ts +276 -0
  61. package/src/types/objectBased/typesDataModelData.ts +7 -8
  62. package/src/types/objectBased/typesModel.ts +23 -6
  63. package/src/types/objectBased/typesObject.ts +11 -15
  64. package/src/types/objectBased/typesRecord.ts +11 -15
  65. package/src/types/objectBased/typesRef.ts +23 -4
  66. package/src/types/schemas.ts +59 -71
  67. package/src/types/tProp.ts +29 -29
  68. package/src/types/utility/typeToStoredData.ts +22 -21
  69. package/src/types/utility/typesCodecCore.ts +8 -1
  70. package/src/types/utility/typesCodecSupport.ts +16 -10
  71. package/src/types/utility/typesMap.ts +43 -51
  72. package/src/types/utility/typesOr.ts +38 -8
  73. package/src/types/utility/typesRefinement.ts +7 -8
  74. package/src/types/utility/typesSkipCheck.ts +7 -8
  75. package/src/types/utility/typesTag.ts +7 -8
  76. package/src/utils/ModelPool.ts +1 -18
  77. package/src/utils/decorators.ts +5 -5
  78. package/src/utils/index.ts +1 -20
  79. package/src/utils/types.ts +5 -0
  80. package/src/wrappers/ArraySet.ts +27 -14
  81. package/src/wrappers/ObjectMap.ts +1 -6
  82. package/src/wrappers/asMap.ts +1 -21
  83. package/src/wrappers/asSet.ts +0 -8
@@ -48,7 +48,9 @@ function reconcilePlainObjectSnapshot(
48
48
  const k = snKeys[i]
49
49
  const v = sn[k]
50
50
 
51
- const oldValue = plainObj[k]
51
+ // an inherited member such as `toString` is no old value (but `__proto__`
52
+ // still reads the prototype, which is rejected as it is no tree node)
53
+ const oldValue = k === "__proto__" || hasOwnProp(plainObj, k) ? plainObj[k] : undefined
52
54
  const newValue = withErrorPathSegment(k, () =>
53
55
  reconcileSnapshot(oldValue, v, modelPool, plainObj)
54
56
  )
@@ -6,7 +6,7 @@ import { applySnapshot } from "../snapshot/applySnapshot"
6
6
  import { fromSnapshot } from "../snapshot/fromSnapshot"
7
7
  import { getSnapshot } from "../snapshot/getSnapshot"
8
8
  import { assertTweakedObject } from "../tweaker/core"
9
- import { failure, mobxAction, mobxComputed } from "../utils"
9
+ import { failure, getMobxVersion, makeObservableCompat, mobxAction, mobxComputed } from "../utils"
10
10
  import { deepEquals } from "./deepEquals"
11
11
 
12
12
  /**
@@ -157,6 +157,11 @@ export class Draft<T extends object> {
157
157
  assertTweakedObject(original, "original")
158
158
 
159
159
  this.originalData = original
160
+
161
+ if (getMobxVersion() >= 6) {
162
+ makeObservableCompat(this)
163
+ }
164
+
160
165
  this.data = fromSnapshot(this.originalSnapshot, { generateNewIds: false })
161
166
  }
162
167
  }
@@ -233,9 +233,11 @@ export class SandboxManager {
233
233
  // see the reverted intermediate state.
234
234
  runInAction(() => {
235
235
  this.allowWrite(() => {
236
- for (let i = events.length - 1; i >= 0; i--) {
237
- applyPatches(this.subtreeRootClone, events[i].inversePatches, true)
238
- }
236
+ applyPatches(
237
+ this.subtreeRootClone,
238
+ events.map((event) => event.inversePatches),
239
+ true
240
+ )
239
241
  })
240
242
  applyPatches(
241
243
  this.subtreeRoot,
@@ -249,10 +251,11 @@ export class SandboxManager {
249
251
  const wasRecording = recorder.recording
250
252
  recorder.recording = false
251
253
  try {
252
- let i = recorder.events.length
253
- while (i-- > numRecorderEvents) {
254
- applyPatches(this.subtreeRootClone, recorder.events[i].inversePatches, true)
255
- }
254
+ applyPatches(
255
+ this.subtreeRootClone,
256
+ recorder.events.slice(numRecorderEvents).map((event) => event.inversePatches),
257
+ true
258
+ )
256
259
  recorder.events.splice(numRecorderEvents)
257
260
  } finally {
258
261
  recorder.recording = wasRecording
@@ -289,7 +289,6 @@ function arrayDidChangeUpdate(
289
289
  ) {
290
290
  const k = change.index
291
291
  const val = change.newValue
292
- const oldVal = oldSnapshot[k]
293
292
  let newVal: any
294
293
  if (isPrimitive(val)) {
295
294
  newVal = val
@@ -299,15 +298,14 @@ function arrayDidChangeUpdate(
299
298
  }
300
299
  const mutate = mutateSet.bind(undefined, k, newVal)
301
300
 
302
- if (shouldEmitPatches || shouldBuildInversePatches) {
301
+ if (shouldBuildInversePatches) {
303
302
  const path = [k]
304
303
  const patches = shouldEmitPatches
305
304
  ? [{ op: "replace" as const, path, value: freezeInternalSnapshot(newVal) }]
306
305
  : undefined
307
- const invPatches = shouldBuildInversePatches
308
- ? [{ op: "replace" as const, path, value: freezeInternalSnapshot(oldVal) }]
309
- : undefined
310
- patchRecorder.record(patches, invPatches)
306
+ patchRecorder.record(patches, [
307
+ { op: "replace" as const, path, value: freezeInternalSnapshot(oldSnapshot[k]) },
308
+ ])
311
309
  }
312
310
  return mutate
313
311
  }
@@ -335,17 +333,16 @@ function arrayDidChangeSplice(
335
333
 
336
334
  const mutate = mutateSplice.bind(undefined, index, removedCount, addedItems)
337
335
 
338
- // With neither patch listeners nor type checking, there is no inverse-patch
339
- // data to build. The snapshot mutation above is all the post-change work we
340
- // need to retain.
341
- if (!shouldEmitPatches && !shouldBuildInversePatches) {
336
+ // With neither patch listeners nor type checking, there is no patch data to
337
+ // build. The snapshot mutation above is all the post-change work we need.
338
+ if (!shouldBuildInversePatches) {
342
339
  return mutate
343
340
  }
344
341
 
345
342
  const oldLen = oldSnapshot.length
346
343
 
347
344
  const patches: Patch[] | undefined = shouldEmitPatches ? [] : undefined
348
- const invPatches: Patch[] | undefined = shouldBuildInversePatches ? [] : undefined
345
+ const invPatches: Patch[] = []
349
346
 
350
347
  // optimization: if we add as many as we remove then remove/readd instead
351
348
 
@@ -357,13 +354,13 @@ function arrayDidChangeSplice(
357
354
 
358
355
  if (addedCount === removedCount) {
359
356
  const readdPatches: Patch[] | undefined = shouldEmitPatches ? [] : undefined
360
- const readdInvPatches: Patch[] | undefined = shouldBuildInversePatches ? [] : undefined
357
+ const readdInvPatches: Patch[] = []
361
358
  let removed = 0
362
359
 
363
360
  for (let i = 0; i < addedCount; i++) {
364
361
  const realIndex = index + i
365
362
 
366
- const newVal = getValueAfterSplice(oldSnapshot, realIndex, index, removedCount, addedItems)
363
+ const newVal = addedItems[i]
367
364
  const oldVal = oldSnapshot[realIndex]
368
365
 
369
366
  if (newVal !== oldVal) {
@@ -372,7 +369,7 @@ function arrayDidChangeSplice(
372
369
  op: "remove",
373
370
  path: removePath,
374
371
  })
375
- invPatches?.push({
372
+ invPatches.push({
376
373
  op: "remove",
377
374
  path: removePath,
378
375
  })
@@ -386,7 +383,7 @@ function arrayDidChangeSplice(
386
383
  value: freezeInternalSnapshot(newVal),
387
384
  })
388
385
 
389
- readdInvPatches?.push({
386
+ readdInvPatches.push({
390
387
  op: "add",
391
388
  path: readdPath,
392
389
  value: freezeInternalSnapshot(oldVal),
@@ -394,17 +391,13 @@ function arrayDidChangeSplice(
394
391
  }
395
392
  }
396
393
 
397
- if (patches && readdPatches && readdPatches.length > 0) {
394
+ if (patches && readdPatches) {
398
395
  for (const patch of readdPatches) patches.push(patch)
399
396
  }
400
- if (invPatches && readdInvPatches && readdInvPatches.length > 0) {
401
- for (const patch of readdInvPatches) invPatches.push(patch)
402
- }
397
+ for (const patch of readdInvPatches) invPatches.push(patch)
403
398
  // We need to reverse once since inverse patches are applied in reverse.
404
399
  // Repeated unshift calls here would make a large splice quadratic.
405
- if (invPatches && invPatches.length > 0) {
406
- invPatches.reverse()
407
- }
400
+ invPatches.reverse()
408
401
  } else {
409
402
  const interimLen = oldLen - removedCount
410
403
 
@@ -433,7 +426,7 @@ function arrayDidChangeSplice(
433
426
  }
434
427
 
435
428
  // add 0, 1, 2... since inverse patches are applied in reverse
436
- invPatches?.push({
429
+ invPatches.push({
437
430
  op: "add",
438
431
  path,
439
432
  value: freezeInternalSnapshot(oldSnapshot[realIndex]),
@@ -446,7 +439,7 @@ function arrayDidChangeSplice(
446
439
  // optimization, for inverse patches, when adding from the end set the length to restore instead
447
440
  const restoreUsingSetLength = index >= interimLen
448
441
  if (restoreUsingSetLength) {
449
- invPatches?.push({
442
+ invPatches.push({
450
443
  op: "replace",
451
444
  path: ["length"],
452
445
  value: interimLen,
@@ -461,14 +454,12 @@ function arrayDidChangeSplice(
461
454
  patches?.push({
462
455
  op: "add",
463
456
  path,
464
- value: freezeInternalSnapshot(
465
- getValueAfterSplice(oldSnapshot, realIndex, index, removedCount, addedItems)
466
- ),
457
+ value: freezeInternalSnapshot(addedItems[i]),
467
458
  })
468
459
 
469
460
  // remove ...2, 1, 0 since inverse patches are applied in reverse
470
461
  if (!restoreUsingSetLength) {
471
- invPatches?.push({
462
+ invPatches.push({
472
463
  op: "remove",
473
464
  path,
474
465
  })
@@ -477,9 +468,7 @@ function arrayDidChangeSplice(
477
468
  }
478
469
  }
479
470
 
480
- if (patches || invPatches) {
481
- patchRecorder.record(patches, invPatches)
482
- }
471
+ patchRecorder.record(patches, invPatches)
483
472
  return mutate
484
473
  }
485
474
 
@@ -676,22 +665,3 @@ class ObservableArrayReplacementQueue {
676
665
  }
677
666
  }
678
667
  }
679
-
680
- function getValueAfterSplice<T>(
681
- array: readonly T[],
682
- i: number,
683
- index: number,
684
- remove: number,
685
- addedItems: readonly T[]
686
- ) {
687
- const base = i - index
688
- if (base < 0) {
689
- return array[i]
690
- }
691
-
692
- if (base < addedItems.length) {
693
- return addedItems[base]
694
- }
695
-
696
- return array[i - addedItems.length + remove]
697
- }
@@ -295,16 +295,14 @@ function objectDidChangeRemove(
295
295
  shouldBuildInversePatches: boolean
296
296
  ) {
297
297
  const k = change.name
298
- const oldVal = oldUntransformedSn[k]
299
298
  const mutate = mutateDelete.bind(undefined, k)
300
299
 
301
- if (shouldEmitPatches || shouldBuildInversePatches) {
300
+ if (shouldBuildInversePatches) {
302
301
  const path = [k as string]
303
302
  const patches = shouldEmitPatches ? [{ op: "remove" as const, path }] : undefined
304
- const invPatches = shouldBuildInversePatches
305
- ? [{ op: "add" as const, path, value: freezeInternalSnapshot(oldVal) }]
306
- : undefined
307
- patchRecorder.record(patches, invPatches)
303
+ patchRecorder.record(patches, [
304
+ { op: "add" as const, path, value: freezeInternalSnapshot(oldUntransformedSn[k]) },
305
+ ])
308
306
  }
309
307
  return mutate
310
308
  }
@@ -318,8 +316,6 @@ function objectDidChangeAddOrUpdate(
318
316
  const k = change.name
319
317
  const val = change.newValue
320
318
 
321
- const oldVal = oldUntransformedSn[k]
322
-
323
319
  let newVal: any
324
320
  if (isPrimitive(val)) {
325
321
  newVal = val
@@ -330,22 +326,20 @@ function objectDidChangeAddOrUpdate(
330
326
 
331
327
  const mutate = mutateSet.bind(undefined, k, newVal)
332
328
 
333
- if (shouldEmitPatches || shouldBuildInversePatches) {
329
+ if (shouldBuildInversePatches) {
334
330
  const path = [k as string]
335
331
  if (change.type === "add") {
336
332
  const patches = shouldEmitPatches
337
333
  ? [{ op: "add" as const, path, value: freezeInternalSnapshot(newVal) }]
338
334
  : undefined
339
- const invPatches = shouldBuildInversePatches ? [{ op: "remove" as const, path }] : undefined
340
- patchRecorder.record(patches, invPatches)
335
+ patchRecorder.record(patches, [{ op: "remove" as const, path }])
341
336
  } else {
342
337
  const patches = shouldEmitPatches
343
338
  ? [{ op: "replace" as const, path, value: freezeInternalSnapshot(newVal) }]
344
339
  : undefined
345
- const invPatches = shouldBuildInversePatches
346
- ? [{ op: "replace" as const, path, value: freezeInternalSnapshot(oldVal) }]
347
- : undefined
348
- patchRecorder.record(patches, invPatches)
340
+ patchRecorder.record(patches, [
341
+ { op: "replace" as const, path, value: freezeInternalSnapshot(oldUntransformedSn[k]) },
342
+ ])
349
343
  }
350
344
  }
351
345
 
@@ -14,7 +14,9 @@ export interface SnapshotTypeMismatchErrorData {
14
14
  }
15
15
 
16
16
  /**
17
- * Thrown when a snapshot value does not match any of the expected types in a union (extends `MobxKeystoneError`).
17
+ * Thrown when a snapshot value does not match any of the expected types in a union, or when a
18
+ * model snapshot names a model (`$modelType`) that is not the expected model or a subclass of it
19
+ * (extends `MobxKeystoneError`).
18
20
  *
19
21
  * Use `instanceof SnapshotTypeMismatchError` to distinguish snapshot type-mismatch errors
20
22
  * from other `MobxKeystoneError` instances.
@@ -50,6 +50,16 @@ export function typesArray<T extends AnyType>(itemType: T): ArrayType<T[]> {
50
50
  }
51
51
  )
52
52
 
53
+ const processorPlan = snapshotProcessorPlan(
54
+ () => [itemChecker],
55
+ ([itemProcessor]) =>
56
+ itemProcessor
57
+ ? (sn: unknown[]) => {
58
+ return sn.map((item, i) => withErrorPathSegment(i, () => itemProcessor(item)))
59
+ }
60
+ : undefined
61
+ )
62
+
53
63
  const thisTc: TypeChecker = new TypeChecker(
54
64
  TypeCheckerBaseType.Array,
55
65
 
@@ -89,25 +99,9 @@ export function typesArray<T extends AnyType>(itemType: T): ArrayType<T[]> {
89
99
  return thisTc
90
100
  },
91
101
 
92
- snapshotProcessorPlan(
93
- () => [itemChecker],
94
- ([itemProcessor]) =>
95
- itemProcessor
96
- ? (sn: unknown[]) => {
97
- return sn.map((item, i) => withErrorPathSegment(i, () => itemProcessor(item)))
98
- }
99
- : undefined
100
- ),
101
-
102
- snapshotProcessorPlan(
103
- () => [itemChecker],
104
- ([itemProcessor]) =>
105
- itemProcessor
106
- ? (sn: unknown[]) => {
107
- return sn.map((item, i) => withErrorPathSegment(i, () => itemProcessor(item)))
108
- }
109
- : undefined
110
- )
102
+ processorPlan,
103
+
104
+ processorPlan
111
105
  )
112
106
 
113
107
  return thisTc
@@ -68,6 +68,19 @@ export function typesTuple<T extends AnyType[]>(...itemTypes: T): ArrayType<T> {
68
68
  // computeds cannot isolate tuple-item changes and only add allocation overhead.
69
69
  const checkTupleItems = createWholeContainerCachedCheck(checkTupleItemsImperatively)
70
70
 
71
+ const processorPlan = snapshotProcessorPlan(
72
+ () => checkers,
73
+ (processors) =>
74
+ processors.some(Boolean)
75
+ ? (array: unknown[]) => {
76
+ return array.map((item, i) => {
77
+ const processor = processors[i]
78
+ return processor ? withErrorPathSegment(i, () => processor(item)) : item
79
+ })
80
+ }
81
+ : undefined
82
+ )
83
+
71
84
  const thisTc: TypeChecker = new TypeChecker(
72
85
  TypeCheckerBaseType.Array,
73
86
 
@@ -102,31 +115,9 @@ export function typesTuple<T extends AnyType[]>(...itemTypes: T): ArrayType<T> {
102
115
  return thisTc
103
116
  },
104
117
 
105
- snapshotProcessorPlan(
106
- () => checkers,
107
- (processors) =>
108
- processors.some(Boolean)
109
- ? (array: unknown[]) => {
110
- return array.map((item, i) => {
111
- const processor = processors[i]
112
- return processor ? withErrorPathSegment(i, () => processor(item)) : item
113
- })
114
- }
115
- : undefined
116
- ),
117
-
118
- snapshotProcessorPlan(
119
- () => checkers,
120
- (processors) =>
121
- processors.some(Boolean)
122
- ? (array: unknown[]) => {
123
- return array.map((item, i) => {
124
- const processor = processors[i]
125
- return processor ? withErrorPathSegment(i, () => processor(item)) : item
126
- })
127
- }
128
- : undefined
129
- )
118
+ processorPlan,
119
+
120
+ processorPlan
130
121
  )
131
122
 
132
123
  return thisTc
@@ -19,6 +19,7 @@ import {
19
19
  } from "../tweaker/tweakedChangeListeners"
20
20
  import { getMobxVersion } from "../utils"
21
21
  import { ChunkedSequence, ChunkedSet, chunkSize, type SequenceChunk } from "../utils/chunks"
22
+ import { getOrCreate } from "../utils/mapUtils"
22
23
  import { TypeCheckError } from "./TypeCheckError"
23
24
 
24
25
  /**
@@ -79,11 +80,7 @@ function checkUncached(
79
80
  typeCheckedValue: any,
80
81
  check: () => TypeCheckError | null
81
82
  ): TypeCheckError | null {
82
- let results = uncachedResults!.get(checker)
83
- if (!results) {
84
- results = new Map()
85
- uncachedResults!.set(checker, results)
86
- }
83
+ const results = getOrCreate(uncachedResults!, checker, () => new Map())
87
84
  let error = results.get(value)
88
85
  if (error === undefined) {
89
86
  error = check()
@@ -152,11 +149,9 @@ export function createWholeContainerCachedCheck(
152
149
  )
153
150
  }
154
151
 
155
- let cached = cache.get(value)
156
- if (!cached) {
157
- cached = computed(() => check(value, emptyPath, undefined), { keepAlive: true })
158
- cache.set(value, cached)
159
- }
152
+ const cached = getOrCreate(cache, value, () =>
153
+ computed(() => check(value, emptyPath, undefined), { keepAlive: true })
154
+ )
160
155
  const error = cached.get()
161
156
  return contextualizeCachedError(error, path, typeCheckedValue)
162
157
  }
@@ -167,6 +162,10 @@ export function createWholeContainerCachedCheck(
167
162
  // check new chunks twice.
168
163
  const needsBatchToCacheChunks = getMobxVersion() < 6
169
164
 
165
+ function checkChunks<T>(fn: () => T): T {
166
+ return needsBatchToCacheChunks ? transaction(fn) : fn()
167
+ }
168
+
170
169
  /**
171
170
  * Checks the items of an array, starting at `firstIndex`, and returns the first
172
171
  * error, or null.
@@ -328,14 +327,8 @@ class RecordChunks
328
327
  readonly atom = createAtom("recordTypeCheckChunks")
329
328
  private readonly record: object
330
329
  private readonly checkKey: (key: string) => TypeCheckError | null
331
- private readonly getEntry = (key: string): CachedEntry => {
332
- let entry = this.entries.get(key)
333
- if (!entry) {
334
- entry = computed(() => this.checkKey(key))
335
- this.entries.set(key, entry)
336
- }
337
- return entry
338
- }
330
+ private readonly getEntry = (key: string): CachedEntry =>
331
+ getOrCreate(this.entries, key, () => computed(() => this.checkKey(key)))
339
332
 
340
333
  constructor(record: object, checkKey: (key: string) => TypeCheckError | null) {
341
334
  super()
@@ -458,10 +451,7 @@ export function createChunkedRecordCachedCheck(
458
451
  const chunks = cached?.chunks
459
452
  return checkUncached(cache, value, path, typeCheckedValue, () => {
460
453
  if (chunks && typeof key === "string") {
461
- const hasError = needsBatchToCacheChunks
462
- ? transaction(() => chunks.hasError(key))
463
- : chunks.hasError(key)
464
- if (!hasError) {
454
+ if (!checkChunks(() => chunks.hasError(key))) {
465
455
  return null
466
456
  }
467
457
  }
@@ -475,11 +465,10 @@ export function createChunkedRecordCachedCheck(
475
465
  addTweakedChangeListener<object>(value, chunks)
476
466
  const check = computed(
477
467
  () => {
478
- const hasError = needsBatchToCacheChunks
479
- ? transaction(() => chunks.hasError())
480
- : chunks.hasError()
481
468
  // any added or removed key changes a chunk, so this runs again then
482
- return hasError ? checkAllEntries(value, emptyPath, undefined) : null
469
+ return checkChunks(() => chunks.hasError())
470
+ ? checkAllEntries(value, emptyPath, undefined)
471
+ : null
483
472
  },
484
473
  { keepAlive: true }
485
474
  )
@@ -535,9 +524,7 @@ export function createChunkedArrayCachedCheck(
535
524
  if (!chunks || typeof index !== "number") {
536
525
  return checkItems(array, 0, emptyPath, undefined)
537
526
  }
538
- return needsBatchToCacheChunks
539
- ? transaction(() => chunks.check(index))
540
- : chunks.check(index)
527
+ return checkChunks(() => chunks.check(index))
541
528
  })
542
529
  }
543
530
 
@@ -561,7 +548,7 @@ export function createChunkedArrayCachedCheck(
561
548
  }
562
549
 
563
550
  const chunks = state.chunks
564
- return needsBatchToCacheChunks ? transaction(() => chunks.check()) : chunks.check()
551
+ return checkChunks(() => chunks.check())
565
552
  },
566
553
  { keepAlive: true }
567
554
  ),
@@ -4,3 +4,4 @@ export * from "./TypeCheckError"
4
4
  export * from "./tProp"
5
5
  export { typeCheck } from "./typeCheck"
6
6
  export * from "./types"
7
+ export type { CodecFromEncoded } from "./utility/typesCodecCore"