@optimystic/db-core 1.0.0-beta.3 → 1.1.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
@@ -14,7 +14,10 @@ export declare const rootId$: string;
14
14
  *
15
15
  * - `absent` — the key must not exist (SQL INSERT): a hit throws {@link TreeKeyTakenError},
16
16
  * discarding the whole action's staged writes.
17
- * - `keepExisting` — if the key exists, skip this entry silently (SQL INSERT OR IGNORE).
17
+ * - `keepExisting` — if the key exists, skip this entry silently. No SQL statement stages
18
+ * it any more (INSERT OR IGNORE is guarded `absent`, because skipping only the main-table
19
+ * entry would leave the statement's index entries beside a rival's row — see the
20
+ * `unchanged` paragraph in docs/internals.md); kept as a serialized log form.
18
21
  * - `absentRange` — no entry OTHER THAN this action's own key may exist in `range`
19
22
  * (secondary-UNIQUE enforcement, where uniqueness is a property of a framed key
20
23
  * PREFIX rather than one exact key: an index tree keys `indexKey ‖ primaryKey`, so
@@ -22,42 +25,101 @@ export declare const rootId$: string;
22
25
  * foreign hit throws {@link TreeRangeTakenError}. The entry being staged lands inside
23
26
  * its own range, so the scan excludes its exact key — otherwise every guarded
24
27
  * re-stage of a present key (a replay after a clean refresh) would refuse itself.
28
+ * - `unchanged` — see {@link TreeUnchangedGuard}: the only kind that says something must
29
+ * still BE here, rather than that nothing may be.
25
30
  *
26
31
  * MIXED VERSIONS: a peer running a build that predates guards destructures `[key, entry]`
27
32
  * and ignores the third slot — its replays revert to today's silent overwrite. No version
28
33
  * gating exists yet (see backlog ticket `debt-mixed-version-identify-incompatibility`).
29
34
  */
30
- export type TreeEntryGuard<TKey> = {
35
+ export type TreeEntryGuard<TKey, TEntry = unknown> = {
31
36
  kind: 'absent';
32
37
  } | {
33
38
  kind: 'keepExisting';
34
39
  } | {
35
40
  kind: 'absentRange';
36
41
  range: KeyRange<TKey>;
42
+ } | TreeUnchangedGuard<TEntry>;
43
+ /**
44
+ * "The entry I am replacing must still be exactly the one I read" — the optimistic-concurrency
45
+ * (lost-update) guard, and the only {@link TreeEntryGuard} kind that also applies to a DELETE.
46
+ * The entry at the key must be PRESENT and structurally equal to `expected` (`structuralEquals`
47
+ * in `packages/db-core/src/utility/structural-equals.ts`); otherwise the handler throws
48
+ * {@link TreeEntryChangedError}.
49
+ *
50
+ * ABSENT COUNTS AS CHANGED. The staged effect was computed from an entry image that no longer
51
+ * exists, so re-applying it is never right: an upsert would resurrect a row a rival deleted, and
52
+ * a delete would be the second of two racing deletes. Refusing both is the optimistic answer —
53
+ * the writer read a row that is now gone, and an application-level retry then affects zero rows
54
+ * sequentially. If tolerating absence on deletes is ever genuinely wanted, add a separate
55
+ * `unchangedOrAbsent` kind rather than weakening this one's contract.
56
+ *
57
+ * `expected` is the entry AS STORED, not a digest: a guard rides in the log beside its action
58
+ * under the same encoding entries already use, so a full copy round-trips by construction and no
59
+ * digest scheme has to be invented, versioned, or kept in sync with the entry encoding.
60
+ *
61
+ * NOTE: that choice roughly doubles the row bytes of every guarded log entry (the new entry plus
62
+ * a full copy of the old one). If log volume ever becomes the binding constraint, replace
63
+ * `expected` with a content digest — the block-digest utilities under
64
+ * `packages/db-core/src/transaction/` are the starting point — and accept the versioning burden
65
+ * that comes with it.
66
+ */
67
+ export type TreeUnchangedGuard<TEntry = unknown> = {
68
+ kind: 'unchanged';
69
+ /** The entry image the staged write read, as stored. */
70
+ expected: TEntry;
37
71
  };
38
- /** Represents a unit of change to a tree collection. */
39
- export type TreeReplaceAction<TKey, TEntry> = [
72
+ /** An element that writes (inserts or replaces) an entry. Any {@link TreeEntryGuard} kind is
73
+ * meaningful here. */
74
+ export type TreeUpsertElement<TKey, TEntry> = [
40
75
  key: TKey,
41
- entry?: TEntry,
42
- guard?: TreeEntryGuard<TKey>
43
- ][];
76
+ entry: TEntry,
77
+ guard?: TreeEntryGuard<TKey, TEntry>
78
+ ];
79
+ /** An element that deletes the entry at a key. Only {@link TreeUnchangedGuard} says anything a
80
+ * delete can act on — the other kinds all assert that nothing is present, which would make the
81
+ * delete a no-op by construction. The handler rejects any other kind at runtime too, since a
82
+ * replayed log entry is deserialized data that this type never policed. */
83
+ export type TreeDeleteElement<TKey, TEntry> = [
84
+ key: TKey,
85
+ entry?: undefined,
86
+ guard?: TreeUnchangedGuard<TEntry>
87
+ ];
88
+ /** Represents a unit of change to a tree collection. */
89
+ export type TreeReplaceAction<TKey, TEntry> = (TreeUpsertElement<TKey, TEntry> | TreeDeleteElement<TKey, TEntry>)[];
44
90
  /**
45
- * Thrown by the tree `replace` handler when an entry guarded `absent` finds its key
46
- * already present — at initial staging, or (the load-bearing case) at conflict replay
47
- * after a rival writer's commit was adopted. The throw discards the whole action's
48
- * staged writes (the handler runs inside an all-or-nothing Atomic wrapper) and
49
- * propagates out of the sync/commit retry loops: it is not a StaleFailure, so no
50
- * retry absorbs it, and it must never be downgraded to a retryable condition.
91
+ * Base of every refusal a {@link TreeEntryGuard} raises out of the tree `replace` handler at
92
+ * initial staging, or (the load-bearing case) at conflict replay after a rival writer's commit
93
+ * was adopted. One contract, stated once for every subclass:
94
+ *
95
+ * - The throw **discards the whole action's staged writes** the handler runs inside an
96
+ * all-or-nothing Atomic wrapper, so not one entry of a multi-entry action lands.
97
+ * - It is **not a `StaleFailure`**, so neither `Collection.sync`'s retry loop nor
98
+ * `TransactionCoordinator.commit`'s stale-loss re-drive absorbs it; it propagates out of the
99
+ * losing commit, and it must never be downgraded to a retryable condition.
100
+ *
101
+ * Subclasses split by WHAT was refused, because consumers map them differently: a
102
+ * {@link TreeKeyTakenError} is a uniqueness violation (the Quereus bridge renders it as
103
+ * `UNIQUE constraint failed`), while a {@link TreeEntryChangedError} is a lost update. Catch
104
+ * this base to treat any guard refusal uniformly; catch a subclass to say which happened.
51
105
  */
52
- export declare class TreeKeyTakenError<TKey = unknown> extends Error {
106
+ export declare class TreeGuardRefusedError<TKey = unknown> extends Error {
53
107
  /** The collection whose tree refused the entry. */
54
108
  readonly collectionId: CollectionId;
55
- /** The key some other writer already committed (for the `absentRange` subclass: the
56
- * key this action was staging, whose claimed range a rival occupies). */
109
+ /** The key whose staged entry was refused. */
57
110
  readonly key: TKey;
58
111
  constructor(
59
112
  /** The collection whose tree refused the entry. */
60
113
  collectionId: CollectionId,
114
+ /** The key whose staged entry was refused. */
115
+ key: TKey, message: string);
116
+ }
117
+ /**
118
+ * Thrown when an entry guarded `absent` finds its key already present: a duplicate-key
119
+ * refusal. See {@link TreeGuardRefusedError} for the contract every guard refusal shares.
120
+ */
121
+ export declare class TreeKeyTakenError<TKey = unknown> extends TreeGuardRefusedError<TKey> {
122
+ constructor(collectionId: CollectionId,
61
123
  /** The key some other writer already committed (for the `absentRange` subclass: the
62
124
  * key this action was staging, whose claimed range a rival occupies). */
63
125
  key: TKey,
@@ -88,4 +150,50 @@ export declare class TreeRangeTakenError<TKey = unknown> extends TreeKeyTakenErr
88
150
  /** The committed key found inside `range` that is not `key`. */
89
151
  occupant: TKey);
90
152
  }
153
+ /**
154
+ * The {@link TreeUnchangedGuard} refusal: the entry at `key` is no longer the one the staged
155
+ * write read — a rival committed a different entry there, or removed it (`actual` is
156
+ * `undefined`). A lost update, NOT a uniqueness violation, which is why this deliberately does
157
+ * NOT subclass {@link TreeKeyTakenError}: the Quereus bridge renders every `TreeKeyTakenError`
158
+ * as that collection's registered `UNIQUE constraint failed` message (`mapCommitRefusal` in
159
+ * `packages/quereus-plugin-optimystic/src/optimystic-adapter/txn-bridge.ts`), and reporting a
160
+ * concurrent-update refusal as a uniqueness failure would mislead every client that reads it.
161
+ * The shared contract lives on {@link TreeGuardRefusedError}.
162
+ */
163
+ export declare class TreeEntryChangedError<TKey = unknown, TEntry = unknown> extends TreeGuardRefusedError<TKey> {
164
+ /** The entry image the staged write read, as carried by its guard. */
165
+ readonly expected: TEntry;
166
+ /** What is committed at `key` now; `undefined` when the entry is gone entirely. */
167
+ readonly actual: TEntry | undefined;
168
+ constructor(collectionId: CollectionId,
169
+ /** The key whose entry the staged write was replacing or deleting. */
170
+ key: TKey,
171
+ /** The entry image the staged write read, as carried by its guard. */
172
+ expected: TEntry,
173
+ /** What is committed at `key` now; `undefined` when the entry is gone entirely. */
174
+ actual: TEntry | undefined);
175
+ }
176
+ /**
177
+ * A DELETE element carries a guard kind no delete can act on. NOT a concurrency refusal and
178
+ * deliberately not a {@link TreeGuardRefusedError}: every other kind asserts that nothing is
179
+ * present, which would make the delete a no-op by construction, so this is a malformed action —
180
+ * a caller bug, or a log entry written by a build whose element types disagree with this one.
181
+ * The handler raises it rather than ignoring the guard (the pre-guard behaviour) so a writer
182
+ * never believes an unenforceable guard is being enforced.
183
+ */
184
+ export declare class TreeDeleteGuardKindError<TKey = unknown> extends Error {
185
+ /** The collection whose tree rejected the element. */
186
+ readonly collectionId: CollectionId;
187
+ /** The key the malformed delete named. */
188
+ readonly key: TKey;
189
+ /** The `kind` that was carried; only `'unchanged'` is meaningful on a delete. */
190
+ readonly guardKind: string;
191
+ constructor(
192
+ /** The collection whose tree rejected the element. */
193
+ collectionId: CollectionId,
194
+ /** The key the malformed delete named. */
195
+ key: TKey,
196
+ /** The `kind` that was carried; only `'unchanged'` is meaningful on a delete. */
197
+ guardKind: string);
198
+ }
91
199
  //# sourceMappingURL=struct.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"struct.d.ts","sourceRoot":"","sources":["../../../../src/collections/tree/struct.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAKrD,eAAO,MAAM,mBAAmB,QAA8C,CAAC;AAO/E,MAAM,MAAM,yBAAyB,GAAG,qBAAqB,GAAG;IAC/D,MAAM,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,OAAO,QAA8C,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,cAAc,CAAC,IAAI,IAC5B;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAElD,wDAAwD;AACxD,MAAM,MAAM,iBAAiB,CAAC,IAAI,EAAE,MAAM,IAAI;IAE7C,GAAG,EAAE,IAAI;IAET,KAAK,CAAC,EAAE,MAAM;IAId,KAAK,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC;CAC5B,EAAE,CAAC;AAEJ;;;;;;;GAOG;AACH,qBAAa,iBAAiB,CAAC,IAAI,GAAG,OAAO,CAAE,SAAQ,KAAK;IAE1D,mDAAmD;aACnC,YAAY,EAAE,YAAY;IAC1C;6EACyE;aACzD,GAAG,EAAE,IAAI;;IAJzB,mDAAmD;IACnC,YAAY,EAAE,YAAY;IAC1C;6EACyE;IACzD,GAAG,EAAE,IAAI;IACzB,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM;CAKjB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,mBAAmB,CAAC,IAAI,GAAG,OAAO,CAAE,SAAQ,iBAAiB,CAAC,IAAI,CAAC;IAK9E,+CAA+C;aAC/B,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC;IACrC,gEAAgE;aAChD,QAAQ,EAAE,IAAI;gBAN9B,YAAY,EAAE,YAAY;IAC1B,kFAAkF;IAClF,GAAG,EAAE,IAAI;IACT,+CAA+C;IAC/B,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC;IACrC,gEAAgE;IAChD,QAAQ,EAAE,IAAI;CAO/B"}
1
+ {"version":3,"file":"struct.d.ts","sourceRoot":"","sources":["../../../../src/collections/tree/struct.ts"],"names":[],"mappings":"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"}
@@ -8,27 +8,47 @@ registerCollectionType({
8
8
  });
9
9
  export const rootId$ = nameof("rootId");
10
10
  /**
11
- * Thrown by the tree `replace` handler when an entry guarded `absent` finds its key
12
- * already present — at initial staging, or (the load-bearing case) at conflict replay
13
- * after a rival writer's commit was adopted. The throw discards the whole action's
14
- * staged writes (the handler runs inside an all-or-nothing Atomic wrapper) and
15
- * propagates out of the sync/commit retry loops: it is not a StaleFailure, so no
16
- * retry absorbs it, and it must never be downgraded to a retryable condition.
11
+ * Base of every refusal a {@link TreeEntryGuard} raises out of the tree `replace` handler at
12
+ * initial staging, or (the load-bearing case) at conflict replay after a rival writer's commit
13
+ * was adopted. One contract, stated once for every subclass:
14
+ *
15
+ * - The throw **discards the whole action's staged writes** the handler runs inside an
16
+ * all-or-nothing Atomic wrapper, so not one entry of a multi-entry action lands.
17
+ * - It is **not a `StaleFailure`**, so neither `Collection.sync`'s retry loop nor
18
+ * `TransactionCoordinator.commit`'s stale-loss re-drive absorbs it; it propagates out of the
19
+ * losing commit, and it must never be downgraded to a retryable condition.
20
+ *
21
+ * Subclasses split by WHAT was refused, because consumers map them differently: a
22
+ * {@link TreeKeyTakenError} is a uniqueness violation (the Quereus bridge renders it as
23
+ * `UNIQUE constraint failed`), while a {@link TreeEntryChangedError} is a lost update. Catch
24
+ * this base to treat any guard refusal uniformly; catch a subclass to say which happened.
17
25
  */
18
- export class TreeKeyTakenError extends Error {
26
+ export class TreeGuardRefusedError extends Error {
19
27
  collectionId;
20
28
  key;
21
29
  constructor(
22
30
  /** The collection whose tree refused the entry. */
23
31
  collectionId,
32
+ /** The key whose staged entry was refused. */
33
+ key, message) {
34
+ super(message);
35
+ this.collectionId = collectionId;
36
+ this.key = key;
37
+ this.name = 'TreeGuardRefusedError';
38
+ }
39
+ }
40
+ /**
41
+ * Thrown when an entry guarded `absent` finds its key already present: a duplicate-key
42
+ * refusal. See {@link TreeGuardRefusedError} for the contract every guard refusal shares.
43
+ */
44
+ export class TreeKeyTakenError extends TreeGuardRefusedError {
45
+ constructor(collectionId,
24
46
  /** The key some other writer already committed (for the `absentRange` subclass: the
25
47
  * key this action was staging, whose claimed range a rival occupies). */
26
48
  key,
27
49
  /** Subclass override of the rendered message; the default names the exact-key refusal. */
28
50
  message) {
29
- super(message ?? `Tree collection ${collectionId}: key ${renderKey(key)} is already taken by a committed entry`);
30
- this.collectionId = collectionId;
31
- this.key = key;
51
+ super(collectionId, key, message ?? `Tree collection ${collectionId}: key ${renderKey(key)} is already taken by a committed entry`);
32
52
  this.name = 'TreeKeyTakenError';
33
53
  }
34
54
  }
@@ -60,9 +80,64 @@ export class TreeRangeTakenError extends TreeKeyTakenError {
60
80
  this.name = 'TreeRangeTakenError';
61
81
  }
62
82
  }
83
+ /**
84
+ * The {@link TreeUnchangedGuard} refusal: the entry at `key` is no longer the one the staged
85
+ * write read — a rival committed a different entry there, or removed it (`actual` is
86
+ * `undefined`). A lost update, NOT a uniqueness violation, which is why this deliberately does
87
+ * NOT subclass {@link TreeKeyTakenError}: the Quereus bridge renders every `TreeKeyTakenError`
88
+ * as that collection's registered `UNIQUE constraint failed` message (`mapCommitRefusal` in
89
+ * `packages/quereus-plugin-optimystic/src/optimystic-adapter/txn-bridge.ts`), and reporting a
90
+ * concurrent-update refusal as a uniqueness failure would mislead every client that reads it.
91
+ * The shared contract lives on {@link TreeGuardRefusedError}.
92
+ */
93
+ export class TreeEntryChangedError extends TreeGuardRefusedError {
94
+ expected;
95
+ actual;
96
+ constructor(collectionId,
97
+ /** The key whose entry the staged write was replacing or deleting. */
98
+ key,
99
+ /** The entry image the staged write read, as carried by its guard. */
100
+ expected,
101
+ /** What is committed at `key` now; `undefined` when the entry is gone entirely. */
102
+ actual) {
103
+ super(collectionId, key, `Tree collection ${collectionId}: the entry at key ${renderKey(key)} was `
104
+ + `${actual === undefined ? 'removed' : 'changed'} by another writer since this change read it`);
105
+ this.expected = expected;
106
+ this.actual = actual;
107
+ this.name = 'TreeEntryChangedError';
108
+ }
109
+ }
110
+ /**
111
+ * A DELETE element carries a guard kind no delete can act on. NOT a concurrency refusal and
112
+ * deliberately not a {@link TreeGuardRefusedError}: every other kind asserts that nothing is
113
+ * present, which would make the delete a no-op by construction, so this is a malformed action —
114
+ * a caller bug, or a log entry written by a build whose element types disagree with this one.
115
+ * The handler raises it rather than ignoring the guard (the pre-guard behaviour) so a writer
116
+ * never believes an unenforceable guard is being enforced.
117
+ */
118
+ export class TreeDeleteGuardKindError extends Error {
119
+ collectionId;
120
+ key;
121
+ guardKind;
122
+ constructor(
123
+ /** The collection whose tree rejected the element. */
124
+ collectionId,
125
+ /** The key the malformed delete named. */
126
+ key,
127
+ /** The `kind` that was carried; only `'unchanged'` is meaningful on a delete. */
128
+ guardKind) {
129
+ super(`Tree collection ${collectionId}: the delete of key ${renderKey(key)} carries a `
130
+ + `'${guardKind}' guard; only 'unchanged' is meaningful on a delete`);
131
+ this.collectionId = collectionId;
132
+ this.key = key;
133
+ this.guardKind = guardKind;
134
+ this.name = 'TreeDeleteGuardKindError';
135
+ }
136
+ }
63
137
  /** String keys render JSON-quoted so framing control bytes stay visible/escaped in logs;
64
138
  * everything else via String() — JSON.stringify would throw on a bigint key, and an error
65
- * constructor must never be the second failure. */
139
+ * constructor must never be the second failure. Module-private on purpose: every tree message
140
+ * renders a key the same way because every one of them is constructed in this file. */
66
141
  function renderKey(key) {
67
142
  return typeof key === 'string' ? JSON.stringify(key) : String(key);
68
143
  }
@@ -1 +1 @@
1
- {"version":3,"file":"struct.js","sourceRoot":"","sources":["../../../../src/collections/tree/struct.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;AAE/E,sBAAsB,CAAC;IACtB,SAAS,EAAE,mBAAmB;IAC9B,IAAI,EAAE,MAAM;CACZ,CAAC,CAAC;AAMH,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAA4B,QAAQ,CAAC,CAAC;AAyCnE;;;;;;;GAOG;AACH,MAAM,OAAO,iBAAkC,SAAQ,KAAK;IAG1C;IAGA;IALjB;IACC,mDAAmD;IACnC,YAA0B;IAC1C;6EACyE;IACzD,GAAS;IACzB,0FAA0F;IAC1F,OAAgB;QAEhB,KAAK,CAAC,OAAO,IAAI,mBAAmB,YAAY,SAAS,SAAS,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QAPjG,iBAAY,GAAZ,YAAY,CAAc;QAG1B,QAAG,GAAH,GAAG,CAAM;QAKzB,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IACjC,CAAC;CACD;AAED;;;;;;;;;;GAUG;AACH,MAAM,OAAO,mBAAoC,SAAQ,iBAAuB;IAM9D;IAEA;IAPjB,YACC,YAA0B;IAC1B,kFAAkF;IAClF,GAAS;IACT,+CAA+C;IAC/B,KAAqB;IACrC,gEAAgE;IAChD,QAAc;QAE9B,KAAK,CAAC,YAAY,EAAE,GAAG,EACtB,mBAAmB,YAAY,SAAS,SAAS,CAAC,GAAG,CAAC,sCAAsC;cAC1F,uCAAuC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QANjD,UAAK,GAAL,KAAK,CAAgB;QAErB,aAAQ,GAAR,QAAQ,CAAM;QAK9B,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACnC,CAAC;CACD;AAED;;mDAEmD;AACnD,SAAS,SAAS,CAAC,GAAY;IAC9B,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACpE,CAAC"}
1
+ {"version":3,"file":"struct.js","sourceRoot":"","sources":["../../../../src/collections/tree/struct.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { Collection, type CollectionId, type CollectionSnapshot, type ReadViewOptions } from "../../collection/index.js";
2
- import type { ITransactor, ActionId } from "../../index.js";
2
+ import type { ITransactor, ActionId, WriteDurability } from "../../index.js";
3
3
  import { type Path, type KeyRange } from "../../btree/index.js";
4
4
  import { type TreeReplaceAction } from "./struct.js";
5
5
  /**
@@ -52,7 +52,17 @@ export declare class Tree<TKey, TEntry> implements TreeReadView<TKey, TEntry> {
52
52
  * over the collection's existing tracker. Either way the result is written back into `held` so
53
53
  * the `replace` handler's path-invalidation targets the very btree reads go through. */
54
54
  private static attach;
55
- replace(data: TreeReplaceAction<TKey, TEntry>): Promise<void>;
55
+ /** Stage a mutation and flush it. Forwards the collection's answer verbatim — see
56
+ * {@link Collection.sync} for what `undefined` means and why a torn commit's `torn` list must
57
+ * survive the trip. This layer never interprets the value.
58
+ *
59
+ * A call that throws leaves nothing staged (see {@link Collection.actAndSync}), so the mutation
60
+ * cannot ride along with a later `replace`. Whether it reached STORAGE is what the error says:
61
+ * a `TornActionError` with `final: true` means it did not and submitting it again stores it
62
+ * once; `final: false` means that could not be established. A `SyncRetryExhaustedError` is not
63
+ * a promise either way — the write path's last budgeted attempt, and a deadline, are not
64
+ * followed by the refresh that would have settled it (see `Collection.syncAttempts`). */
65
+ replace(data: TreeReplaceAction<TKey, TEntry>): Promise<WriteDurability | undefined>;
56
66
  /** Stage a mutation into the collection's tracker WITHOUT flushing it to the
57
67
  * transactor. Reads through this same Tree instance see the staged change;
58
68
  * call {@link sync} to persist it, or {@link snapshot}/{@link restore} to drop it. This
@@ -62,7 +72,7 @@ export declare class Tree<TKey, TEntry> implements TreeReadView<TKey, TEntry> {
62
72
  stage(data: TreeReplaceAction<TKey, TEntry>): Promise<void>;
63
73
  /** Flush all staged (and any other pending) changes to the transactor.
64
74
  * Equivalent to the flush half of {@link replace}. */
65
- sync(): Promise<void>;
75
+ sync(): Promise<WriteDurability | undefined>;
66
76
  /** Whether {@link sync} has anything to push — see
67
77
  * {@link Collection.hasUnsyncedChanges}. `false` means the commit half of
68
78
  * {@link sync} is a no-op, so a caller flushing several trees can skip the ones
@@ -1 +1 @@
1
- {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../../../src/collections/tree/tree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../../../src/collections/tree/tree.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,69 @@
1
1
  import { Collection } from "../../collection/index.js";
2
2
  import { BTree } from "../../btree/index.js";
3
3
  import { CollectionTrunk } from "./collection-trunk.js";
4
- import { TreeHeaderBlockType, TreeKeyTakenError, TreeRangeTakenError } from "./struct.js";
4
+ import { structuralEquals } from "../../utility/structural-equals.js";
5
+ import { TreeHeaderBlockType, TreeDeleteGuardKindError, TreeEntryChangedError, TreeKeyTakenError, TreeRangeTakenError, } from "./struct.js";
6
+ /**
7
+ * Enforce a guard carried by an UPSERT element against the CURRENT content of `actionTree` —
8
+ * the same Atomic store the upsert writes to, so it sees what earlier elements of this same
9
+ * replay already staged or deleted (an UPDATE's delete-old half runs before its guarded insert
10
+ * half). Throws the guard's refusal, which discards the whole action's staged writes.
11
+ *
12
+ * @returns `'skip'` when the element must be left unwritten (`keepExisting` found the key
13
+ * occupied — the INSERT OR IGNORE disposition), `'proceed'` otherwise.
14
+ */
15
+ async function enforceUpsertGuard(actionTree, id, key, guard, keyFromEntry, compare) {
16
+ switch (guard.kind) {
17
+ case 'absentRange': {
18
+ // Secondary-UNIQUE: the claimed range (a unique index's framed value prefix) must hold
19
+ // no entry other than this action's own key. Two short descents (range start and end)
20
+ // plus an early-exit walk. The guard is plain data (it is serialized into the log with
21
+ // its action), and BTree.range reads the range's fields only — so a KeyRange that has
22
+ // round-tripped through JSON is scanned exactly like a live instance.
23
+ for await (const path of actionTree.range(guard.range)) {
24
+ const occupant = actionTree.at(path);
25
+ if (occupant === undefined)
26
+ continue;
27
+ const occupantKey = keyFromEntry(occupant);
28
+ if (compare(occupantKey, key) === 0)
29
+ continue; // self-exclusion
30
+ throw new TreeRangeTakenError(id, key, guard.range, occupantKey);
31
+ }
32
+ return 'proceed';
33
+ }
34
+ case 'unchanged': {
35
+ assertEntryUnchanged(id, key, guard.expected, actionTree.at(await actionTree.find(key)));
36
+ return 'proceed';
37
+ }
38
+ case 'absent':
39
+ case 'keepExisting': {
40
+ if (!(await actionTree.find(key)).on)
41
+ return 'proceed';
42
+ if (guard.kind === 'absent')
43
+ throw new TreeKeyTakenError(id, key);
44
+ // keepExisting: leave the present (rival's) entry in place and skip this element.
45
+ return 'skip';
46
+ }
47
+ }
48
+ }
49
+ /** The lost-update check shared by guarded upserts and guarded deletes: the committed entry must
50
+ * be present AND structurally equal to what the staged write read. Absence counts as changed —
51
+ * see {@link TreeUnchangedGuard} for why that is the contract on both dispositions. */
52
+ function assertEntryUnchanged(id, key, expected, actual) {
53
+ if (actual === undefined || !structuralEquals(actual, expected)) {
54
+ throw new TreeEntryChangedError(id, key, expected, actual);
55
+ }
56
+ }
57
+ /** Narrow a DELETE element's guard to the only kind a delete can act on. The element type already
58
+ * says this ({@link TreeDeleteElement}), but a replayed log entry is deserialized data that no
59
+ * type policed, so the handler re-checks it and throws {@link TreeDeleteGuardKindError} rather
60
+ * than silently ignoring a guard the writer believed was being enforced. */
61
+ function deleteGuardExpected(id, key, guard) {
62
+ if (guard.kind !== 'unchanged') {
63
+ throw new TreeDeleteGuardKindError(id, key, guard.kind);
64
+ }
65
+ return guard.expected;
66
+ }
5
67
  export class Tree {
6
68
  collection;
7
69
  btree;
@@ -59,48 +121,43 @@ export class Tree {
59
121
  // public constructor; no btree API change needed.
60
122
  const actionTree = new BTree(trx, new CollectionTrunk(trx, id), keyFromEntry, compare, nodeCapacity);
61
123
  for (const [key, entry, guard] of actions) {
124
+ // NOTE: an element is a DELETE when its entry slot is falsy, not when it is
125
+ // strictly `undefined`. That is deliberate and load-bearing: JSON encodes the
126
+ // empty slot of `[key, undefined]` as `null`, so a replayed log entry arrives
127
+ // as `[key, null]` and a `!== undefined` test would upsert `null` over the row.
128
+ // JSON really is the live encoding, not just a hypothetical: the p2p repo
129
+ // protocol stringifies and parses every message (`protocol-client.ts` and
130
+ // `repo/service.ts` in `packages/db-p2p/src/`). The in-process test transactors
131
+ // use `structuredClone`, which preserves `undefined` — so no test that goes
132
+ // only through them can reach this shape; the round-trip spec below stages the
133
+ // JSON shape explicitly for that reason.
134
+ // The cost is that a falsy-but-real entry (`''`, `0`, `false`) reads as a
135
+ // delete. No entry type in this repo is falsy today (rows encode to a non-empty
136
+ // string or Uint8Array; index entries are arrays); if one ever is, this needs an
137
+ // explicit delete marker in the tuple rather than a tighter comparison.
62
138
  if (entry) {
63
139
  // Enforce the entry's guard (if any) on EVERY handler run — initial staging
64
- // and every conflict replay — so the uniqueness decision is re-made against
65
- // the newest adopted committed state, not just the stage-time snapshot.
66
- // A throw here discards the whole action's staged writes (Atomic wrapper).
67
- if (guard !== undefined) {
68
- if (guard.kind === 'absentRange') {
69
- // Secondary-UNIQUE: the claimed range (a unique index's framed
70
- // value prefix) must hold no entry other than this action's own
71
- // key. Two short descents (range start and end) plus an early-exit
72
- // walk, over the SAME store the upsert below writes to, so it sees entries earlier
73
- // actions of this replay already staged or deleted (an UPDATE's
74
- // delete-old half runs before its guarded insert half). The guard
75
- // is plain data (it is serialized into the log with its action), and
76
- // BTree.range reads the range's fields only — so a KeyRange that has
77
- // round-tripped through JSON is scanned exactly like a live instance.
78
- for await (const path of actionTree.range(guard.range)) {
79
- const occupant = actionTree.at(path);
80
- if (occupant === undefined)
81
- continue;
82
- const occupantKey = keyFromEntry(occupant);
83
- if (compare(occupantKey, key) === 0)
84
- continue; // self-exclusion
85
- throw new TreeRangeTakenError(id, key, guard.range, occupantKey);
86
- }
87
- }
88
- else {
89
- const found = await actionTree.find(key);
90
- if (found.on) {
91
- if (guard.kind === 'absent') {
92
- throw new TreeKeyTakenError(id, key);
93
- }
94
- // keepExisting: leave the present (rival's) entry in place and
95
- // skip this entry silently — the INSERT OR IGNORE disposition.
96
- continue;
97
- }
98
- }
140
+ // and every conflict replay — so the decision is re-made against the newest
141
+ // adopted committed state, not just the stage-time snapshot. A throw here
142
+ // discards the whole action's staged writes (Atomic wrapper).
143
+ // Truthiness, not `!== undefined`, for the same round-trip reason as the entry
144
+ // slot above: an explicitly-passed `undefined` guard (the shape every unguarded
145
+ // index write stages) comes back from JSON as `null`, and reading `.kind` off it
146
+ // would throw a TypeError mid-replay instead of meaning "no guard".
147
+ if (guard
148
+ && await enforceUpsertGuard(actionTree, id, key, guard, keyFromEntry, compare) === 'skip') {
149
+ continue;
99
150
  }
100
151
  await actionTree.upsert(entry);
101
152
  }
102
153
  else {
103
- await actionTree.deleteAt((await actionTree.find(key)));
154
+ // The path is found once and reused: the guard check reads it and `deleteAt`
155
+ // consumes it, with no mutation in between to invalidate it.
156
+ const path = await actionTree.find(key);
157
+ if (guard) {
158
+ assertEntryUnchanged(id, key, deleteGuardExpected(id, key, guard), actionTree.at(path));
159
+ }
160
+ await actionTree.deleteAt(path);
104
161
  }
105
162
  }
106
163
  // Mutations landed in `trx`, not the read btree, so its version counter never moved.
@@ -133,9 +190,18 @@ export class Tree {
133
190
  ?? new BTree(collection.tracker, new CollectionTrunk(collection.tracker, collection.id), keyFromEntry, compare, nodeCapacity);
134
191
  return new Tree(collection, held.btree, keyFromEntry, compare);
135
192
  }
193
+ /** Stage a mutation and flush it. Forwards the collection's answer verbatim — see
194
+ * {@link Collection.sync} for what `undefined` means and why a torn commit's `torn` list must
195
+ * survive the trip. This layer never interprets the value.
196
+ *
197
+ * A call that throws leaves nothing staged (see {@link Collection.actAndSync}), so the mutation
198
+ * cannot ride along with a later `replace`. Whether it reached STORAGE is what the error says:
199
+ * a `TornActionError` with `final: true` means it did not and submitting it again stores it
200
+ * once; `final: false` means that could not be established. A `SyncRetryExhaustedError` is not
201
+ * a promise either way — the write path's last budgeted attempt, and a deadline, are not
202
+ * followed by the refresh that would have settled it (see `Collection.syncAttempts`). */
136
203
  async replace(data) {
137
- await this.collection.act({ type: "replace", data });
138
- await this.collection.updateAndSync();
204
+ return await this.collection.actAndSync([{ type: "replace", data }]);
139
205
  }
140
206
  /** Stage a mutation into the collection's tracker WITHOUT flushing it to the
141
207
  * transactor. Reads through this same Tree instance see the staged change;
@@ -149,7 +215,7 @@ export class Tree {
149
215
  /** Flush all staged (and any other pending) changes to the transactor.
150
216
  * Equivalent to the flush half of {@link replace}. */
151
217
  async sync() {
152
- await this.collection.updateAndSync();
218
+ return await this.collection.updateAndSync();
153
219
  }
154
220
  /** Whether {@link sync} has anything to push — see
155
221
  * {@link Collection.hasUnsyncedChanges}. `false` means the commit half of
@@ -1 +1 @@
1
- {"version":3,"file":"tree.js","sourceRoot":"","sources":["../../../../src/collections/tree/tree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tree.js","sourceRoot":"","sources":["../../../../src/collections/tree/tree.ts"],"names":[],"mappings":"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"}
@@ -18,9 +18,9 @@ export * from "./utility/groupby.js";
18
18
  export * from "./utility/hash-string.js";
19
19
  export * from "./utility/latches.js";
20
20
  export * from "./utility/nameof.js";
21
+ export * from "./utility/structural-equals.js";
21
22
  export * from "./utility/ensured.js";
22
23
  export * from "./utility/pending.js";
23
- export * from "./utility/block-id-to-bytes.js";
24
24
  export * from "./utility/lru-map.js";
25
25
  export * from "./utility/backoff.js";
26
26
  //# sourceMappingURL=index.d.ts.map