@optimystic/db-core 0.14.0 → 0.16.2

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 (301) hide show
  1. package/dist/src/blocks/block-store.d.ts +18 -1
  2. package/dist/src/blocks/block-store.d.ts.map +1 -1
  3. package/dist/src/blocks/helpers.d.ts +2 -2
  4. package/dist/src/blocks/helpers.d.ts.map +1 -1
  5. package/dist/src/blocks/helpers.js +2 -2
  6. package/dist/src/blocks/helpers.js.map +1 -1
  7. package/dist/src/btree/btree.d.ts +27 -6
  8. package/dist/src/btree/btree.d.ts.map +1 -1
  9. package/dist/src/btree/btree.js +104 -61
  10. package/dist/src/btree/btree.js.map +1 -1
  11. package/dist/src/chain/chain.d.ts.map +1 -1
  12. package/dist/src/chain/chain.js +11 -1
  13. package/dist/src/chain/chain.js.map +1 -1
  14. package/dist/src/cluster/index.d.ts +1 -0
  15. package/dist/src/cluster/index.d.ts.map +1 -1
  16. package/dist/src/cluster/index.js +1 -0
  17. package/dist/src/cluster/index.js.map +1 -1
  18. package/dist/src/cluster/membership.d.ts +49 -0
  19. package/dist/src/cluster/membership.d.ts.map +1 -0
  20. package/dist/src/cluster/membership.js +75 -0
  21. package/dist/src/cluster/membership.js.map +1 -0
  22. package/dist/src/cluster/structs.d.ts +50 -1
  23. package/dist/src/cluster/structs.d.ts.map +1 -1
  24. package/dist/src/cluster/structs.js +9 -1
  25. package/dist/src/cluster/structs.js.map +1 -1
  26. package/dist/src/cohort-topic/addressing.d.ts +8 -2
  27. package/dist/src/cohort-topic/addressing.d.ts.map +1 -1
  28. package/dist/src/cohort-topic/addressing.js +11 -3
  29. package/dist/src/cohort-topic/addressing.js.map +1 -1
  30. package/dist/src/cohort-topic/antidos/bootstrap-evidence.d.ts +13 -7
  31. package/dist/src/cohort-topic/antidos/bootstrap-evidence.d.ts.map +1 -1
  32. package/dist/src/cohort-topic/antidos/bootstrap-evidence.js +17 -6
  33. package/dist/src/cohort-topic/antidos/bootstrap-evidence.js.map +1 -1
  34. package/dist/src/cohort-topic/antidos/replay-guard.d.ts +17 -0
  35. package/dist/src/cohort-topic/antidos/replay-guard.d.ts.map +1 -1
  36. package/dist/src/cohort-topic/antidos/replay-guard.js +33 -0
  37. package/dist/src/cohort-topic/antidos/replay-guard.js.map +1 -1
  38. package/dist/src/cohort-topic/antidos/topic-budget.d.ts +7 -0
  39. package/dist/src/cohort-topic/antidos/topic-budget.d.ts.map +1 -1
  40. package/dist/src/cohort-topic/antidos/topic-budget.js +8 -2
  41. package/dist/src/cohort-topic/antidos/topic-budget.js.map +1 -1
  42. package/dist/src/cohort-topic/coldstart.d.ts +34 -14
  43. package/dist/src/cohort-topic/coldstart.d.ts.map +1 -1
  44. package/dist/src/cohort-topic/coldstart.js +25 -11
  45. package/dist/src/cohort-topic/coldstart.js.map +1 -1
  46. package/dist/src/cohort-topic/gossip/bus.d.ts +12 -1
  47. package/dist/src/cohort-topic/gossip/bus.d.ts.map +1 -1
  48. package/dist/src/cohort-topic/gossip/bus.js +27 -1
  49. package/dist/src/cohort-topic/gossip/bus.js.map +1 -1
  50. package/dist/src/cohort-topic/gossip/view.d.ts +8 -0
  51. package/dist/src/cohort-topic/gossip/view.d.ts.map +1 -1
  52. package/dist/src/cohort-topic/gossip/view.js +17 -1
  53. package/dist/src/cohort-topic/gossip/view.js.map +1 -1
  54. package/dist/src/cohort-topic/member-engine.d.ts +10 -3
  55. package/dist/src/cohort-topic/member-engine.d.ts.map +1 -1
  56. package/dist/src/cohort-topic/member-engine.js +29 -14
  57. package/dist/src/cohort-topic/member-engine.js.map +1 -1
  58. package/dist/src/cohort-topic/membership/publisher.d.ts +14 -7
  59. package/dist/src/cohort-topic/membership/publisher.d.ts.map +1 -1
  60. package/dist/src/cohort-topic/membership/publisher.js +15 -27
  61. package/dist/src/cohort-topic/membership/publisher.js.map +1 -1
  62. package/dist/src/cohort-topic/membership/verifier.d.ts +35 -0
  63. package/dist/src/cohort-topic/membership/verifier.d.ts.map +1 -1
  64. package/dist/src/cohort-topic/membership/verifier.js +88 -3
  65. package/dist/src/cohort-topic/membership/verifier.js.map +1 -1
  66. package/dist/src/cohort-topic/promotion.d.ts +7 -0
  67. package/dist/src/cohort-topic/promotion.d.ts.map +1 -1
  68. package/dist/src/cohort-topic/promotion.js +16 -2
  69. package/dist/src/cohort-topic/promotion.js.map +1 -1
  70. package/dist/src/cohort-topic/registration/renewal.d.ts +18 -0
  71. package/dist/src/cohort-topic/registration/renewal.d.ts.map +1 -1
  72. package/dist/src/cohort-topic/registration/renewal.js +54 -0
  73. package/dist/src/cohort-topic/registration/renewal.js.map +1 -1
  74. package/dist/src/cohort-topic/registration/types.d.ts +12 -0
  75. package/dist/src/cohort-topic/registration/types.d.ts.map +1 -1
  76. package/dist/src/cohort-topic/registration/types.js +14 -0
  77. package/dist/src/cohort-topic/registration/types.js.map +1 -1
  78. package/dist/src/cohort-topic/service.d.ts +4 -3
  79. package/dist/src/cohort-topic/service.d.ts.map +1 -1
  80. package/dist/src/cohort-topic/service.js +38 -12
  81. package/dist/src/cohort-topic/service.js.map +1 -1
  82. package/dist/src/cohort-topic/sig/payloads.d.ts +23 -7
  83. package/dist/src/cohort-topic/sig/payloads.d.ts.map +1 -1
  84. package/dist/src/cohort-topic/sig/payloads.js +22 -6
  85. package/dist/src/cohort-topic/sig/payloads.js.map +1 -1
  86. package/dist/src/cohort-topic/traffic.d.ts +6 -0
  87. package/dist/src/cohort-topic/traffic.d.ts.map +1 -1
  88. package/dist/src/cohort-topic/traffic.js +16 -1
  89. package/dist/src/cohort-topic/traffic.js.map +1 -1
  90. package/dist/src/cohort-topic/walk.d.ts +22 -7
  91. package/dist/src/cohort-topic/walk.d.ts.map +1 -1
  92. package/dist/src/cohort-topic/walk.js +78 -18
  93. package/dist/src/cohort-topic/walk.js.map +1 -1
  94. package/dist/src/cohort-topic/wire/codec.d.ts +3 -1
  95. package/dist/src/cohort-topic/wire/codec.d.ts.map +1 -1
  96. package/dist/src/cohort-topic/wire/codec.js +7 -1
  97. package/dist/src/cohort-topic/wire/codec.js.map +1 -1
  98. package/dist/src/cohort-topic/wire/index.d.ts +1 -1
  99. package/dist/src/cohort-topic/wire/index.d.ts.map +1 -1
  100. package/dist/src/cohort-topic/wire/index.js +1 -1
  101. package/dist/src/cohort-topic/wire/index.js.map +1 -1
  102. package/dist/src/cohort-topic/wire/payloads.d.ts +5 -4
  103. package/dist/src/cohort-topic/wire/payloads.d.ts.map +1 -1
  104. package/dist/src/cohort-topic/wire/payloads.js +14 -5
  105. package/dist/src/cohort-topic/wire/payloads.js.map +1 -1
  106. package/dist/src/cohort-topic/wire/primitives.d.ts +65 -0
  107. package/dist/src/cohort-topic/wire/primitives.d.ts.map +1 -0
  108. package/dist/src/cohort-topic/wire/primitives.js +173 -0
  109. package/dist/src/cohort-topic/wire/primitives.js.map +1 -0
  110. package/dist/src/cohort-topic/wire/types.d.ts +132 -5
  111. package/dist/src/cohort-topic/wire/types.d.ts.map +1 -1
  112. package/dist/src/cohort-topic/wire/validate.d.ts +15 -5
  113. package/dist/src/cohort-topic/wire/validate.d.ts.map +1 -1
  114. package/dist/src/cohort-topic/wire/validate.js +146 -123
  115. package/dist/src/cohort-topic/wire/validate.js.map +1 -1
  116. package/dist/src/collection/collection.d.ts +23 -12
  117. package/dist/src/collection/collection.d.ts.map +1 -1
  118. package/dist/src/collection/collection.js +111 -35
  119. package/dist/src/collection/collection.js.map +1 -1
  120. package/dist/src/collection/struct.d.ts +37 -2
  121. package/dist/src/collection/struct.d.ts.map +1 -1
  122. package/dist/src/collection/struct.js +16 -1
  123. package/dist/src/collection/struct.js.map +1 -1
  124. package/dist/src/collections/tree/tree.d.ts +18 -1
  125. package/dist/src/collections/tree/tree.d.ts.map +1 -1
  126. package/dist/src/collections/tree/tree.js +36 -6
  127. package/dist/src/collections/tree/tree.js.map +1 -1
  128. package/dist/src/index.d.ts +1 -0
  129. package/dist/src/index.d.ts.map +1 -1
  130. package/dist/src/index.js +1 -0
  131. package/dist/src/index.js.map +1 -1
  132. package/dist/src/log/log.d.ts +26 -3
  133. package/dist/src/log/log.d.ts.map +1 -1
  134. package/dist/src/log/log.js +34 -7
  135. package/dist/src/log/log.js.map +1 -1
  136. package/dist/src/log/struct.d.ts +5 -4
  137. package/dist/src/log/struct.d.ts.map +1 -1
  138. package/dist/src/log/struct.js.map +1 -1
  139. package/dist/src/matchmaking/wire.d.ts +2 -1
  140. package/dist/src/matchmaking/wire.d.ts.map +1 -1
  141. package/dist/src/matchmaking/wire.js +13 -92
  142. package/dist/src/matchmaking/wire.js.map +1 -1
  143. package/dist/src/network/i-key-network.d.ts +9 -0
  144. package/dist/src/network/i-key-network.d.ts.map +1 -1
  145. package/dist/src/network/i-repo.d.ts +8 -0
  146. package/dist/src/network/i-repo.d.ts.map +1 -1
  147. package/dist/src/network/struct.d.ts +10 -0
  148. package/dist/src/network/struct.d.ts.map +1 -1
  149. package/dist/src/reactivity/push-state.d.ts.map +1 -1
  150. package/dist/src/reactivity/push-state.js +4 -33
  151. package/dist/src/reactivity/push-state.js.map +1 -1
  152. package/dist/src/reactivity/wire-validate.d.ts +7 -22
  153. package/dist/src/reactivity/wire-validate.d.ts.map +1 -1
  154. package/dist/src/reactivity/wire-validate.js +7 -73
  155. package/dist/src/reactivity/wire-validate.js.map +1 -1
  156. package/dist/src/reactivity/wire.js +3 -3
  157. package/dist/src/reactivity/wire.js.map +1 -1
  158. package/dist/src/testing/async-wait.d.ts +23 -0
  159. package/dist/src/testing/async-wait.d.ts.map +1 -0
  160. package/dist/src/testing/async-wait.js +42 -0
  161. package/dist/src/testing/async-wait.js.map +1 -0
  162. package/dist/src/testing/index.d.ts +3 -0
  163. package/dist/src/testing/index.d.ts.map +1 -0
  164. package/dist/src/testing/index.js +3 -0
  165. package/dist/src/testing/index.js.map +1 -0
  166. package/dist/src/testing/test-transactor.d.ts +44 -0
  167. package/dist/src/testing/test-transactor.d.ts.map +1 -0
  168. package/dist/src/testing/test-transactor.js +423 -0
  169. package/dist/src/testing/test-transactor.js.map +1 -0
  170. package/dist/src/transaction/actions-engine.d.ts +6 -3
  171. package/dist/src/transaction/actions-engine.d.ts.map +1 -1
  172. package/dist/src/transaction/actions-engine.js +8 -7
  173. package/dist/src/transaction/actions-engine.js.map +1 -1
  174. package/dist/src/transaction/coordinator.d.ts +43 -22
  175. package/dist/src/transaction/coordinator.d.ts.map +1 -1
  176. package/dist/src/transaction/coordinator.js +443 -178
  177. package/dist/src/transaction/coordinator.js.map +1 -1
  178. package/dist/src/transaction/errors.d.ts +82 -0
  179. package/dist/src/transaction/errors.d.ts.map +1 -0
  180. package/dist/src/transaction/errors.js +93 -0
  181. package/dist/src/transaction/errors.js.map +1 -0
  182. package/dist/src/transaction/index.d.ts +6 -3
  183. package/dist/src/transaction/index.d.ts.map +1 -1
  184. package/dist/src/transaction/index.js +4 -2
  185. package/dist/src/transaction/index.js.map +1 -1
  186. package/dist/src/transaction/operations-hash.d.ts +119 -0
  187. package/dist/src/transaction/operations-hash.d.ts.map +1 -0
  188. package/dist/src/transaction/operations-hash.js +180 -0
  189. package/dist/src/transaction/operations-hash.js.map +1 -0
  190. package/dist/src/transaction/read-dependency-collector.d.ts +43 -0
  191. package/dist/src/transaction/read-dependency-collector.d.ts.map +1 -0
  192. package/dist/src/transaction/read-dependency-collector.js +69 -0
  193. package/dist/src/transaction/read-dependency-collector.js.map +1 -0
  194. package/dist/src/transaction/session.d.ts +12 -3
  195. package/dist/src/transaction/session.d.ts.map +1 -1
  196. package/dist/src/transaction/session.js +35 -9
  197. package/dist/src/transaction/session.js.map +1 -1
  198. package/dist/src/transaction/transaction.d.ts +162 -1
  199. package/dist/src/transaction/transaction.d.ts.map +1 -1
  200. package/dist/src/transaction/transaction.js +85 -3
  201. package/dist/src/transaction/transaction.js.map +1 -1
  202. package/dist/src/transaction/validator.d.ts +3 -11
  203. package/dist/src/transaction/validator.d.ts.map +1 -1
  204. package/dist/src/transaction/validator.js +69 -28
  205. package/dist/src/transaction/validator.js.map +1 -1
  206. package/dist/src/transactor/network-transactor.d.ts +35 -0
  207. package/dist/src/transactor/network-transactor.d.ts.map +1 -1
  208. package/dist/src/transactor/network-transactor.js +146 -40
  209. package/dist/src/transactor/network-transactor.js.map +1 -1
  210. package/dist/src/transactor/transactor-source.d.ts +19 -5
  211. package/dist/src/transactor/transactor-source.d.ts.map +1 -1
  212. package/dist/src/transactor/transactor-source.js +43 -11
  213. package/dist/src/transactor/transactor-source.js.map +1 -1
  214. package/dist/src/transform/atomic-proxy.d.ts +35 -5
  215. package/dist/src/transform/atomic-proxy.d.ts.map +1 -1
  216. package/dist/src/transform/atomic-proxy.js +39 -7
  217. package/dist/src/transform/atomic-proxy.js.map +1 -1
  218. package/dist/src/transform/cache-source.d.ts +36 -5
  219. package/dist/src/transform/cache-source.d.ts.map +1 -1
  220. package/dist/src/transform/cache-source.js +84 -8
  221. package/dist/src/transform/cache-source.js.map +1 -1
  222. package/dist/src/transform/helpers.d.ts.map +1 -1
  223. package/dist/src/transform/helpers.js +8 -2
  224. package/dist/src/transform/helpers.js.map +1 -1
  225. package/dist/src/transform/tracker.d.ts +17 -2
  226. package/dist/src/transform/tracker.d.ts.map +1 -1
  227. package/dist/src/transform/tracker.js +66 -11
  228. package/dist/src/transform/tracker.js.map +1 -1
  229. package/dist/src/utility/backoff.d.ts +48 -0
  230. package/dist/src/utility/backoff.d.ts.map +1 -0
  231. package/dist/src/utility/backoff.js +60 -0
  232. package/dist/src/utility/backoff.js.map +1 -0
  233. package/dist/src/utility/pending.d.ts +1 -0
  234. package/dist/src/utility/pending.d.ts.map +1 -1
  235. package/dist/src/utility/pending.js +3 -1
  236. package/dist/src/utility/pending.js.map +1 -1
  237. package/package.json +4 -4
  238. package/src/blocks/block-store.ts +19 -1
  239. package/src/blocks/helpers.ts +3 -3
  240. package/src/btree/btree.ts +108 -63
  241. package/src/chain/chain.ts +11 -1
  242. package/src/cluster/index.ts +1 -0
  243. package/src/cluster/membership.ts +85 -0
  244. package/src/cluster/structs.ts +51 -1
  245. package/src/cohort-topic/addressing.ts +12 -4
  246. package/src/cohort-topic/antidos/bootstrap-evidence.ts +21 -9
  247. package/src/cohort-topic/antidos/replay-guard.ts +37 -0
  248. package/src/cohort-topic/antidos/topic-budget.ts +17 -2
  249. package/src/cohort-topic/coldstart.ts +48 -15
  250. package/src/cohort-topic/gossip/bus.ts +39 -2
  251. package/src/cohort-topic/gossip/view.ts +26 -1
  252. package/src/cohort-topic/member-engine.ts +36 -15
  253. package/src/cohort-topic/membership/publisher.ts +25 -33
  254. package/src/cohort-topic/membership/verifier.ts +119 -3
  255. package/src/cohort-topic/promotion.ts +23 -2
  256. package/src/cohort-topic/registration/renewal.ts +73 -1
  257. package/src/cohort-topic/registration/types.ts +15 -0
  258. package/src/cohort-topic/service.ts +41 -15
  259. package/src/cohort-topic/sig/payloads.ts +29 -9
  260. package/src/cohort-topic/traffic.ts +23 -1
  261. package/src/cohort-topic/walk.ts +95 -24
  262. package/src/cohort-topic/wire/codec.ts +12 -0
  263. package/src/cohort-topic/wire/index.ts +2 -0
  264. package/src/cohort-topic/wire/payloads.ts +14 -5
  265. package/src/cohort-topic/wire/primitives.ts +188 -0
  266. package/src/cohort-topic/wire/types.ts +136 -4
  267. package/src/cohort-topic/wire/validate.ts +168 -134
  268. package/src/collection/collection.ts +123 -40
  269. package/src/collection/struct.ts +44 -2
  270. package/src/collections/tree/tree.ts +42 -5
  271. package/src/index.ts +1 -0
  272. package/src/log/log.ts +37 -9
  273. package/src/log/struct.ts +5 -4
  274. package/src/matchmaking/wire.ts +25 -102
  275. package/src/network/i-key-network.ts +10 -0
  276. package/src/network/i-repo.ts +8 -0
  277. package/src/network/struct.ts +10 -0
  278. package/src/reactivity/push-state.ts +4 -37
  279. package/src/reactivity/wire-validate.ts +7 -81
  280. package/src/reactivity/wire.ts +3 -3
  281. package/src/testing/async-wait.ts +65 -0
  282. package/src/testing/index.ts +2 -0
  283. package/src/testing/test-transactor.ts +468 -0
  284. package/src/transaction/actions-engine.ts +8 -6
  285. package/src/transaction/coordinator.ts +498 -229
  286. package/src/transaction/errors.ts +91 -0
  287. package/src/transaction/index.ts +23 -3
  288. package/src/transaction/operations-hash.ts +196 -0
  289. package/src/transaction/read-dependency-collector.ts +78 -0
  290. package/src/transaction/session.ts +37 -9
  291. package/src/transaction/transaction.ts +211 -4
  292. package/src/transaction/validator.ts +73 -48
  293. package/src/transactor/network-transactor.ts +164 -49
  294. package/src/transactor/transactor-source.ts +47 -12
  295. package/src/transform/atomic-proxy.ts +92 -49
  296. package/src/transform/cache-source.ts +87 -9
  297. package/src/transform/helpers.ts +8 -2
  298. package/src/transform/tracker.ts +69 -11
  299. package/src/utility/backoff.ts +95 -0
  300. package/src/utility/pending.ts +3 -1
  301. package/src/transaction/context.ts +0 -103
@@ -0,0 +1,180 @@
1
+ import { hashString } from '../utility/hash-string.js';
2
+ /**
3
+ * Rank of each operation type, used ONLY as the final tiebreaker when the same
4
+ * (collectionId, blockId) legitimately carries more than one operation — a block
5
+ * staged, then mutated, then deleted within one transform (Transforms apply order
6
+ * is insert → update → delete; see transform/struct.ts). This is the semantic
7
+ * apply order. The exact ranking is arbitrary for correctness (both sides use it),
8
+ * but it MUST be defined in exactly one place — here.
9
+ */
10
+ const TYPE_RANK = {
11
+ insert: 0,
12
+ update: 1,
13
+ delete: 2,
14
+ };
15
+ /**
16
+ * Collect every block operation across all collections into a flat list.
17
+ *
18
+ * The returned order reflects Map/object insertion order and is therefore NOT
19
+ * canonical — {@link hashOperations} sorts before hashing, so callers do not need
20
+ * to pre-sort. Shared by the coordinator (both commit() and execute()) and the
21
+ * validator so all three collect sites produce the identical logical set.
22
+ */
23
+ export function collectOperations(transforms) {
24
+ const operations = [];
25
+ for (const [collectionId, t] of transforms) {
26
+ for (const [blockId, block] of Object.entries(t.inserts ?? {})) {
27
+ operations.push({ type: 'insert', collectionId, blockId, block });
28
+ }
29
+ for (const [blockId, ops] of Object.entries(t.updates ?? {})) {
30
+ operations.push({ type: 'update', collectionId, blockId, operations: ops });
31
+ }
32
+ for (const blockId of t.deletes ?? []) {
33
+ operations.push({ type: 'delete', collectionId, blockId });
34
+ }
35
+ }
36
+ return operations;
37
+ }
38
+ /**
39
+ * Total order over operations by the tuple (collectionId, blockId, type), using
40
+ * plain string comparison on the first two components and {@link TYPE_RANK} on the
41
+ * third. This is the cross-node ordering contract: two honest nodes that see the
42
+ * same logical set MUST produce the same sorted sequence regardless of the order
43
+ * they happened to collect operations in.
44
+ */
45
+ function compareOperations(a, b) {
46
+ if (a.collectionId !== b.collectionId)
47
+ return a.collectionId < b.collectionId ? -1 : 1;
48
+ if (a.blockId !== b.blockId)
49
+ return a.blockId < b.blockId ? -1 : 1;
50
+ return TYPE_RANK[a.type] - TYPE_RANK[b.type];
51
+ }
52
+ /**
53
+ * Canonical JSON encoder: recursively sorts object keys but PRESERVES array element
54
+ * order, and matches JSON.stringify leaf semantics.
55
+ *
56
+ * - Object keys are emitted in ascending (sorted) order, so two objects with the
57
+ * same content but different key-insertion order encode identically.
58
+ * - Array element order is preserved because BlockOperations is an ordered list of
59
+ * [entity, index, deleteCount, inserted] tuples whose order is semantically
60
+ * meaningful (as are any data arrays nested inside an IBlock).
61
+ * - Leaf semantics mirror JSON.stringify: `undefined`/function/symbol object-values
62
+ * are dropped, the same in arrays encode as `null`, `null` encodes as `null`,
63
+ * non-finite numbers as `null`, and other primitives via JSON.stringify.
64
+ *
65
+ * Exported so the order-independence test can exercise it directly.
66
+ *
67
+ * NOTE: no toJSON/Date special-casing — a value carrying toJSON (e.g. a Date)
68
+ * encodes as its plain enumerable keys ({} for a Date), not JSON.stringify's
69
+ * toJSON string. Harmless today (blocks hold plain JSON) and still deterministic
70
+ * across nodes (both sides run this same encoder); if IBlock content ever grows
71
+ * toJSON-bearing values and matching JSON.stringify exactly matters, add the hook.
72
+ */
73
+ export function canonicalStringify(value) {
74
+ if (value === null)
75
+ return 'null';
76
+ const type = typeof value;
77
+ if (type === 'number')
78
+ return Number.isFinite(value) ? JSON.stringify(value) : 'null';
79
+ if (type === 'string' || type === 'boolean')
80
+ return JSON.stringify(value);
81
+ if (type === 'bigint')
82
+ throw new TypeError('Do not know how to serialize a BigInt');
83
+ if (type === 'undefined' || type === 'function' || type === 'symbol')
84
+ return 'null';
85
+ if (Array.isArray(value)) {
86
+ const items = value.map(element => {
87
+ const et = typeof element;
88
+ // In arrays, undefined/function/symbol serialize as null (JSON.stringify semantics).
89
+ if (element === undefined || et === 'function' || et === 'symbol')
90
+ return 'null';
91
+ return canonicalStringify(element);
92
+ });
93
+ return `[${items.join(',')}]`;
94
+ }
95
+ // Plain object: sort keys ascending, drop undefined/function/symbol values.
96
+ const obj = value;
97
+ const parts = [];
98
+ for (const key of Object.keys(obj).sort()) {
99
+ const v = obj[key];
100
+ const vt = typeof v;
101
+ if (v === undefined || vt === 'function' || vt === 'symbol')
102
+ continue;
103
+ parts.push(`${JSON.stringify(key)}:${canonicalStringify(v)}`);
104
+ }
105
+ return `{${parts.join(',')}}`;
106
+ }
107
+ /**
108
+ * Current operations-hash FORMAT VERSION. Versions the *serialization* of operations
109
+ * into bytes (the sort key, {@link canonicalStringify} rules, and the SHA-256/base64url
110
+ * step) — distinct from `engineId` in the TransactionStamp, which versions the operation
111
+ * *content* an engine produces from the same statements. Two honest nodes must agree on
112
+ * BOTH dimensions to produce the same ops-hash.
113
+ *
114
+ * Bump this whenever a change to the canonical serialization alters the emitted bytes,
115
+ * so a peer running the old format is *detected* (a legible version-skew error) rather
116
+ * than mistaken for a content disagreement or a Byzantine lie. See docs/transactions.md
117
+ * ("Operations Hash — Canonical Serialization").
118
+ */
119
+ export const OPS_HASH_VERSION = 'v1';
120
+ /**
121
+ * Wire-token prefix carrying {@link OPS_HASH_VERSION}: `ops.v1:`. The `.` delimiter is
122
+ * outside the base64url alphabet (A–Z a–z 0–9 `-` `_`) that follows the trailing `:`, so
123
+ * the version segment can always be sliced back out unambiguously — see {@link opsHashVersion}.
124
+ */
125
+ export const OPS_HASH_PREFIX = `ops.${OPS_HASH_VERSION}:`;
126
+ /**
127
+ * Extract the format-version segment from an ops-hash token — the `v1` in `ops.v1:<hash>` —
128
+ * or `null` if the string is not a recognizable versioned ops-hash token.
129
+ *
130
+ * Total: never throws. A bare legacy `ops:<hash>` token (no `.` delimiter), an empty
131
+ * string, or any garbage all return `null`. A validator treats a `null` (or a version it
132
+ * does not recognize) as an unsupported/foreign format — a legible version-skew error —
133
+ * never as an accidental content match.
134
+ */
135
+ export function opsHashVersion(token) {
136
+ if (typeof token !== 'string')
137
+ return null;
138
+ if (!token.startsWith('ops.'))
139
+ return null;
140
+ const colon = token.indexOf(':', 4);
141
+ if (colon <= 4)
142
+ return null; // no version characters between "ops." and ":"
143
+ return token.slice(4, colon);
144
+ }
145
+ /**
146
+ * The EXACT canonical byte-string {@link hashOperations} feeds into SHA-256: the operations
147
+ * sorted by {@link compareOperations} and run through {@link canonicalStringify}. The version
148
+ * token is NOT part of this preimage — it wraps the resulting hash, it is not hashed.
149
+ *
150
+ * Exposed so a future client signature (design-client-transaction-signatures) can bind the
151
+ * IDENTICAL bytes the validators hash, rather than re-deriving the serialization and risking
152
+ * drift. Pair it with {@link OPS_HASH_VERSION} to record which format the bytes belong to.
153
+ */
154
+ export function canonicalOperationsPayload(operations) {
155
+ return canonicalStringify([...operations].sort(compareOperations));
156
+ }
157
+ /**
158
+ * Compute the transaction operations hash: sort into canonical order, canonically
159
+ * stringify, SHA-256 (base64url) via {@link hashString}, then prefix the versioned
160
+ * {@link OPS_HASH_PREFIX} token (`ops.v1:`) so the wire string is self-describing.
161
+ *
162
+ * This is the fingerprint the coordinator sends in PendRequest.operationsHash and
163
+ * the validator recomputes; equality of this string is the cross-node agreement
164
+ * that a transaction's operations match.
165
+ *
166
+ * NOTE: the ops-hash carries a format-version token, so a mixed-version cluster now
167
+ * *detects* skew — a validator seeing a foreign/legacy version emits a distinct
168
+ * "unsupported operations-hash format version" error instead of the ambiguous
169
+ * "Operations hash mismatch" (see TransactionValidator). What it does NOT do is
170
+ * *cross-compute* older formats: a node only recognizes that a peer speaks a different
171
+ * version, it cannot reproduce that peer's historical bytes. Mixed-version clusters
172
+ * therefore fail LEGIBLY, not interoperably; multi-version compatibility is future
173
+ * work if rolling upgrades ship. The ops-hash is recomputed fresh on both sides and
174
+ * never persisted, so bumping the version cannot retroactively invalidate committed
175
+ * transactions (unlike transaction.id, which IS persisted — leave it untouched).
176
+ */
177
+ export async function hashOperations(operations) {
178
+ return `${OPS_HASH_PREFIX}${await hashString(canonicalOperationsPayload(operations))}`;
179
+ }
180
+ //# sourceMappingURL=operations-hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations-hash.js","sourceRoot":"","sources":["../../../src/transaction/operations-hash.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { BlockId, ReadPurpose } from "../blocks/index.js";
2
+ import type { ReadDependency } from "./transaction.js";
3
+ /** Accumulates the read dependencies of one transaction. Keyed by block id. For each id it keeps:
4
+ *
5
+ * - the HIGHEST revision observed (never downgrades — a re-read from cache must not overwrite a
6
+ * higher revision seen earlier), and
7
+ * - the read's PURPOSE with value-wins semantics: once a block is recorded as a `value` read from
8
+ * ANY path it stays `value`; `navigation` sticks only for a block that was never read as a value.
9
+ * This is the exact analogue of the max-wins rule on revision, and it makes the classification
10
+ * order-independent (so it is deterministic regardless of cache/timing — required for the
11
+ * transaction id and client signature to match across a re-executing validator; Theorem 4).
12
+ *
13
+ * {@link getReadDependencies} returns only the CONFLICT set (value reads); purely-structural
14
+ * `navigation` reads — interior B-tree branches walked through to reach a captured leaf — are
15
+ * dropped. See {@link markValue} and docs/correctness.md Theorem 5.
16
+ *
17
+ * One instance is shared by a collection's {@link TransactorSource} (direct structural reads —
18
+ * bootstrap, header) and its {@link CacheSource} (every cache hit/miss), so a block read from
19
+ * either layer produces a dependency. Because both feed the same collector, a cache miss records
20
+ * the id once from each layer at the same revision/purpose; the merge collapses those to one
21
+ * entry. Cleared at each txn boundary. */
22
+ export declare class ReadDependencyCollector {
23
+ private reads;
24
+ /** Record a read of `blockId` at `revision`. `purpose` defaults to `value` (retained); pass
25
+ * `navigation` for an interior structural read that a later {@link markValue} may or may not
26
+ * upgrade. Revision is max-wins; purpose is value-wins (see class doc). */
27
+ record(blockId: BlockId, revision: number, purpose?: ReadPurpose): void;
28
+ /** Upgrade an already-recorded read to `value` (keeping its revision), retaining it in the
29
+ * conflict set. The B-tree point-lookup path uses this to mark the terminal leaf — the
30
+ * load-bearing read whose content the result depends on — after its interior descent nodes
31
+ * were recorded as `navigation`. No-op if the id was never recorded (e.g. a leaf served from
32
+ * an uncommitted staged insert, which records no dependency at all). */
33
+ markValue(blockId: BlockId): void;
34
+ /** The optimistic-concurrency conflict (read) set: every `value` read, with `navigation`
35
+ * reads excluded. Dropping a covered navigation read cannot admit a lost update — any
36
+ * concurrent change to the queried result also bumps a retained value read (the target
37
+ * leaf) — but it removes the false-positive stale rejections that structural block reads
38
+ * otherwise caused (Theorem 5 Bound). Deterministic in query shape, so a coordinator and a
39
+ * re-executing validator derive the identical set. */
40
+ getReadDependencies(): ReadDependency[];
41
+ clear(): void;
42
+ }
43
+ //# sourceMappingURL=read-dependency-collector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-dependency-collector.d.ts","sourceRoot":"","sources":["../../../src/transaction/read-dependency-collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKvD;;;;;;;;;;;;;;;;;;2CAkB2C;AAC3C,qBAAa,uBAAuB;IACnC,OAAO,CAAC,KAAK,CAAiC;IAE9C;;gFAE4E;IAC5E,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAqB,GAAG,IAAI;IAehF;;;;6EAIyE;IACzE,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOjC;;;;;2DAKuD;IACvD,mBAAmB,IAAI,cAAc,EAAE;IAUvC,KAAK,IAAI,IAAI;CAGb"}
@@ -0,0 +1,69 @@
1
+ /** Accumulates the read dependencies of one transaction. Keyed by block id. For each id it keeps:
2
+ *
3
+ * - the HIGHEST revision observed (never downgrades — a re-read from cache must not overwrite a
4
+ * higher revision seen earlier), and
5
+ * - the read's PURPOSE with value-wins semantics: once a block is recorded as a `value` read from
6
+ * ANY path it stays `value`; `navigation` sticks only for a block that was never read as a value.
7
+ * This is the exact analogue of the max-wins rule on revision, and it makes the classification
8
+ * order-independent (so it is deterministic regardless of cache/timing — required for the
9
+ * transaction id and client signature to match across a re-executing validator; Theorem 4).
10
+ *
11
+ * {@link getReadDependencies} returns only the CONFLICT set (value reads); purely-structural
12
+ * `navigation` reads — interior B-tree branches walked through to reach a captured leaf — are
13
+ * dropped. See {@link markValue} and docs/correctness.md Theorem 5.
14
+ *
15
+ * One instance is shared by a collection's {@link TransactorSource} (direct structural reads —
16
+ * bootstrap, header) and its {@link CacheSource} (every cache hit/miss), so a block read from
17
+ * either layer produces a dependency. Because both feed the same collector, a cache miss records
18
+ * the id once from each layer at the same revision/purpose; the merge collapses those to one
19
+ * entry. Cleared at each txn boundary. */
20
+ export class ReadDependencyCollector {
21
+ reads = new Map();
22
+ /** Record a read of `blockId` at `revision`. `purpose` defaults to `value` (retained); pass
23
+ * `navigation` for an interior structural read that a later {@link markValue} may or may not
24
+ * upgrade. Revision is max-wins; purpose is value-wins (see class doc). */
25
+ record(blockId, revision, purpose = 'value') {
26
+ const prev = this.reads.get(blockId);
27
+ if (prev === undefined) {
28
+ this.reads.set(blockId, { revision, purpose });
29
+ return;
30
+ }
31
+ if (revision > prev.revision) {
32
+ prev.revision = revision;
33
+ }
34
+ // value-wins: a value read anywhere pins the block as value; navigation never downgrades it.
35
+ if (purpose === 'value') {
36
+ prev.purpose = 'value';
37
+ }
38
+ }
39
+ /** Upgrade an already-recorded read to `value` (keeping its revision), retaining it in the
40
+ * conflict set. The B-tree point-lookup path uses this to mark the terminal leaf — the
41
+ * load-bearing read whose content the result depends on — after its interior descent nodes
42
+ * were recorded as `navigation`. No-op if the id was never recorded (e.g. a leaf served from
43
+ * an uncommitted staged insert, which records no dependency at all). */
44
+ markValue(blockId) {
45
+ const prev = this.reads.get(blockId);
46
+ if (prev) {
47
+ prev.purpose = 'value';
48
+ }
49
+ }
50
+ /** The optimistic-concurrency conflict (read) set: every `value` read, with `navigation`
51
+ * reads excluded. Dropping a covered navigation read cannot admit a lost update — any
52
+ * concurrent change to the queried result also bumps a retained value read (the target
53
+ * leaf) — but it removes the false-positive stale rejections that structural block reads
54
+ * otherwise caused (Theorem 5 Bound). Deterministic in query shape, so a coordinator and a
55
+ * re-executing validator derive the identical set. */
56
+ getReadDependencies() {
57
+ const result = [];
58
+ for (const [blockId, entry] of this.reads) {
59
+ if (entry.purpose === 'value') {
60
+ result.push({ blockId, revision: entry.revision });
61
+ }
62
+ }
63
+ return result;
64
+ }
65
+ clear() {
66
+ this.reads.clear();
67
+ }
68
+ }
69
+ //# sourceMappingURL=read-dependency-collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-dependency-collector.js","sourceRoot":"","sources":["../../../src/transaction/read-dependency-collector.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;2CAkB2C;AAC3C,MAAM,OAAO,uBAAuB;IAC3B,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAE9C;;gFAE4E;IAC5E,MAAM,CAAC,OAAgB,EAAE,QAAgB,EAAE,UAAuB,OAAO;QACxE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YAC/C,OAAO;QACR,CAAC;QACD,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC1B,CAAC;QACD,6FAA6F;QAC7F,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACxB,CAAC;IACF,CAAC;IAED;;;;6EAIyE;IACzE,SAAS,CAAC,OAAgB;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,IAAI,EAAE,CAAC;YACV,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACxB,CAAC;IACF,CAAC;IAED;;;;;2DAKuD;IACvD,mBAAmB;QAClB,MAAM,MAAM,GAAqB,EAAE,CAAC;QACpC,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3C,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;gBAC/B,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YACpD,CAAC;QACF,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;CACD"}
@@ -1,5 +1,6 @@
1
1
  import type { TransactionCoordinator } from "./coordinator.js";
2
- import type { ExecutionResult, ITransactionEngine, TransactionStamp, CollectionActions } from "./transaction.js";
2
+ import type { SyncOptions } from "../collection/index.js";
3
+ import type { ExecutionResult, ITransactionEngine, TransactionStamp, CollectionActions, TransactionSigner } from "./transaction.js";
3
4
  /**
4
5
  * TransactionSession manages incremental transaction building.
5
6
  *
@@ -22,6 +23,7 @@ import type { ExecutionResult, ITransactionEngine, TransactionStamp, CollectionA
22
23
  export declare class TransactionSession {
23
24
  private readonly coordinator;
24
25
  private readonly engine;
26
+ private readonly signer?;
25
27
  private readonly statements;
26
28
  private readonly stamp;
27
29
  private committed;
@@ -30,8 +32,12 @@ export declare class TransactionSession {
30
32
  /**
31
33
  * Create a new TransactionSession.
32
34
  * Uses async factory because stamp creation requires SHA-256 hashing.
35
+ *
36
+ * @param signer - Optional client signer. When supplied, commit() stamps the built
37
+ * transaction's `signature` over its canonical payload; when omitted the
38
+ * transaction is left unsigned (accepted only by nodes with no verifier wired).
33
39
  */
34
- static create(coordinator: TransactionCoordinator, engine: ITransactionEngine, peerId?: string, schemaHash?: string, ttlMs?: number): Promise<TransactionSession>;
40
+ static create(coordinator: TransactionCoordinator, engine: ITransactionEngine, peerId?: string, schemaHash?: string, ttlMs?: number, signer?: TransactionSigner): Promise<TransactionSession>;
35
41
  /**
36
42
  * Execute a statement.
37
43
  *
@@ -50,8 +56,11 @@ export declare class TransactionSession {
50
56
  * Commit the transaction.
51
57
  *
52
58
  * Compiles all statements into a complete Transaction and commits through coordinator.
59
+ *
60
+ * @param options - Optional retry knobs forwarded to {@link TransactionCoordinator.commit}
61
+ * (bounded backoff+jitter retry of a clean stale loss). Defaults are safe out of the box.
53
62
  */
54
- commit(): Promise<ExecutionResult>;
63
+ commit(options?: SyncOptions): Promise<ExecutionResult>;
55
64
  /**
56
65
  * Rollback the transaction (undo this session's applied actions).
57
66
  *
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/transaction/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAe,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG9H;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,kBAAkB;IAO7B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPxB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO;IAQP;;;OAGG;WACU,MAAM,CAClB,WAAW,EAAE,sBAAsB,EACnC,MAAM,EAAE,kBAAkB,EAC1B,MAAM,GAAE,MAAgB,EACxB,UAAU,GAAE,MAAW,EACvB,KAAK,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,CAAC;IAW9B;;;;;;;;;OASG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA2C9G;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,eAAe,CAAC;IAgCxC;;;;;;OAMG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAe/B;;OAEG;IACH,UAAU,IAAI,MAAM;IAIpB;;OAEG;IACH,QAAQ,IAAI,gBAAgB;IAI5B;;OAEG;IACH,aAAa,IAAI,SAAS,MAAM,EAAE;IAIlC;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,YAAY,IAAI,OAAO;CAGvB"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/transaction/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAe,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGjJ;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,kBAAkB;IAO7B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IATzB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO;IASP;;;;;;;OAOG;WACU,MAAM,CAClB,WAAW,EAAE,sBAAsB,EACnC,MAAM,EAAE,kBAAkB,EAC1B,MAAM,GAAE,MAAgB,EACxB,UAAU,GAAE,MAAW,EACvB,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,iBAAiB,GACxB,OAAO,CAAC,kBAAkB,CAAC;IAW9B;;;;;;;;;OASG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA2C9G;;;;;;;OAOG;IACG,MAAM,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC;IAkD7D;;;;;;OAMG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAe/B;;OAEG;IACH,UAAU,IAAI,MAAM;IAIpB;;OAEG;IACH,QAAQ,IAAI,gBAAgB;IAI5B;;OAEG;IACH,aAAa,IAAI,SAAS,MAAM,EAAE;IAIlC;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,YAAY,IAAI,OAAO;CAGvB"}
@@ -1,4 +1,4 @@
1
- import { createTransactionStamp, createTransactionId, isTransactionExpired } from "./transaction.js";
1
+ import { createTransactionStamp, createTransactionId, isTransactionExpired, clientSignaturePayload } from "./transaction.js";
2
2
  /**
3
3
  * TransactionSession manages incremental transaction building.
4
4
  *
@@ -21,23 +21,28 @@ import { createTransactionStamp, createTransactionId, isTransactionExpired } fro
21
21
  export class TransactionSession {
22
22
  coordinator;
23
23
  engine;
24
+ signer;
24
25
  statements = [];
25
26
  stamp;
26
27
  committed = false;
27
28
  rolledBack = false;
28
- constructor(coordinator, engine, stamp) {
29
+ constructor(coordinator, engine, stamp, signer) {
29
30
  this.coordinator = coordinator;
30
31
  this.engine = engine;
32
+ this.signer = signer;
31
33
  this.stamp = stamp;
32
34
  }
33
35
  /**
34
36
  * Create a new TransactionSession.
35
37
  * Uses async factory because stamp creation requires SHA-256 hashing.
38
+ *
39
+ * @param signer - Optional client signer. When supplied, commit() stamps the built
40
+ * transaction's `signature` over its canonical payload; when omitted the
41
+ * transaction is left unsigned (accepted only by nodes with no verifier wired).
36
42
  */
37
- static async create(coordinator, engine, peerId = 'local', schemaHash = '', ttlMs) {
38
- const stamp = await createTransactionStamp(peerId, Date.now(), schemaHash, 'unknown', // TODO: Get engine ID from engine
39
- ttlMs);
40
- return new TransactionSession(coordinator, engine, stamp);
43
+ static async create(coordinator, engine, peerId = 'local', schemaHash = '', ttlMs, signer) {
44
+ const stamp = await createTransactionStamp(peerId, Date.now(), schemaHash, engine.id, ttlMs);
45
+ return new TransactionSession(coordinator, engine, stamp, signer);
41
46
  }
42
47
  /**
43
48
  * Execute a statement.
@@ -93,8 +98,11 @@ export class TransactionSession {
93
98
  * Commit the transaction.
94
99
  *
95
100
  * Compiles all statements into a complete Transaction and commits through coordinator.
101
+ *
102
+ * @param options - Optional retry knobs forwarded to {@link TransactionCoordinator.commit}
103
+ * (bounded backoff+jitter retry of a clean stale loss). Defaults are safe out of the box.
96
104
  */
97
- async commit() {
105
+ async commit(options) {
98
106
  if (this.committed) {
99
107
  return { success: false, error: 'Transaction already committed' };
100
108
  }
@@ -113,8 +121,26 @@ export class TransactionSession {
113
121
  reads,
114
122
  id: await createTransactionId(this.stamp.id, this.statements, reads)
115
123
  };
116
- // Commit through coordinator (which will orchestrate PEND/COMMIT)
117
- await this.coordinator.commit(transaction);
124
+ // Sign the canonical client-signature payload if a signer was supplied. The
125
+ // payload covers stamp.id + statements + reads, which are all final now. A signer failure
126
+ // (e.g. a wrong-key-type libp2p sign) is caught and surfaced as a clean commit failure BEFORE
127
+ // coordinator.commit runs — the transaction object is local and discarded, so a failed sign can
128
+ // never leak a partially-built unsigned transaction into consensus.
129
+ if (this.signer) {
130
+ const payload = clientSignaturePayload(this.stamp.id, this.statements, reads);
131
+ try {
132
+ transaction.signature = await this.signer(payload);
133
+ }
134
+ catch (error) {
135
+ return {
136
+ success: false,
137
+ error: `Failed to sign transaction: ${error instanceof Error ? error.message : String(error)}`
138
+ };
139
+ }
140
+ }
141
+ // Commit through coordinator (which will orchestrate PEND/COMMIT, with bounded
142
+ // backoff+jitter retry of a clean stale loss)
143
+ await this.coordinator.commit(transaction, options);
118
144
  // Clear read dependencies after successful commit
119
145
  this.coordinator.clearReadDependencies();
120
146
  this.committed = true;
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/transaction/session.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAErG;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,kBAAkB;IAOZ;IACA;IAPD,UAAU,GAAa,EAAE,CAAC;IAC1B,KAAK,CAAmB;IACjC,SAAS,GAAG,KAAK,CAAC;IAClB,UAAU,GAAG,KAAK,CAAC;IAE3B,YACkB,WAAmC,EACnC,MAA0B,EAC3C,KAAuB;QAFN,gBAAW,GAAX,WAAW,CAAwB;QACnC,WAAM,GAAN,MAAM,CAAoB;QAG3C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAClB,WAAmC,EACnC,MAA0B,EAC1B,SAAiB,OAAO,EACxB,aAAqB,EAAE,EACvB,KAAc;QAEd,MAAM,KAAK,GAAG,MAAM,sBAAsB,CACzC,MAAM,EACN,IAAI,CAAC,GAAG,EAAE,EACV,UAAU,EACV,SAAS,EAAE,kCAAkC;QAC7C,KAAK,CACL,CAAC;QACF,OAAO,IAAI,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,OAAO,CAAC,SAAiB,EAAE,OAA6B;QAC7D,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC;QACnE,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC;QACrE,CAAC;QAED,IAAI,CAAC;YACJ,gEAAgE;YAChE,IAAI,cAAmC,CAAC;YACxC,IAAI,OAAO,EAAE,CAAC;gBACb,cAAc,GAAG,OAAO,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACP,0EAA0E;gBAC1E,MAAM,eAAe,GAAgB;oBACpC,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,UAAU,EAAE,CAAC,SAAS,CAAC;oBACvB,KAAK,EAAE,EAAE;oBACT,EAAE,EAAE,MAAM,CAAC,oCAAoC;iBAC/C,CAAC;gBACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;gBAC1D,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBACxC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,+BAA+B,EAAE,CAAC;gBACnF,CAAC;gBACD,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC;YACjC,CAAC;YAED,oCAAoC;YACpC,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAEnE,iDAAiD;YACjD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAEhC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO;gBACN,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,gCAAgC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;aAC/F,CAAC;QACH,CAAC;IACF,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM;QACX,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC;QACnE,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC;QACrE,CAAC;QACD,IAAI,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;QACrF,CAAC;QAED,+DAA+D;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,CAAC;QAErD,kCAAkC;QAClC,MAAM,WAAW,GAAgB;YAChC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK;YACL,EAAE,EAAE,MAAM,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC;SACpE,CAAC;QAEF,kEAAkE;QAClE,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAE3C,kDAAkD;QAClD,IAAI,CAAC,WAAW,CAAC,qBAAqB,EAAE,CAAC;QAEzC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,QAAQ;QACb,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACpD,CAAC;QAED,+BAA+B;QAC/B,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,WAAW,CAAC,qBAAqB,EAAE,CAAC;QACzC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,UAAU;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,QAAQ;QACP,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,aAAa;QACZ,OAAO,IAAI,CAAC,UAAU,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,WAAW;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,YAAY;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACxB,CAAC;CACD"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/transaction/session.ts"],"names":[],"mappings":"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"}