@optimystic/db-core 1.0.0-beta.3 → 1.0.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 (171) hide show
  1. package/dist/src/cluster/structs.d.ts +30 -6
  2. package/dist/src/cluster/structs.d.ts.map +1 -1
  3. package/dist/src/cluster/structs.js +5 -3
  4. package/dist/src/cluster/structs.js.map +1 -1
  5. package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.d.ts +2 -1
  6. package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.d.ts.map +1 -1
  7. package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.js +10 -3
  8. package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.js.map +1 -1
  9. package/dist/src/cohort-topic/wire/codec.d.ts.map +1 -1
  10. package/dist/src/cohort-topic/wire/codec.js +8 -2
  11. package/dist/src/cohort-topic/wire/codec.js.map +1 -1
  12. package/dist/src/collection/collection.d.ts +439 -34
  13. package/dist/src/collection/collection.d.ts.map +1 -1
  14. package/dist/src/collection/collection.js +843 -148
  15. package/dist/src/collection/collection.js.map +1 -1
  16. package/dist/src/collection/struct.d.ts +109 -4
  17. package/dist/src/collection/struct.d.ts.map +1 -1
  18. package/dist/src/collection/struct.js +88 -1
  19. package/dist/src/collection/struct.js.map +1 -1
  20. package/dist/src/collections/diary/diary.d.ts +6 -2
  21. package/dist/src/collections/diary/diary.d.ts.map +1 -1
  22. package/dist/src/collections/diary/diary.js +5 -2
  23. package/dist/src/collections/diary/diary.js.map +1 -1
  24. package/dist/src/collections/tree/struct.d.ts +124 -16
  25. package/dist/src/collections/tree/struct.d.ts.map +1 -1
  26. package/dist/src/collections/tree/struct.js +86 -11
  27. package/dist/src/collections/tree/struct.js.map +1 -1
  28. package/dist/src/collections/tree/tree.d.ts +13 -3
  29. package/dist/src/collections/tree/tree.d.ts.map +1 -1
  30. package/dist/src/collections/tree/tree.js +106 -40
  31. package/dist/src/collections/tree/tree.js.map +1 -1
  32. package/dist/src/index.d.ts +1 -1
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +1 -1
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/matchmaking/wire.d.ts.map +1 -1
  37. package/dist/src/matchmaking/wire.js +8 -2
  38. package/dist/src/matchmaking/wire.js.map +1 -1
  39. package/dist/src/network/durability.d.ts +45 -0
  40. package/dist/src/network/durability.d.ts.map +1 -0
  41. package/dist/src/network/durability.js +114 -0
  42. package/dist/src/network/durability.js.map +1 -0
  43. package/dist/src/network/i-key-network.d.ts +14 -6
  44. package/dist/src/network/i-key-network.d.ts.map +1 -1
  45. package/dist/src/network/index.d.ts +3 -0
  46. package/dist/src/network/index.d.ts.map +1 -1
  47. package/dist/src/network/index.js +3 -0
  48. package/dist/src/network/index.js.map +1 -1
  49. package/dist/src/network/lineage.d.ts +39 -0
  50. package/dist/src/network/lineage.d.ts.map +1 -0
  51. package/dist/src/network/lineage.js +61 -0
  52. package/dist/src/network/lineage.js.map +1 -0
  53. package/dist/src/network/routing-key.d.ts +24 -0
  54. package/dist/src/network/routing-key.d.ts.map +1 -0
  55. package/dist/src/network/routing-key.js +9 -0
  56. package/dist/src/network/routing-key.js.map +1 -0
  57. package/dist/src/network/stale-failure.d.ts +5 -1
  58. package/dist/src/network/stale-failure.d.ts.map +1 -1
  59. package/dist/src/network/stale-failure.js +5 -1
  60. package/dist/src/network/stale-failure.js.map +1 -1
  61. package/dist/src/network/struct.d.ts +151 -8
  62. package/dist/src/network/struct.d.ts.map +1 -1
  63. package/dist/src/network/struct.js.map +1 -1
  64. package/dist/src/reactivity/wire.d.ts.map +1 -1
  65. package/dist/src/reactivity/wire.js +8 -2
  66. package/dist/src/reactivity/wire.js.map +1 -1
  67. package/dist/src/testing/test-transactor.d.ts +64 -7
  68. package/dist/src/testing/test-transactor.d.ts.map +1 -1
  69. package/dist/src/testing/test-transactor.js +150 -23
  70. package/dist/src/testing/test-transactor.js.map +1 -1
  71. package/dist/src/transaction/coordinator.d.ts +141 -21
  72. package/dist/src/transaction/coordinator.d.ts.map +1 -1
  73. package/dist/src/transaction/coordinator.js +408 -122
  74. package/dist/src/transaction/coordinator.js.map +1 -1
  75. package/dist/src/transaction/errors.d.ts +39 -10
  76. package/dist/src/transaction/errors.d.ts.map +1 -1
  77. package/dist/src/transaction/errors.js +34 -9
  78. package/dist/src/transaction/errors.js.map +1 -1
  79. package/dist/src/transaction/index.d.ts +1 -0
  80. package/dist/src/transaction/index.d.ts.map +1 -1
  81. package/dist/src/transaction/index.js.map +1 -1
  82. package/dist/src/transactor/block-floors.d.ts +78 -0
  83. package/dist/src/transactor/block-floors.d.ts.map +1 -0
  84. package/dist/src/transactor/block-floors.js +62 -0
  85. package/dist/src/transactor/block-floors.js.map +1 -0
  86. package/dist/src/transactor/change-notifier.d.ts +43 -0
  87. package/dist/src/transactor/change-notifier.d.ts.map +1 -1
  88. package/dist/src/transactor/change-notifier.js +3 -0
  89. package/dist/src/transactor/change-notifier.js.map +1 -1
  90. package/dist/src/transactor/index.d.ts +1 -0
  91. package/dist/src/transactor/index.d.ts.map +1 -1
  92. package/dist/src/transactor/index.js +1 -0
  93. package/dist/src/transactor/index.js.map +1 -1
  94. package/dist/src/transactor/network-transactor.d.ts +43 -6
  95. package/dist/src/transactor/network-transactor.d.ts.map +1 -1
  96. package/dist/src/transactor/network-transactor.js +279 -86
  97. package/dist/src/transactor/network-transactor.js.map +1 -1
  98. package/dist/src/transactor/transactor-source.d.ts +94 -4
  99. package/dist/src/transactor/transactor-source.d.ts.map +1 -1
  100. package/dist/src/transactor/transactor-source.js +120 -42
  101. package/dist/src/transactor/transactor-source.js.map +1 -1
  102. package/dist/src/transactor/transactor.d.ts +14 -1
  103. package/dist/src/transactor/transactor.d.ts.map +1 -1
  104. package/dist/src/transform/atomic.d.ts.map +1 -1
  105. package/dist/src/transform/atomic.js +12 -9
  106. package/dist/src/transform/atomic.js.map +1 -1
  107. package/dist/src/transform/base-pins.d.ts +50 -17
  108. package/dist/src/transform/base-pins.d.ts.map +1 -1
  109. package/dist/src/transform/base-pins.js +58 -11
  110. package/dist/src/transform/base-pins.js.map +1 -1
  111. package/dist/src/transform/cache-source.d.ts +75 -11
  112. package/dist/src/transform/cache-source.d.ts.map +1 -1
  113. package/dist/src/transform/cache-source.js +162 -36
  114. package/dist/src/transform/cache-source.js.map +1 -1
  115. package/dist/src/transform/digest.d.ts +8 -1
  116. package/dist/src/transform/digest.d.ts.map +1 -1
  117. package/dist/src/transform/digest.js +19 -9
  118. package/dist/src/transform/digest.js.map +1 -1
  119. package/dist/src/transform/helpers.d.ts +6 -2
  120. package/dist/src/transform/helpers.d.ts.map +1 -1
  121. package/dist/src/transform/helpers.js +8 -3
  122. package/dist/src/transform/helpers.js.map +1 -1
  123. package/dist/src/transform/tracker.d.ts +94 -14
  124. package/dist/src/transform/tracker.d.ts.map +1 -1
  125. package/dist/src/transform/tracker.js +222 -68
  126. package/dist/src/transform/tracker.js.map +1 -1
  127. package/dist/src/utility/structural-equals.d.ts +38 -0
  128. package/dist/src/utility/structural-equals.d.ts.map +1 -0
  129. package/dist/src/utility/structural-equals.js +77 -0
  130. package/dist/src/utility/structural-equals.js.map +1 -0
  131. package/package.json +2 -2
  132. package/src/cluster/structs.ts +28 -7
  133. package/src/cohort-topic/antidos/bootstrap-evidence-envelope.ts +260 -253
  134. package/src/cohort-topic/wire/codec.ts +222 -216
  135. package/src/collection/collection.ts +960 -157
  136. package/src/collection/struct.ts +99 -4
  137. package/src/collections/diary/diary.ts +71 -68
  138. package/src/collections/tree/struct.ts +155 -23
  139. package/src/collections/tree/tree.ts +127 -40
  140. package/src/index.ts +1 -1
  141. package/src/matchmaking/wire.ts +8 -2
  142. package/src/network/durability.ts +123 -0
  143. package/src/network/i-key-network.ts +60 -52
  144. package/src/network/index.ts +10 -7
  145. package/src/network/lineage.ts +80 -0
  146. package/src/network/routing-key.ts +27 -0
  147. package/src/network/stale-failure.ts +5 -1
  148. package/src/network/struct.ts +156 -8
  149. package/src/reactivity/wire.ts +230 -224
  150. package/src/testing/test-transactor.ts +152 -24
  151. package/src/transaction/coordinator.ts +470 -131
  152. package/src/transaction/errors.ts +34 -9
  153. package/src/transaction/index.ts +1 -0
  154. package/src/transactor/block-floors.ts +105 -0
  155. package/src/transactor/change-notifier.ts +129 -80
  156. package/src/transactor/index.ts +1 -0
  157. package/src/transactor/network-transactor.ts +297 -89
  158. package/src/transactor/transactor-source.ts +131 -42
  159. package/src/transactor/transactor.ts +13 -1
  160. package/src/transform/atomic.ts +25 -22
  161. package/src/transform/base-pins.ts +76 -18
  162. package/src/transform/cache-source.ts +327 -194
  163. package/src/transform/digest.ts +21 -10
  164. package/src/transform/helpers.ts +8 -3
  165. package/src/transform/tracker.ts +423 -270
  166. package/src/utility/structural-equals.ts +72 -0
  167. package/dist/src/utility/block-id-to-bytes.d.ts +0 -3
  168. package/dist/src/utility/block-id-to-bytes.d.ts.map +0 -1
  169. package/dist/src/utility/block-id-to-bytes.js +0 -7
  170. package/dist/src/utility/block-id-to-bytes.js.map +0 -1
  171. package/src/utility/block-id-to-bytes.ts +0 -8
@@ -10,6 +10,19 @@ function sourceReadRevision(source, id) {
10
10
  const src = source;
11
11
  return typeof src.getReadRevision === 'function' ? src.getReadRevision(id) : undefined;
12
12
  }
13
+ /** What the source says about `block`, the object it just returned for `id`: the revision the
14
+ * content is, and whether it may be kept and served again without re-asking.
15
+ *
16
+ * Prefers the source's per-OBJECT answer (`describeServed`, which TransactorSource provides) over
17
+ * the by-id {@link sourceReadRevision}. This runs after an `await`, so with two reads of one id in
18
+ * flight a by-id record describes whichever answer the source processed last — not necessarily
19
+ * this one — and would stamp one answer's content with the other's revision and verdict. A source
20
+ * that offers neither allows keeping at revision 0, the behaviour before either probe existed. */
21
+ function sourceServed(source, id, block) {
22
+ const src = source;
23
+ const described = typeof src.describeServed === 'function' ? src.describeServed(block) : undefined;
24
+ return described ?? { rev: sourceReadRevision(source, id) ?? 0, mayRetain: true };
25
+ }
13
26
  export class CacheSource {
14
27
  source;
15
28
  collector;
@@ -29,10 +42,27 @@ export class CacheSource {
29
42
  * in, and dropped alongside the cached block on delete/clear. Re-emitted on every cache HIT
30
43
  * so a hit records a read dependency at the right revision — the whole point of this map, since
31
44
  * the underlying source is never consulted on a hit. */
32
- // NOTE: an LRU-evicted id can leave a stale `revisions` entry (eviction drops `cache` but not
33
- // this map see clear()/the LruMap eviction). Benign: the next read of that id is a cache MISS
34
- // that re-learns the revision from the source and overwrites the entry before recording anything.
45
+ // NOTE: an LRU-evicted id keeps its `revisions` entry (eviction drops `cache` but not this map).
46
+ // That lingering entry is LOAD-BEARING, not a leak: every path that serves or forgets content for
47
+ // an id writes this map in the same step (keep, handThrough, clear, transformCache), so the entry
48
+ // is always the revision of the content LAST SERVED for the id — which is exactly what a write
49
+ // staged over a since-evicted read needs to declare as its base (a rev-only pin, see
50
+ // `PinnedBase.block` in base-pins.ts). Only `peek` pairs a revision with content, and it answers
51
+ // nothing for an evicted id, so the revision never pairs with a block it does not describe.
35
52
  revisions = new Map();
53
+ /** The most recent answer per id that this cache returned to a reader but did not keep — a
54
+ * below-floor answer, content older than a log entry the collection already walked says the
55
+ * block is (see {@link sourceServed}), or an answer overtaken while in flight over an id nothing
56
+ * is held for (see {@link admit}). NEVER served to a read: {@link tryGet} re-asks the source
57
+ * every time such an id is read, which is the whole point. It exists for the base probes alone
58
+ * ({@link peek} / {@link getCachedRevision}): a write staged over this content must declare the
59
+ * base it was really built on, at the revision it was really served at, so that the storage-side
60
+ * guard which refuses a transform whose declared base is not the one the member holds can fire
61
+ * instead of abstaining and applying edits computed against the old content over newer content.
62
+ * An id is never in both this map and `cache`/`revisions`. It leaves on its next keepable answer,
63
+ * on {@link clear}, and on any {@link transformCache} that touches it, so the map is bounded by
64
+ * the source's unmet floors plus the ids caught mid-flight by a clear or a fold. */
65
+ unkept = new Map();
36
66
  constructor(source, maxSize = DefaultMaxSize,
37
67
  /** Shared per-transaction read-dependency accumulator (same instance the collection's
38
68
  * TransactorSource holds). Optional: log-walk caches that never form a transaction omit it. */
@@ -61,9 +91,16 @@ export class CacheSource {
61
91
  getGeneration(id) {
62
92
  return this.generations.get(id) ?? 0;
63
93
  }
94
+ /** INVARIANT: what a read returns for an id is what this cache then describes for it — the
95
+ * block {@link peek} answers and the revision {@link getCachedRevision} answers, immediately
96
+ * after, are the content the reader holds, on every path (hit, kept, handed through, evicted
97
+ * since). A write staged over the returned content pins that revision as its base, so a read
98
+ * that returned one thing while the cache described another would put a wrong base on the
99
+ * commit — the one direction the storage-side guard cannot catch. {@link admit} is where the
100
+ * two are decided together. */
64
101
  async tryGet(id, purpose = 'value') {
65
- let block = this.cache.get(id);
66
- if (block) {
102
+ const hit = this.cache.get(id);
103
+ if (hit) {
67
104
  // Cache hit: the source is never consulted, so re-emit the revision we learned when this
68
105
  // id was first loaded/folded. Without this a block served from cache records NO read
69
106
  // dependency (the original bug), so its stale-read check could never fire. Carry the
@@ -72,44 +109,120 @@ export class CacheSource {
72
109
  if (rev !== undefined)
73
110
  this.collector?.record(id, rev, purpose);
74
111
  log('hit id=%s', id);
112
+ return structuredClone(hit);
75
113
  }
76
- else {
77
- block = await this.source.tryGet(id, purpose);
78
- if (block) {
79
- this.cache.set(id, block);
80
- this.bump(id);
81
- // Learn the revision from the source (which just served it) and record it. On a miss the
82
- // underlying TransactorSource already recorded the same id@rev/purpose into the shared
83
- // collector; max-wins (revision) + value-wins (purpose) collapse the two to one entry.
84
- const rev = sourceReadRevision(this.source, id) ?? 0;
85
- this.revisions.set(id, rev);
86
- this.collector?.record(id, rev, purpose);
87
- log('miss:loaded id=%s cacheSize=%d', id, this.cache.size);
88
- }
89
- else {
90
- // Absent block: record nothing (matches TransactorSource, which skips missing blocks).
91
- log('miss:absent id=%s', id);
92
- }
114
+ const generationAtMiss = this.getGeneration(id);
115
+ const answer = await this.source.tryGet(id, purpose);
116
+ if (!answer) {
117
+ // Absent block: record nothing (matches TransactorSource, which skips missing blocks).
118
+ log('miss:absent id=%s', id);
119
+ return undefined;
93
120
  }
94
- return structuredClone(block);
121
+ const { rev, mayRetain } = sourceServed(this.source, id, answer);
122
+ const served = this.admit(id, answer, rev, mayRetain, generationAtMiss);
123
+ // Record the dependency at the revision RETURNED. On a miss the underlying TransactorSource
124
+ // already recorded the answer's own id@rev/purpose into the shared collector; max-wins
125
+ // (revision) + value-wins (purpose) collapse the two to one entry, at the higher revision.
126
+ this.collector?.record(id, served.rev, purpose);
127
+ return structuredClone(served.block);
95
128
  }
96
- /** The block currently cached for `id`, without consulting the source. Cloned (callers apply ops
97
- * to it) and recency-neutral ({@link LruMap.peek})an observation pass must neither pay a
98
- * network read nor reshape eviction order. Records no read dependency: the caller that peeks
99
- * already read the block through {@link tryGet} (that is how it got cached), so the dependency
100
- * exists; a digest pass merely re-describes it. */
129
+ /** Decide, for an answer the source just gave for `id`, what the reader gets and what this cache
130
+ * describes for the id from now on one decision, so the two cannot come apart.
131
+ *
132
+ * A keepable answer that is {@link stillWanted} is kept and returned. Otherwise the answer is
133
+ * either below its floor or was overtaken while in flight, and of two answers to one id the
134
+ * higher revision is the truer — so if content is HELD for the id (a concurrent read answered
135
+ * well, a folded commit, or content that met a floor this answer does not), the held content is
136
+ * what the reader gets, exactly as a hit a moment later would get it; the answer leaves no trace.
137
+ * Held content is never older than a below-floor answer: raising a floor forgets the id in the
138
+ * same step, so anything held for it since met the floor. With nothing held, the answer is
139
+ * handed through (see {@link handThrough}): returned, described, not kept. */
140
+ admit(id, answer, rev, mayRetain, generationAtMiss) {
141
+ if (mayRetain && this.stillWanted(id, rev, generationAtMiss)) {
142
+ this.keep(id, answer, rev);
143
+ return { block: answer, rev };
144
+ }
145
+ const held = this.cache.get(id);
146
+ const heldRev = held === undefined ? undefined : this.revisions.get(id);
147
+ if (held !== undefined && heldRev !== undefined) {
148
+ log('miss:superseded id=%s rev=%d heldRev=%d unkeepable=%s', id, rev, heldRev, !mayRetain);
149
+ return { block: held, rev: heldRev };
150
+ }
151
+ this.handThrough(id, answer, rev);
152
+ return { block: answer, rev };
153
+ }
154
+ /** Whether an answer at `rev`, asked for when this id's generation was `generationAtMiss`, is
155
+ * still one to keep now that it has arrived.
156
+ *
157
+ * A miss is decided before the `await` and acted on after it. If the generation has not moved,
158
+ * nothing happened to the id meanwhile and the answer is kept. If it has — a second read of the
159
+ * id landed first, a refresh cleared it, a commit folded in ({@link transformCache}) — this answer
160
+ * was asked for in a world that has since changed, and keeping it blindly is how old content gets
161
+ * remembered for good: nothing clears a block but a log entry naming it, and that entry may be
162
+ * the very thing that moved the generation. So it is then kept only to REPLACE strictly older
163
+ * content (every answer to one source is for one view, so of two the higher revision is the
164
+ * truer, whichever arrives last); what an overtaken answer's reader gets is {@link admit}'s call.
165
+ * Only a CACHED id is compared: `revisions` outlives an LRU-evicted block (see its NOTE). */
166
+ stillWanted(id, rev, generationAtMiss) {
167
+ if (this.getGeneration(id) === generationAtMiss) {
168
+ return true;
169
+ }
170
+ const held = this.cache.has(id) ? this.revisions.get(id) : undefined;
171
+ const replacesOlder = held !== undefined && held < rev;
172
+ if (!replacesOlder) {
173
+ log('miss:overtaken id=%s rev=%d heldRev=%s', id, rev, held ?? 'none');
174
+ }
175
+ return replacesOlder;
176
+ }
177
+ /** A keepable answer: cached, and served to every later read of `id` until something clears it. */
178
+ keep(id, block, rev) {
179
+ this.cache.set(id, block);
180
+ this.revisions.set(id, rev);
181
+ this.unkept.delete(id);
182
+ this.bump(id);
183
+ log('miss:loaded id=%s cacheSize=%d', id, this.cache.size);
184
+ }
185
+ /** An answer this cache will not keep, over an id it holds nothing for: returned to this one
186
+ * reader and described to the base probes (see {@link unkept}), but the next read of `id` asks
187
+ * the source again. Only {@link admit} calls this, after establishing that nothing is held —
188
+ * a cached id is never also in {@link unkept}.
189
+ *
190
+ * Bumped like a load: the answer changes what this cache can say about the id, and the bump is
191
+ * what sends a base pin or a materialized memo built on the previous answer back to be
192
+ * re-judged. */
193
+ handThrough(id, block, rev) {
194
+ this.revisions.delete(id);
195
+ this.unkept.set(id, { block, rev });
196
+ this.bump(id);
197
+ log('miss:unkept id=%s rev=%d', id, rev);
198
+ }
199
+ /** The base this cache can describe for `id`, without consulting the source: the cached block,
200
+ * or the content last handed through unkept (see {@link unkept}) — either way the content the
201
+ * most recent {@link tryGet} of the id returned, unless it has been evicted since. Cloned
202
+ * (callers apply ops to it) and recency-neutral ({@link LruMap.peek}) — an observation pass must
203
+ * neither pay a network read nor reshape eviction order. Records no read dependency: the caller
204
+ * that peeks already read the block through {@link tryGet} (that is how this cache learned it),
205
+ * so the dependency exists; a digest pass merely re-describes it. */
101
206
  peek(id) {
102
- const block = this.cache.peek(id);
207
+ const block = this.cache.peek(id) ?? this.unkept.get(id)?.block;
103
208
  return block === undefined ? undefined : structuredClone(block);
104
209
  }
105
- /** The committed revision of the content currently cached for `id` the source-reported
106
- * materialized revision learned on miss-load (see {@link revisions}), NOT the block's own
107
- * `state.latest.rev`. An LRU-evicted id can leave a stale entry here (see the NOTE on
108
- * {@link revisions}); callers must therefore require BOTH {@link peek} and this to be present —
109
- * {@link peek} returns `undefined` for the evicted id, so a stale revision never pairs with a
110
- * peeked block. */
210
+ /** Whether a later {@link tryGet} of `id` is answered from memory with the content this cache
211
+ * holds now. `false` for content handed through unkept, which {@link peek} still describes so
212
+ * a consumer that would FREEZE a read result ({@link Tracker}'s materialized memo) asks this, not
213
+ * {@link peek}. Recency-neutral. */
214
+ retains(id) {
215
+ return this.cache.has(id);
216
+ }
217
+ /** The committed revision of the content this cache last served for `id` — the source-reported
218
+ * materialized revision learned on miss-load (see {@link revisions}) or handed through
219
+ * ({@link unkept}), NOT the block's own `state.latest.rev`. Answers for an LRU-evicted id too
220
+ * (see the NOTE on {@link revisions}): that is the revision a write staged over the evicted
221
+ * read was computed against, and what a rev-only base pin carries. {@link peek} returns
222
+ * `undefined` for the evicted id, so the revision never pairs with content it does not describe.
223
+ * `undefined` once the id has been cleared or folded away, or if it was never served. */
111
224
  getCachedRevision(id) {
112
- return this.revisions.get(id);
225
+ return this.revisions.get(id) ?? this.unkept.get(id)?.rev;
113
226
  }
114
227
  /** Upgrade an already-captured read of `id` to a `value` read in the shared collector,
115
228
  * retaining it in the conflict set. The B-tree point-lookup descent calls this (through the
@@ -130,6 +243,7 @@ export class CacheSource {
130
243
  for (const id of blockIds) {
131
244
  this.cache.delete(id);
132
245
  this.revisions.delete(id);
246
+ this.unkept.delete(id);
133
247
  this.bump(id);
134
248
  }
135
249
  }
@@ -137,8 +251,12 @@ export class CacheSource {
137
251
  for (const [id] of this.cache) {
138
252
  this.bump(id);
139
253
  }
254
+ for (const id of this.unkept.keys()) {
255
+ this.bump(id);
256
+ }
140
257
  this.cache.clear();
141
258
  this.revisions.clear();
259
+ this.unkept.clear();
142
260
  }
143
261
  }
144
262
  /** A cloned copy of the current cache contents with each id's committed revision, in LRU
@@ -160,11 +278,13 @@ export class CacheSource {
160
278
  for (const blockId of transform.deletes ?? []) {
161
279
  this.cache.delete(blockId);
162
280
  this.revisions.delete(blockId);
281
+ this.unkept.delete(blockId);
163
282
  this.bump(blockId);
164
283
  }
165
284
  for (const [, block] of Object.entries(transform.inserts ?? {})) {
166
285
  this.cache.set(block.header.id, structuredClone(block));
167
286
  this.revisions.set(block.header.id, revision);
287
+ this.unkept.delete(block.header.id);
168
288
  this.bump(block.header.id);
169
289
  }
170
290
  for (const [blockId, operations] of Object.entries(transform.updates ?? {})) {
@@ -176,6 +296,12 @@ export class CacheSource {
176
296
  }
177
297
  this.revisions.set(blockId, revision);
178
298
  }
299
+ else if (this.unkept.delete(blockId)) {
300
+ // The commit superseded the unkept base, and the ops are NOT folded into it: it was
301
+ // never trusted as this id's content, so the result would not be either. The id stays
302
+ // out of memory and the next read asks the source, which now holds `revision`.
303
+ this.bump(blockId);
304
+ }
179
305
  }
180
306
  }
181
307
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cache-source.js","sourceRoot":"","sources":["../../../src/transform/cache-source.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache-source.js","sourceRoot":"","sources":["../../../src/transform/cache-source.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { BlockId, IBlock } from "../index.js";
2
- import type { BlockContentDigests } from "../network/struct.js";
2
+ import type { BlockBaseRevs, BlockContentDigests } from "../network/struct.js";
3
3
  import type { Tracker } from "./tracker.js";
4
4
  /** Digests for the blocks the tracker's staged transforms touch, computed WITHOUT loading anything
5
5
  * from the source. An id whose base is neither pinned nor cached is omitted rather than fetched —
@@ -17,4 +17,11 @@ export declare function computeBlockContentDigests<T extends IBlock>(tracker: Tr
17
17
  export declare function blockDigestsField(digests: BlockContentDigests | undefined): {
18
18
  blockDigests?: BlockContentDigests;
19
19
  };
20
+ /** The pend-side sibling of {@link blockDigestsField}: wraps `PendRequest.baseRevs` so it spreads
21
+ * onto a request only when some block names a base. Same reason — the pend is hashed verbatim into
22
+ * every cohort signature preimage, so a pend that names no base must serialize exactly as it did
23
+ * before the field existed. Every producer of the field goes through here. */
24
+ export declare function baseRevsField(baseRevs: BlockBaseRevs | undefined): {
25
+ baseRevs?: BlockBaseRevs;
26
+ };
20
27
  //# sourceMappingURL=digest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../../../src/transform/digest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAIhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAI5C;;;;;;;wBAOwB;AAWxB,wBAAsB,0BAA0B,CAAC,CAAC,SAAS,MAAM,EAChE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,QAAQ,EAAE,OAAO,EAAE,GACjB,OAAO,CAAC,mBAAmB,CAAC,CAW9B;AAED;;;mFAGmF;AACnF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,SAAS,GAAG;IAAE,YAAY,CAAC,EAAE,mBAAmB,CAAA;CAAE,CAElH"}
1
+ {"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../../../src/transform/digest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAI/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAI5C;;;;;;;wBAOwB;AAcxB,wBAAsB,0BAA0B,CAAC,CAAC,SAAS,MAAM,EAChE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,QAAQ,EAAE,OAAO,EAAE,GACjB,OAAO,CAAC,mBAAmB,CAAC,CAW9B;AAED;;;mFAGmF;AACnF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,SAAS,GAAG;IAAE,YAAY,CAAC,EAAE,mBAAmB,CAAA;CAAE,CAElH;AAED;;;8EAG8E;AAC9E,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,SAAS,GAAG;IAAE,QAAQ,CAAC,EAAE,aAAa,CAAA;CAAE,CAE/F"}
@@ -11,15 +11,18 @@ const log = createLogger('digest');
11
11
  * block will contain at the committing revision; `baseRev` rides along except for base-independent
12
12
  * (inserted) blocks. */
13
13
  // NOTE: declarability follows what the transaction read and staged, not read-cache residency. Each
14
- // updated block's committed base is pinned at the moment its update is staged (Tracker.update ->
15
- // BasePins) and held until the transaction boundary, so a commit of any size declares 100% of the
16
- // blocks whose bases it read — verified through the production path (`Collection.act`/`sync`) in
17
- // `test/digest-cache-coverage.spec.ts` at 2x and 4x the cache capacity. The two remaining
18
- // legitimate omissions: a delete (materializes to nothing) and a blind update to a block this node
19
- // never read whose base is not cached (nothing to declare, and a commit must never pay a network
20
- // read to describe itself). Residual gap: read-far-then-update a block read, then evicted by
21
- // 128+ other reads, and only then updated, finds nothing to pin; see the NOTE at the pin site in
22
- // `tracker.ts`.
14
+ // updated block's committed base is pinned at the moment its FIRST update is staged (Tracker.update
15
+ // -> BasePins), fixed there, and held until the transaction boundary, so a commit of any size
16
+ // declares 100% of the blocks whose bases it read — verified through the production path
17
+ // (`Collection.act`/`sync`) in `test/digest-cache-coverage.spec.ts` at 2x and 4x the cache capacity.
18
+ // `baseRev` is always the pin's revision: the one the operations were computed against, never the
19
+ // live cache's. The legitimate omissions: a delete (materializes to nothing); a blind update to a
20
+ // block this node never read (nothing to declare, and a commit must never pay a network read to
21
+ // describe itself); read-far-then-update a block read, then evicted by 128+ other reads, and only
22
+ // then updated — which pins the revision but not the content, so the base is still named on the
23
+ // pend (`Tracker.stagedBaseRevs`) and only its digest is undeclared; and a base that MOVED under its
24
+ // staged operations, which is never declared at any revision (`Tracker.revalidatePin`) and is
25
+ // re-staged before it is pended (`Collection.restageIfBasesMoved`).
23
26
  export async function computeBlockContentDigests(tracker, blockIds) {
24
27
  const digests = {};
25
28
  for (const id of blockIds) {
@@ -40,6 +43,13 @@ export async function computeBlockContentDigests(tracker, blockIds) {
40
43
  export function blockDigestsField(digests) {
41
44
  return digests && !isRecordEmpty(digests) ? { blockDigests: digests } : {};
42
45
  }
46
+ /** The pend-side sibling of {@link blockDigestsField}: wraps `PendRequest.baseRevs` so it spreads
47
+ * onto a request only when some block names a base. Same reason — the pend is hashed verbatim into
48
+ * every cohort signature preimage, so a pend that names no base must serialize exactly as it did
49
+ * before the field existed. Every producer of the field goes through here. */
50
+ export function baseRevsField(baseRevs) {
51
+ return baseRevs && !isRecordEmpty(baseRevs) ? { baseRevs } : {};
52
+ }
43
53
  /** {@link Tracker.peekMaterialized}, degraded to "undeclared" when materializing throws.
44
54
  *
45
55
  * Declaring content must never break committing it. Materializing replays the staged ops against the
@@ -1 +1 @@
1
- {"version":3,"file":"digest.js","sourceRoot":"","sources":["../../../src/transform/digest.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAG9D,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;AAEnC;;;;;;;wBAOwB;AACxB,mGAAmG;AACnG,iGAAiG;AACjG,kGAAkG;AAClG,iGAAiG;AACjG,0FAA0F;AAC1F,mGAAmG;AACnG,iGAAiG;AACjG,+FAA+F;AAC/F,iGAAiG;AACjG,gBAAgB;AAChB,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC/C,OAAmB,EACnB,QAAmB;IAEnB,MAAM,OAAO,GAAwB,EAAE,CAAC;IACxC,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,OAAO,CAAC,EAAE,CAAC,GAAG;YACb,MAAM,EAAE,MAAM,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC;YAC9C,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpE,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;mFAGmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,OAAwC;IACzE,OAAO,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5E,CAAC;AAED;;;;;;;8EAO8E;AAC9E,SAAS,UAAU,CAAmB,OAAmB,EAAE,EAAW;IACrE,IAAI,CAAC;QACJ,OAAO,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,GAAG,CAAC,4EAA4E,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACzF,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"digest.js","sourceRoot":"","sources":["../../../src/transform/digest.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAG9D,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;AAEnC;;;;;;;wBAOwB;AACxB,mGAAmG;AACnG,oGAAoG;AACpG,8FAA8F;AAC9F,yFAAyF;AACzF,qGAAqG;AACrG,kGAAkG;AAClG,kGAAkG;AAClG,gGAAgG;AAChG,oGAAoG;AACpG,gGAAgG;AAChG,qGAAqG;AACrG,8FAA8F;AAC9F,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC/C,OAAmB,EACnB,QAAmB;IAEnB,MAAM,OAAO,GAAwB,EAAE,CAAC;IACxC,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,OAAO,CAAC,EAAE,CAAC,GAAG;YACb,MAAM,EAAE,MAAM,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC;YAC9C,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpE,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;mFAGmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,OAAwC;IACzE,OAAO,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5E,CAAC;AAED;;;8EAG8E;AAC9E,MAAM,UAAU,aAAa,CAAC,QAAmC;IAChE,OAAO,QAAQ,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACjE,CAAC;AAED;;;;;;;8EAO8E;AAC9E,SAAS,UAAU,CAAmB,OAAmB,EAAE,EAAW;IACrE,IAAI,CAAC;QACJ,OAAO,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,GAAG,CAAC,4EAA4E,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACzF,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC"}
@@ -39,9 +39,13 @@ export declare function concatTransforms(...transforms: Transforms[]): Transform
39
39
  /**
40
40
  * Extracts the transform for a specific block from a Transforms object.
41
41
  *
42
- * @pitfall Updates array MUST be deep cloned - extracting without cloning shares
43
- * the array reference, causing mutations to affect the original Transforms.
42
+ * @pitfall Both `insert` and `updates` MUST be deep cloned - extracting without cloning shares
43
+ * the object/array reference, causing mutations (e.g. `applyTransform` mutating `insert` in place
44
+ * when `updates` ride along) to affect the original Transforms.
44
45
  * @see docs/internals.md "Shallow Copy of Transforms" pitfall
46
+ *
47
+ * NOTE: clones unconditionally, even for read-only callers (e.g. StorageRepo.pend's classify pass);
48
+ * if large inserts ever show up in a pend/commit profile, add a non-cloning variant for those callers.
45
49
  */
46
50
  export declare function transformForBlockId(transform: Transforms, blockId: BlockId): Transform;
47
51
  export declare function transformsFromTransform(transform: Transform, blockId: BlockId): Transforms;
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/transform/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvH;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,cAAc,QAMnG;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,QAIzE;AAED,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,cAAc;;EAOlG;AAED,8DAA8D;AAC9D,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,YAMvE;AAED,iCAAiC;AACjC,wBAAgB,eAAe,IAAI,UAAU,CAE5C;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,UAAU,GAAG,UAAU,CAQhE;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,CAYxE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAIhE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,UAAU,CAExE;AAGD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,CAOtF;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,UAAU,CAM1F;AAED,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,QAYlG;AAED,6CAA6C;AAC7C,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAWlG;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,UAAU,CAE1G"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/transform/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvH;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,cAAc,QAMnG;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,QAIzE;AAED,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,cAAc;;EAOlG;AAED,8DAA8D;AAC9D,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,YAMvE;AAED,iCAAiC;AACjC,wBAAgB,eAAe,IAAI,UAAU,CAE5C;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,UAAU,GAAG,UAAU,CAQhE;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,CAYxE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAIhE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,UAAU,CAExE;AAGD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,CAQtF;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,UAAU,CAM1F;AAED,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,QAYlG;AAED,6CAA6C;AAC7C,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAWlG;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,UAAU,CAE1G"}
@@ -90,13 +90,18 @@ export function concatTransforms(...transforms) {
90
90
  /**
91
91
  * Extracts the transform for a specific block from a Transforms object.
92
92
  *
93
- * @pitfall Updates array MUST be deep cloned - extracting without cloning shares
94
- * the array reference, causing mutations to affect the original Transforms.
93
+ * @pitfall Both `insert` and `updates` MUST be deep cloned - extracting without cloning shares
94
+ * the object/array reference, causing mutations (e.g. `applyTransform` mutating `insert` in place
95
+ * when `updates` ride along) to affect the original Transforms.
95
96
  * @see docs/internals.md "Shallow Copy of Transforms" pitfall
97
+ *
98
+ * NOTE: clones unconditionally, even for read-only callers (e.g. StorageRepo.pend's classify pass);
99
+ * if large inserts ever show up in a pend/commit profile, add a non-cloning variant for those callers.
96
100
  */
97
101
  export function transformForBlockId(transform, blockId) {
98
102
  return {
99
- ...(transform.inserts && blockId in transform.inserts ? { insert: transform.inserts[blockId] } : {}),
103
+ // Clone insert to prevent applyTransform's in-place mutation from reaching the original
104
+ ...(transform.inserts && blockId in transform.inserts ? { insert: structuredClone(transform.inserts[blockId]) } : {}),
100
105
  // Clone updates array to prevent shared references
101
106
  ...(transform.updates && blockId in transform.updates ? { updates: structuredClone(transform.updates[blockId]) } : {}),
102
107
  ...(transform.deletes?.includes(blockId) ? { delete: true } : {})
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/transform/helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/transform/helpers.ts"],"names":[],"mappings":"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"}