@optimystic/db-core 0.13.5 → 0.14.1

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 (447) hide show
  1. package/dist/src/cluster/structs.d.ts +13 -0
  2. package/dist/src/cluster/structs.d.ts.map +1 -1
  3. package/dist/src/cohort-topic/addressing.d.ts +53 -0
  4. package/dist/src/cohort-topic/addressing.d.ts.map +1 -0
  5. package/dist/src/cohort-topic/addressing.js +95 -0
  6. package/dist/src/cohort-topic/addressing.js.map +1 -0
  7. package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.d.ts +105 -0
  8. package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.d.ts.map +1 -0
  9. package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.js +197 -0
  10. package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.js.map +1 -0
  11. package/dist/src/cohort-topic/antidos/bootstrap-evidence.d.ts +50 -0
  12. package/dist/src/cohort-topic/antidos/bootstrap-evidence.d.ts.map +1 -0
  13. package/dist/src/cohort-topic/antidos/bootstrap-evidence.js +62 -0
  14. package/dist/src/cohort-topic/antidos/bootstrap-evidence.js.map +1 -0
  15. package/dist/src/cohort-topic/antidos/index.d.ts +6 -0
  16. package/dist/src/cohort-topic/antidos/index.d.ts.map +1 -0
  17. package/dist/src/cohort-topic/antidos/index.js +6 -0
  18. package/dist/src/cohort-topic/antidos/index.js.map +1 -0
  19. package/dist/src/cohort-topic/antidos/rate-limiter.d.ts +95 -0
  20. package/dist/src/cohort-topic/antidos/rate-limiter.d.ts.map +1 -0
  21. package/dist/src/cohort-topic/antidos/rate-limiter.js +146 -0
  22. package/dist/src/cohort-topic/antidos/rate-limiter.js.map +1 -0
  23. package/dist/src/cohort-topic/antidos/replay-guard.d.ts +37 -0
  24. package/dist/src/cohort-topic/antidos/replay-guard.d.ts.map +1 -0
  25. package/dist/src/cohort-topic/antidos/replay-guard.js +78 -0
  26. package/dist/src/cohort-topic/antidos/replay-guard.js.map +1 -0
  27. package/dist/src/cohort-topic/antidos/topic-budget.d.ts +50 -0
  28. package/dist/src/cohort-topic/antidos/topic-budget.d.ts.map +1 -0
  29. package/dist/src/cohort-topic/antidos/topic-budget.js +95 -0
  30. package/dist/src/cohort-topic/antidos/topic-budget.js.map +1 -0
  31. package/dist/src/cohort-topic/antiflood/index.d.ts +3 -0
  32. package/dist/src/cohort-topic/antiflood/index.d.ts.map +1 -0
  33. package/dist/src/cohort-topic/antiflood/index.js +3 -0
  34. package/dist/src/cohort-topic/antiflood/index.js.map +1 -0
  35. package/dist/src/cohort-topic/antiflood/invariants.d.ts +70 -0
  36. package/dist/src/cohort-topic/antiflood/invariants.d.ts.map +1 -0
  37. package/dist/src/cohort-topic/antiflood/invariants.js +86 -0
  38. package/dist/src/cohort-topic/antiflood/invariants.js.map +1 -0
  39. package/dist/src/cohort-topic/antiflood/jitter.d.ts +65 -0
  40. package/dist/src/cohort-topic/antiflood/jitter.d.ts.map +1 -0
  41. package/dist/src/cohort-topic/antiflood/jitter.js +75 -0
  42. package/dist/src/cohort-topic/antiflood/jitter.js.map +1 -0
  43. package/dist/src/cohort-topic/coldstart.d.ts +117 -0
  44. package/dist/src/cohort-topic/coldstart.d.ts.map +1 -0
  45. package/dist/src/cohort-topic/coldstart.js +127 -0
  46. package/dist/src/cohort-topic/coldstart.js.map +1 -0
  47. package/dist/src/cohort-topic/dmax.d.ts +44 -0
  48. package/dist/src/cohort-topic/dmax.d.ts.map +1 -0
  49. package/dist/src/cohort-topic/dmax.js +70 -0
  50. package/dist/src/cohort-topic/dmax.js.map +1 -0
  51. package/dist/src/cohort-topic/gossip/bus.d.ts +85 -0
  52. package/dist/src/cohort-topic/gossip/bus.d.ts.map +1 -0
  53. package/dist/src/cohort-topic/gossip/bus.js +146 -0
  54. package/dist/src/cohort-topic/gossip/bus.js.map +1 -0
  55. package/dist/src/cohort-topic/gossip/index.d.ts +4 -0
  56. package/dist/src/cohort-topic/gossip/index.d.ts.map +1 -0
  57. package/dist/src/cohort-topic/gossip/index.js +4 -0
  58. package/dist/src/cohort-topic/gossip/index.js.map +1 -0
  59. package/dist/src/cohort-topic/gossip/records.d.ts +12 -0
  60. package/dist/src/cohort-topic/gossip/records.d.ts.map +1 -0
  61. package/dist/src/cohort-topic/gossip/records.js +41 -0
  62. package/dist/src/cohort-topic/gossip/records.js.map +1 -0
  63. package/dist/src/cohort-topic/gossip/view.d.ts +39 -0
  64. package/dist/src/cohort-topic/gossip/view.d.ts.map +1 -0
  65. package/dist/src/cohort-topic/gossip/view.js +30 -0
  66. package/dist/src/cohort-topic/gossip/view.js.map +1 -0
  67. package/dist/src/cohort-topic/index.d.ts +21 -0
  68. package/dist/src/cohort-topic/index.d.ts.map +1 -0
  69. package/dist/src/cohort-topic/index.js +21 -0
  70. package/dist/src/cohort-topic/index.js.map +1 -0
  71. package/dist/src/cohort-topic/load/barometer.d.ts +78 -0
  72. package/dist/src/cohort-topic/load/barometer.d.ts.map +1 -0
  73. package/dist/src/cohort-topic/load/barometer.js +93 -0
  74. package/dist/src/cohort-topic/load/barometer.js.map +1 -0
  75. package/dist/src/cohort-topic/load/index.d.ts +2 -0
  76. package/dist/src/cohort-topic/load/index.d.ts.map +1 -0
  77. package/dist/src/cohort-topic/load/index.js +2 -0
  78. package/dist/src/cohort-topic/load/index.js.map +1 -0
  79. package/dist/src/cohort-topic/member-engine.d.ts +134 -0
  80. package/dist/src/cohort-topic/member-engine.d.ts.map +1 -0
  81. package/dist/src/cohort-topic/member-engine.js +264 -0
  82. package/dist/src/cohort-topic/member-engine.js.map +1 -0
  83. package/dist/src/cohort-topic/membership/index.d.ts +4 -0
  84. package/dist/src/cohort-topic/membership/index.d.ts.map +1 -0
  85. package/dist/src/cohort-topic/membership/index.js +4 -0
  86. package/dist/src/cohort-topic/membership/index.js.map +1 -0
  87. package/dist/src/cohort-topic/membership/publisher.d.ts +82 -0
  88. package/dist/src/cohort-topic/membership/publisher.d.ts.map +1 -0
  89. package/dist/src/cohort-topic/membership/publisher.js +107 -0
  90. package/dist/src/cohort-topic/membership/publisher.js.map +1 -0
  91. package/dist/src/cohort-topic/membership/source.d.ts +31 -0
  92. package/dist/src/cohort-topic/membership/source.d.ts.map +1 -0
  93. package/dist/src/cohort-topic/membership/source.js +32 -0
  94. package/dist/src/cohort-topic/membership/source.js.map +1 -0
  95. package/dist/src/cohort-topic/membership/verifier.d.ts +96 -0
  96. package/dist/src/cohort-topic/membership/verifier.d.ts.map +1 -0
  97. package/dist/src/cohort-topic/membership/verifier.js +250 -0
  98. package/dist/src/cohort-topic/membership/verifier.js.map +1 -0
  99. package/dist/src/cohort-topic/ports.d.ts +149 -0
  100. package/dist/src/cohort-topic/ports.d.ts.map +1 -0
  101. package/dist/src/cohort-topic/ports.js +25 -0
  102. package/dist/src/cohort-topic/ports.js.map +1 -0
  103. package/dist/src/cohort-topic/promotion.d.ts +135 -0
  104. package/dist/src/cohort-topic/promotion.d.ts.map +1 -0
  105. package/dist/src/cohort-topic/promotion.js +269 -0
  106. package/dist/src/cohort-topic/promotion.js.map +1 -0
  107. package/dist/src/cohort-topic/registration/bytes.d.ts +16 -0
  108. package/dist/src/cohort-topic/registration/bytes.d.ts.map +1 -0
  109. package/dist/src/cohort-topic/registration/bytes.js +32 -0
  110. package/dist/src/cohort-topic/registration/bytes.js.map +1 -0
  111. package/dist/src/cohort-topic/registration/handoff.d.ts +69 -0
  112. package/dist/src/cohort-topic/registration/handoff.d.ts.map +1 -0
  113. package/dist/src/cohort-topic/registration/handoff.js +98 -0
  114. package/dist/src/cohort-topic/registration/handoff.js.map +1 -0
  115. package/dist/src/cohort-topic/registration/index.d.ts +7 -0
  116. package/dist/src/cohort-topic/registration/index.d.ts.map +1 -0
  117. package/dist/src/cohort-topic/registration/index.js +7 -0
  118. package/dist/src/cohort-topic/registration/index.js.map +1 -0
  119. package/dist/src/cohort-topic/registration/renewal.d.ts +115 -0
  120. package/dist/src/cohort-topic/registration/renewal.d.ts.map +1 -0
  121. package/dist/src/cohort-topic/registration/renewal.js +306 -0
  122. package/dist/src/cohort-topic/registration/renewal.js.map +1 -0
  123. package/dist/src/cohort-topic/registration/sharding.d.ts +31 -0
  124. package/dist/src/cohort-topic/registration/sharding.d.ts.map +1 -0
  125. package/dist/src/cohort-topic/registration/sharding.js +48 -0
  126. package/dist/src/cohort-topic/registration/sharding.js.map +1 -0
  127. package/dist/src/cohort-topic/registration/store.d.ts +13 -0
  128. package/dist/src/cohort-topic/registration/store.d.ts.map +1 -0
  129. package/dist/src/cohort-topic/registration/store.js +72 -0
  130. package/dist/src/cohort-topic/registration/store.js.map +1 -0
  131. package/dist/src/cohort-topic/registration/types.d.ts +71 -0
  132. package/dist/src/cohort-topic/registration/types.d.ts.map +1 -0
  133. package/dist/src/cohort-topic/registration/types.js +27 -0
  134. package/dist/src/cohort-topic/registration/types.js.map +1 -0
  135. package/dist/src/cohort-topic/ring-hash.d.ts +27 -0
  136. package/dist/src/cohort-topic/ring-hash.d.ts.map +1 -0
  137. package/dist/src/cohort-topic/ring-hash.js +45 -0
  138. package/dist/src/cohort-topic/ring-hash.js.map +1 -0
  139. package/dist/src/cohort-topic/service.d.ts +157 -0
  140. package/dist/src/cohort-topic/service.d.ts.map +1 -0
  141. package/dist/src/cohort-topic/service.js +237 -0
  142. package/dist/src/cohort-topic/service.js.map +1 -0
  143. package/dist/src/cohort-topic/sig/index.d.ts +3 -0
  144. package/dist/src/cohort-topic/sig/index.d.ts.map +1 -0
  145. package/dist/src/cohort-topic/sig/index.js +3 -0
  146. package/dist/src/cohort-topic/sig/index.js.map +1 -0
  147. package/dist/src/cohort-topic/sig/payloads.d.ts +25 -0
  148. package/dist/src/cohort-topic/sig/payloads.d.ts.map +1 -0
  149. package/dist/src/cohort-topic/sig/payloads.js +25 -0
  150. package/dist/src/cohort-topic/sig/payloads.js.map +1 -0
  151. package/dist/src/cohort-topic/sig/threshold.d.ts +33 -0
  152. package/dist/src/cohort-topic/sig/threshold.d.ts.map +1 -0
  153. package/dist/src/cohort-topic/sig/threshold.js +51 -0
  154. package/dist/src/cohort-topic/sig/threshold.js.map +1 -0
  155. package/dist/src/cohort-topic/tiers.d.ts +58 -0
  156. package/dist/src/cohort-topic/tiers.d.ts.map +1 -0
  157. package/dist/src/cohort-topic/tiers.js +49 -0
  158. package/dist/src/cohort-topic/tiers.js.map +1 -0
  159. package/dist/src/cohort-topic/traffic.d.ts +90 -0
  160. package/dist/src/cohort-topic/traffic.d.ts.map +1 -0
  161. package/dist/src/cohort-topic/traffic.js +146 -0
  162. package/dist/src/cohort-topic/traffic.js.map +1 -0
  163. package/dist/src/cohort-topic/walk.d.ts +123 -0
  164. package/dist/src/cohort-topic/walk.d.ts.map +1 -0
  165. package/dist/src/cohort-topic/walk.js +150 -0
  166. package/dist/src/cohort-topic/walk.js.map +1 -0
  167. package/dist/src/cohort-topic/willingness.d.ts +123 -0
  168. package/dist/src/cohort-topic/willingness.d.ts.map +1 -0
  169. package/dist/src/cohort-topic/willingness.js +143 -0
  170. package/dist/src/cohort-topic/willingness.js.map +1 -0
  171. package/dist/src/cohort-topic/wire/codec.d.ts +42 -0
  172. package/dist/src/cohort-topic/wire/codec.d.ts.map +1 -0
  173. package/dist/src/cohort-topic/wire/codec.js +163 -0
  174. package/dist/src/cohort-topic/wire/codec.js.map +1 -0
  175. package/dist/src/cohort-topic/wire/index.d.ts +6 -0
  176. package/dist/src/cohort-topic/wire/index.d.ts.map +1 -0
  177. package/dist/src/cohort-topic/wire/index.js +6 -0
  178. package/dist/src/cohort-topic/wire/index.js.map +1 -0
  179. package/dist/src/cohort-topic/wire/payloads.d.ts +38 -0
  180. package/dist/src/cohort-topic/wire/payloads.d.ts.map +1 -0
  181. package/dist/src/cohort-topic/wire/payloads.js +102 -0
  182. package/dist/src/cohort-topic/wire/payloads.js.map +1 -0
  183. package/dist/src/cohort-topic/wire/types.d.ts +304 -0
  184. package/dist/src/cohort-topic/wire/types.d.ts.map +1 -0
  185. package/dist/src/cohort-topic/wire/types.js +16 -0
  186. package/dist/src/cohort-topic/wire/types.js.map +1 -0
  187. package/dist/src/cohort-topic/wire/validate.d.ts +25 -0
  188. package/dist/src/cohort-topic/wire/validate.d.ts.map +1 -0
  189. package/dist/src/cohort-topic/wire/validate.js +427 -0
  190. package/dist/src/cohort-topic/wire/validate.js.map +1 -0
  191. package/dist/src/collection/collection.d.ts +58 -1
  192. package/dist/src/collection/collection.d.ts.map +1 -1
  193. package/dist/src/collection/collection.js +76 -0
  194. package/dist/src/collection/collection.js.map +1 -1
  195. package/dist/src/collections/tree/tree.d.ts +58 -2
  196. package/dist/src/collections/tree/tree.d.ts.map +1 -1
  197. package/dist/src/collections/tree/tree.js +59 -2
  198. package/dist/src/collections/tree/tree.js.map +1 -1
  199. package/dist/src/index.d.ts +3 -0
  200. package/dist/src/index.d.ts.map +1 -1
  201. package/dist/src/index.js +3 -0
  202. package/dist/src/index.js.map +1 -1
  203. package/dist/src/log/log.d.ts +42 -4
  204. package/dist/src/log/log.d.ts.map +1 -1
  205. package/dist/src/log/log.js +71 -3
  206. package/dist/src/log/log.js.map +1 -1
  207. package/dist/src/log/struct.d.ts +122 -2
  208. package/dist/src/log/struct.d.ts.map +1 -1
  209. package/dist/src/log/struct.js.map +1 -1
  210. package/dist/src/matchmaking/capability-filter.d.ts +24 -0
  211. package/dist/src/matchmaking/capability-filter.d.ts.map +1 -0
  212. package/dist/src/matchmaking/capability-filter.js +37 -0
  213. package/dist/src/matchmaking/capability-filter.js.map +1 -0
  214. package/dist/src/matchmaking/config.d.ts +77 -0
  215. package/dist/src/matchmaking/config.d.ts.map +1 -0
  216. package/dist/src/matchmaking/config.js +69 -0
  217. package/dist/src/matchmaking/config.js.map +1 -0
  218. package/dist/src/matchmaking/index.d.ts +21 -0
  219. package/dist/src/matchmaking/index.d.ts.map +1 -0
  220. package/dist/src/matchmaking/index.js +21 -0
  221. package/dist/src/matchmaking/index.js.map +1 -0
  222. package/dist/src/matchmaking/multi-cohort-seeker.d.ts +133 -0
  223. package/dist/src/matchmaking/multi-cohort-seeker.d.ts.map +1 -0
  224. package/dist/src/matchmaking/multi-cohort-seeker.js +142 -0
  225. package/dist/src/matchmaking/multi-cohort-seeker.js.map +1 -0
  226. package/dist/src/matchmaking/provider.d.ts +70 -0
  227. package/dist/src/matchmaking/provider.d.ts.map +1 -0
  228. package/dist/src/matchmaking/provider.js +93 -0
  229. package/dist/src/matchmaking/provider.js.map +1 -0
  230. package/dist/src/matchmaking/query-eval.d.ts +53 -0
  231. package/dist/src/matchmaking/query-eval.d.ts.map +1 -0
  232. package/dist/src/matchmaking/query-eval.js +69 -0
  233. package/dist/src/matchmaking/query-eval.js.map +1 -0
  234. package/dist/src/matchmaking/seeker-walk.d.ts +95 -0
  235. package/dist/src/matchmaking/seeker-walk.d.ts.map +1 -0
  236. package/dist/src/matchmaking/seeker-walk.js +75 -0
  237. package/dist/src/matchmaking/seeker-walk.js.map +1 -0
  238. package/dist/src/matchmaking/seeker.d.ts +51 -0
  239. package/dist/src/matchmaking/seeker.d.ts.map +1 -0
  240. package/dist/src/matchmaking/seeker.js +62 -0
  241. package/dist/src/matchmaking/seeker.js.map +1 -0
  242. package/dist/src/matchmaking/topic-anchor.d.ts +54 -0
  243. package/dist/src/matchmaking/topic-anchor.d.ts.map +1 -0
  244. package/dist/src/matchmaking/topic-anchor.js +67 -0
  245. package/dist/src/matchmaking/topic-anchor.js.map +1 -0
  246. package/dist/src/matchmaking/voting-quorum.d.ts +233 -0
  247. package/dist/src/matchmaking/voting-quorum.d.ts.map +1 -0
  248. package/dist/src/matchmaking/voting-quorum.js +238 -0
  249. package/dist/src/matchmaking/voting-quorum.js.map +1 -0
  250. package/dist/src/matchmaking/wire.d.ts +259 -0
  251. package/dist/src/matchmaking/wire.d.ts.map +1 -0
  252. package/dist/src/matchmaking/wire.js +484 -0
  253. package/dist/src/matchmaking/wire.js.map +1 -0
  254. package/dist/src/network/i-repo.d.ts +9 -0
  255. package/dist/src/network/i-repo.d.ts.map +1 -1
  256. package/dist/src/network/repo-protocol.d.ts +3 -1
  257. package/dist/src/network/repo-protocol.d.ts.map +1 -1
  258. package/dist/src/network/struct.d.ts +23 -1
  259. package/dist/src/network/struct.d.ts.map +1 -1
  260. package/dist/src/reactivity/backfill.d.ts +118 -0
  261. package/dist/src/reactivity/backfill.d.ts.map +1 -0
  262. package/dist/src/reactivity/backfill.js +137 -0
  263. package/dist/src/reactivity/backfill.js.map +1 -0
  264. package/dist/src/reactivity/backpressure.d.ts +99 -0
  265. package/dist/src/reactivity/backpressure.d.ts.map +1 -0
  266. package/dist/src/reactivity/backpressure.js +153 -0
  267. package/dist/src/reactivity/backpressure.js.map +1 -0
  268. package/dist/src/reactivity/checkpoint.d.ts +165 -0
  269. package/dist/src/reactivity/checkpoint.d.ts.map +1 -0
  270. package/dist/src/reactivity/checkpoint.js +232 -0
  271. package/dist/src/reactivity/checkpoint.js.map +1 -0
  272. package/dist/src/reactivity/config.d.ts +131 -0
  273. package/dist/src/reactivity/config.d.ts.map +1 -0
  274. package/dist/src/reactivity/config.js +135 -0
  275. package/dist/src/reactivity/config.js.map +1 -0
  276. package/dist/src/reactivity/dedupe.d.ts +51 -0
  277. package/dist/src/reactivity/dedupe.d.ts.map +1 -0
  278. package/dist/src/reactivity/dedupe.js +90 -0
  279. package/dist/src/reactivity/dedupe.js.map +1 -0
  280. package/dist/src/reactivity/forwarder.d.ts +50 -0
  281. package/dist/src/reactivity/forwarder.d.ts.map +1 -0
  282. package/dist/src/reactivity/forwarder.js +52 -0
  283. package/dist/src/reactivity/forwarder.js.map +1 -0
  284. package/dist/src/reactivity/index.d.ts +34 -0
  285. package/dist/src/reactivity/index.d.ts.map +1 -0
  286. package/dist/src/reactivity/index.js +34 -0
  287. package/dist/src/reactivity/index.js.map +1 -0
  288. package/dist/src/reactivity/notification.d.ts +72 -0
  289. package/dist/src/reactivity/notification.d.ts.map +1 -0
  290. package/dist/src/reactivity/notification.js +92 -0
  291. package/dist/src/reactivity/notification.js.map +1 -0
  292. package/dist/src/reactivity/policy.d.ts +59 -0
  293. package/dist/src/reactivity/policy.d.ts.map +1 -0
  294. package/dist/src/reactivity/policy.js +64 -0
  295. package/dist/src/reactivity/policy.js.map +1 -0
  296. package/dist/src/reactivity/push-state.d.ts +140 -0
  297. package/dist/src/reactivity/push-state.d.ts.map +1 -0
  298. package/dist/src/reactivity/push-state.js +270 -0
  299. package/dist/src/reactivity/push-state.js.map +1 -0
  300. package/dist/src/reactivity/recover.d.ts +75 -0
  301. package/dist/src/reactivity/recover.d.ts.map +1 -0
  302. package/dist/src/reactivity/recover.js +105 -0
  303. package/dist/src/reactivity/recover.js.map +1 -0
  304. package/dist/src/reactivity/replay-buffer.d.ts +57 -0
  305. package/dist/src/reactivity/replay-buffer.d.ts.map +1 -0
  306. package/dist/src/reactivity/replay-buffer.js +88 -0
  307. package/dist/src/reactivity/replay-buffer.js.map +1 -0
  308. package/dist/src/reactivity/resume.d.ts +214 -0
  309. package/dist/src/reactivity/resume.d.ts.map +1 -0
  310. package/dist/src/reactivity/resume.js +358 -0
  311. package/dist/src/reactivity/resume.js.map +1 -0
  312. package/dist/src/reactivity/rotation.d.ts +283 -0
  313. package/dist/src/reactivity/rotation.d.ts.map +1 -0
  314. package/dist/src/reactivity/rotation.js +265 -0
  315. package/dist/src/reactivity/rotation.js.map +1 -0
  316. package/dist/src/reactivity/subscriber.d.ts +66 -0
  317. package/dist/src/reactivity/subscriber.d.ts.map +1 -0
  318. package/dist/src/reactivity/subscriber.js +75 -0
  319. package/dist/src/reactivity/subscriber.js.map +1 -0
  320. package/dist/src/reactivity/subscription.d.ts +52 -0
  321. package/dist/src/reactivity/subscription.d.ts.map +1 -0
  322. package/dist/src/reactivity/subscription.js +28 -0
  323. package/dist/src/reactivity/subscription.js.map +1 -0
  324. package/dist/src/reactivity/topic-anchor.d.ts +46 -0
  325. package/dist/src/reactivity/topic-anchor.d.ts.map +1 -0
  326. package/dist/src/reactivity/topic-anchor.js +61 -0
  327. package/dist/src/reactivity/topic-anchor.js.map +1 -0
  328. package/dist/src/reactivity/verify.d.ts +41 -0
  329. package/dist/src/reactivity/verify.d.ts.map +1 -0
  330. package/dist/src/reactivity/verify.js +48 -0
  331. package/dist/src/reactivity/verify.js.map +1 -0
  332. package/dist/src/reactivity/wire-validate.d.ts +28 -0
  333. package/dist/src/reactivity/wire-validate.d.ts.map +1 -0
  334. package/dist/src/reactivity/wire-validate.js +79 -0
  335. package/dist/src/reactivity/wire-validate.js.map +1 -0
  336. package/dist/src/reactivity/wire.d.ts +102 -0
  337. package/dist/src/reactivity/wire.d.ts.map +1 -0
  338. package/dist/src/reactivity/wire.js +129 -0
  339. package/dist/src/reactivity/wire.js.map +1 -0
  340. package/dist/src/transaction/coordinator.d.ts +9 -5
  341. package/dist/src/transaction/coordinator.d.ts.map +1 -1
  342. package/dist/src/transaction/coordinator.js +48 -25
  343. package/dist/src/transaction/coordinator.js.map +1 -1
  344. package/dist/src/transactor/change-notifier.d.ts +74 -0
  345. package/dist/src/transactor/change-notifier.d.ts.map +1 -0
  346. package/dist/src/transactor/change-notifier.js +4 -0
  347. package/dist/src/transactor/change-notifier.js.map +1 -0
  348. package/dist/src/transactor/index.d.ts +1 -0
  349. package/dist/src/transactor/index.d.ts.map +1 -1
  350. package/dist/src/transactor/index.js +1 -0
  351. package/dist/src/transactor/index.js.map +1 -1
  352. package/dist/src/transactor/network-transactor.d.ts +34 -2
  353. package/dist/src/transactor/network-transactor.d.ts.map +1 -1
  354. package/dist/src/transactor/network-transactor.js +113 -13
  355. package/dist/src/transactor/network-transactor.js.map +1 -1
  356. package/package.json +2 -2
  357. package/src/cluster/structs.ts +13 -0
  358. package/src/cohort-topic/addressing.ts +112 -0
  359. package/src/cohort-topic/antidos/bootstrap-evidence-envelope.ts +253 -0
  360. package/src/cohort-topic/antidos/bootstrap-evidence.ts +94 -0
  361. package/src/cohort-topic/antidos/index.ts +5 -0
  362. package/src/cohort-topic/antidos/rate-limiter.ts +210 -0
  363. package/src/cohort-topic/antidos/replay-guard.ts +109 -0
  364. package/src/cohort-topic/antidos/topic-budget.ts +145 -0
  365. package/src/cohort-topic/antiflood/index.ts +2 -0
  366. package/src/cohort-topic/antiflood/invariants.ts +108 -0
  367. package/src/cohort-topic/antiflood/jitter.ts +117 -0
  368. package/src/cohort-topic/coldstart.ts +204 -0
  369. package/src/cohort-topic/dmax.ts +88 -0
  370. package/src/cohort-topic/gossip/bus.ts +217 -0
  371. package/src/cohort-topic/gossip/index.ts +3 -0
  372. package/src/cohort-topic/gossip/records.ts +45 -0
  373. package/src/cohort-topic/gossip/view.ts +66 -0
  374. package/src/cohort-topic/index.ts +20 -0
  375. package/src/cohort-topic/load/barometer.ts +134 -0
  376. package/src/cohort-topic/load/index.ts +1 -0
  377. package/src/cohort-topic/member-engine.ts +409 -0
  378. package/src/cohort-topic/membership/index.ts +3 -0
  379. package/src/cohort-topic/membership/publisher.ts +171 -0
  380. package/src/cohort-topic/membership/source.ts +41 -0
  381. package/src/cohort-topic/membership/verifier.ts +345 -0
  382. package/src/cohort-topic/ports.ts +157 -0
  383. package/src/cohort-topic/promotion.ts +384 -0
  384. package/src/cohort-topic/registration/bytes.ts +37 -0
  385. package/src/cohort-topic/registration/handoff.ts +154 -0
  386. package/src/cohort-topic/registration/index.ts +6 -0
  387. package/src/cohort-topic/registration/renewal.ts +423 -0
  388. package/src/cohort-topic/registration/sharding.ts +61 -0
  389. package/src/cohort-topic/registration/store.ts +81 -0
  390. package/src/cohort-topic/registration/types.ts +76 -0
  391. package/src/cohort-topic/ring-hash.ts +50 -0
  392. package/src/cohort-topic/service.ts +390 -0
  393. package/src/cohort-topic/sig/index.ts +2 -0
  394. package/src/cohort-topic/sig/payloads.ts +39 -0
  395. package/src/cohort-topic/sig/threshold.ts +64 -0
  396. package/src/cohort-topic/tiers.ts +74 -0
  397. package/src/cohort-topic/traffic.ts +211 -0
  398. package/src/cohort-topic/walk.ts +255 -0
  399. package/src/cohort-topic/willingness.ts +237 -0
  400. package/src/cohort-topic/wire/codec.ts +204 -0
  401. package/src/cohort-topic/wire/index.ts +16 -0
  402. package/src/cohort-topic/wire/payloads.ts +117 -0
  403. package/src/cohort-topic/wire/types.ts +343 -0
  404. package/src/cohort-topic/wire/validate.ts +478 -0
  405. package/src/collection/collection.ts +93 -1
  406. package/src/collections/tree/tree.ts +84 -3
  407. package/src/index.ts +3 -0
  408. package/src/log/log.ts +86 -7
  409. package/src/log/struct.ts +126 -2
  410. package/src/matchmaking/capability-filter.ts +45 -0
  411. package/src/matchmaking/config.ts +98 -0
  412. package/src/matchmaking/index.ts +21 -0
  413. package/src/matchmaking/multi-cohort-seeker.ts +234 -0
  414. package/src/matchmaking/provider.ts +123 -0
  415. package/src/matchmaking/query-eval.ts +105 -0
  416. package/src/matchmaking/seeker-walk.ts +127 -0
  417. package/src/matchmaking/seeker.ts +86 -0
  418. package/src/matchmaking/topic-anchor.ts +90 -0
  419. package/src/matchmaking/voting-quorum.ts +394 -0
  420. package/src/matchmaking/wire.ts +680 -0
  421. package/src/network/i-repo.ts +9 -0
  422. package/src/network/repo-protocol.ts +3 -2
  423. package/src/network/struct.ts +24 -1
  424. package/src/reactivity/backfill.ts +220 -0
  425. package/src/reactivity/backpressure.ts +191 -0
  426. package/src/reactivity/checkpoint.ts +308 -0
  427. package/src/reactivity/config.ts +172 -0
  428. package/src/reactivity/dedupe.ts +132 -0
  429. package/src/reactivity/forwarder.ts +87 -0
  430. package/src/reactivity/index.ts +34 -0
  431. package/src/reactivity/notification.ts +123 -0
  432. package/src/reactivity/policy.ts +79 -0
  433. package/src/reactivity/push-state.ts +343 -0
  434. package/src/reactivity/recover.ts +153 -0
  435. package/src/reactivity/replay-buffer.ts +141 -0
  436. package/src/reactivity/resume.ts +549 -0
  437. package/src/reactivity/rotation.ts +415 -0
  438. package/src/reactivity/subscriber.ts +132 -0
  439. package/src/reactivity/subscription.ts +66 -0
  440. package/src/reactivity/topic-anchor.ts +71 -0
  441. package/src/reactivity/verify.ts +73 -0
  442. package/src/reactivity/wire-validate.ts +87 -0
  443. package/src/reactivity/wire.ts +224 -0
  444. package/src/transaction/coordinator.ts +53 -27
  445. package/src/transactor/change-notifier.ts +80 -0
  446. package/src/transactor/index.ts +1 -0
  447. package/src/transactor/network-transactor.ts +133 -15
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Reactivity — subscriber delivery path (`docs/reactivity.md` §Delivery).
3
+ *
4
+ * A subscriber receiving a notification:
5
+ * 1. **verifies** `sig` against the cached tail-cohort `MembershipCertV1` (the {@link NotificationVerifier}
6
+ * owns the **one fetch-and-retry** on a stale cache);
7
+ * 2. checks `revision == lastRevision + 1`. If not, requests a backfill for the gap
8
+ * `[lastRevision + 1, revision]` via the {@link requestBackfill} seam (the `BackfillV1` request shape
9
+ * lands in [reactivity-backfill-resume-checkpoints]; this ticket only *detects* the gap and calls the
10
+ * hook);
11
+ * 3. updates `lastRevision` once revisions are contiguous;
12
+ * 4. surfaces the notification to the application layer.
13
+ *
14
+ * Subscribers dedupe by `(collectionId, revision)`; duplicates from forwarder retries are discarded.
15
+ * A fresh subscription (`lastKnownRev == 0`, uninitialized) adopts the first verified notification as its
16
+ * baseline rather than demanding a backfill from revision 1.
17
+ */
18
+ class CollectionSubscriber {
19
+ deps;
20
+ last;
21
+ initialized;
22
+ constructor(deps) {
23
+ this.deps = deps;
24
+ const lastKnownRev = deps.lastKnownRev ?? 0;
25
+ this.last = lastKnownRev;
26
+ // A fresh subscribe (lastKnownRev == 0) has no baseline yet; the first verified notification sets it.
27
+ this.initialized = lastKnownRev > 0;
28
+ }
29
+ get lastRevision() {
30
+ return this.last;
31
+ }
32
+ rebaseline(revision) {
33
+ // A verified checkpoint summarized everything up to `revision`; jump the head forward (never back).
34
+ if (!this.initialized || revision > this.last) {
35
+ this.last = revision;
36
+ this.initialized = true;
37
+ }
38
+ }
39
+ async onNotification(n) {
40
+ if (n.collectionId !== this.deps.collectionId) {
41
+ return "foreign";
42
+ }
43
+ // Verify first (one fetch-and-retry is internal to the verifier). An untrusted notification is
44
+ // dropped before any (collectionId, revision) dedupe or lastRevision update.
45
+ const verdict = await this.deps.verifier.verify(n);
46
+ if (verdict !== "verified") {
47
+ return "untrusted";
48
+ }
49
+ // Fresh subscription: adopt the first verified notification as the contiguity baseline.
50
+ if (!this.initialized) {
51
+ this.initialized = true;
52
+ this.last = n.revision;
53
+ this.deps.deliver(n);
54
+ return "delivered";
55
+ }
56
+ // Dedupe by (collectionId, revision): anything at or below the contiguous head is already delivered.
57
+ if (n.revision <= this.last) {
58
+ return "duplicate";
59
+ }
60
+ // Contiguity check.
61
+ if (n.revision === this.last + 1) {
62
+ this.last = n.revision;
63
+ this.deps.deliver(n);
64
+ return "delivered";
65
+ }
66
+ // Gap: request the missing range (inclusive of `revision`); the backfilled entries re-enter here.
67
+ this.deps.requestBackfill?.(this.last + 1, n.revision);
68
+ return "gap";
69
+ }
70
+ }
71
+ /** Build a {@link ReactivitySubscriber} for one collection. */
72
+ export function createReactivitySubscriber(deps) {
73
+ return new CollectionSubscriber(deps);
74
+ }
75
+ //# sourceMappingURL=subscriber.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscriber.js","sourceRoot":"","sources":["../../../src/reactivity/subscriber.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAoDH,MAAM,oBAAoB;IAII;IAHrB,IAAI,CAAS;IACb,WAAW,CAAU;IAE7B,YAA6B,IAA8B;QAA9B,SAAI,GAAJ,IAAI,CAA0B;QAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,sGAAsG;QACtG,IAAI,CAAC,WAAW,GAAG,YAAY,GAAG,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,YAAY;QACf,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,UAAU,CAAC,QAAgB;QAC1B,oGAAoG;QACpG,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC/C,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;YACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACzB,CAAC;IACF,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,CAAiB;QACrC,IAAI,CAAC,CAAC,YAAY,KAAK,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC/C,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,+FAA+F;QAC/F,6EAA6E;QAC7E,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACnD,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC5B,OAAO,WAAW,CAAC;QACpB,CAAC;QAED,wFAAwF;QACxF,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACrB,OAAO,WAAW,CAAC;QACpB,CAAC;QAED,qGAAqG;QACrG,IAAI,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC7B,OAAO,WAAW,CAAC;QACpB,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACrB,OAAO,WAAW,CAAC;QACpB,CAAC;QAED,kGAAkG;QAClG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;QACvD,OAAO,KAAK,CAAC;IACd,CAAC;CACD;AAED,+DAA+D;AAC/D,MAAM,UAAU,0BAA0B,CAAC,IAA8B;IACxE,OAAO,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Reactivity — subscriber-side subscription state (`docs/reactivity.md` §Subscription).
3
+ *
4
+ * Subscribing to a collection is an **ordinary cohort-topic registration** at tier T3 with a reactivity
5
+ * `appPayload`: `topicId = H(currentTailId(C) ‖ "reactivity")`, the configured TTL (Edge 60 s / Core 90 s),
6
+ * and the cohort-topic walk-toward-root / willingness / promotion / TTL-renewal all reused unchanged.
7
+ * This module owns only the subscriber-side bookkeeping struct and the `appPayload` builder; the db-p2p
8
+ * subscription manager drives the cohort-topic `RegisterV1`.
9
+ *
10
+ * `tailIdAtAttach` is the subscriber-side detector for tail rotation (the whole-tree migration the
11
+ * rotation ticket handles); `cohortEpoch` detects membership drift within the topic.
12
+ */
13
+ import { type SubscribeAppPayloadV1 } from "./wire.js";
14
+ /** Subscriber-side live state for one active subscription (`docs/reactivity.md` §Subscriber-side state). */
15
+ export interface ActiveSubscription {
16
+ /** Stable collection identity. */
17
+ readonly collectionId: Uint8Array;
18
+ /** Current tail-anchored topic id. */
19
+ readonly topicId: Uint8Array;
20
+ /** Tail block id at registration time — detects tail rotation. */
21
+ readonly tailIdAtAttach: Uint8Array;
22
+ /** Serving cohort member. */
23
+ primary: Uint8Array;
24
+ /** Warm-failover cohort members. */
25
+ backups: Uint8Array[];
26
+ /** Cohort member hint set for fast re-attach. */
27
+ cohortHint: Uint8Array[];
28
+ /** Cohort epoch for membership-drift detection. */
29
+ cohortEpoch: Uint8Array;
30
+ /** Last contiguously-delivered revision. */
31
+ lastRevision: number;
32
+ /** Unix ms of the last delivery. */
33
+ lastDeliveredAt: number;
34
+ /** Unix ms the subscription attached. */
35
+ attachedAt: number;
36
+ }
37
+ /** Parameters for building a subscribe `appPayload`. */
38
+ export interface SubscribeParams {
39
+ /** Collection id, base64url. */
40
+ readonly collectionId: string;
41
+ /** Tail block id at attach time, base64url. */
42
+ readonly tailIdAtAttach: string;
43
+ /** Last revision already held; `0` for a fresh subscribe. */
44
+ readonly lastKnownRev?: number;
45
+ /** Max delta bytes accepted; `0` declines deltas (Edge). */
46
+ readonly deltaMaxBytes: number;
47
+ }
48
+ /** Build the validated {@link SubscribeAppPayloadV1} for a subscription. */
49
+ export declare function buildSubscribeAppPayload(params: SubscribeParams): SubscribeAppPayloadV1;
50
+ /** Build the opaque `RegisterV1.appPayload` bytes for a subscription. */
51
+ export declare function subscribeAppPayloadBytes(params: SubscribeParams): Uint8Array;
52
+ //# sourceMappingURL=subscription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../../src/reactivity/subscription.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAA6B,KAAK,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAElF,4GAA4G;AAC5G,MAAM,WAAW,kBAAkB;IAClC,kCAAkC;IAClC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC;IAClC,sCAAsC;IACtC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC;IACpC,6BAA6B;IAC7B,OAAO,EAAE,UAAU,CAAC;IACpB,oCAAoC;IACpC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,iDAAiD;IACjD,UAAU,EAAE,UAAU,EAAE,CAAC;IACzB,mDAAmD;IACnD,WAAW,EAAE,UAAU,CAAC;IACxB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,wDAAwD;AACxD,MAAM,WAAW,eAAe;IAC/B,gCAAgC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,+CAA+C;IAC/C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAC/B;AAED,4EAA4E;AAC5E,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,eAAe,GAAG,qBAAqB,CAQvF;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,eAAe,GAAG,UAAU,CAE5E"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Reactivity — subscriber-side subscription state (`docs/reactivity.md` §Subscription).
3
+ *
4
+ * Subscribing to a collection is an **ordinary cohort-topic registration** at tier T3 with a reactivity
5
+ * `appPayload`: `topicId = H(currentTailId(C) ‖ "reactivity")`, the configured TTL (Edge 60 s / Core 90 s),
6
+ * and the cohort-topic walk-toward-root / willingness / promotion / TTL-renewal all reused unchanged.
7
+ * This module owns only the subscriber-side bookkeeping struct and the `appPayload` builder; the db-p2p
8
+ * subscription manager drives the cohort-topic `RegisterV1`.
9
+ *
10
+ * `tailIdAtAttach` is the subscriber-side detector for tail rotation (the whole-tree migration the
11
+ * rotation ticket handles); `cohortEpoch` detects membership drift within the topic.
12
+ */
13
+ import { encodeSubscribeAppPayload } from "./wire.js";
14
+ /** Build the validated {@link SubscribeAppPayloadV1} for a subscription. */
15
+ export function buildSubscribeAppPayload(params) {
16
+ return {
17
+ kind: "reactivity",
18
+ collectionId: params.collectionId,
19
+ tailIdAtAttach: params.tailIdAtAttach,
20
+ lastKnownRev: params.lastKnownRev ?? 0,
21
+ deltaMaxBytes: params.deltaMaxBytes,
22
+ };
23
+ }
24
+ /** Build the opaque `RegisterV1.appPayload` bytes for a subscription. */
25
+ export function subscribeAppPayloadBytes(params) {
26
+ return encodeSubscribeAppPayload(buildSubscribeAppPayload(params));
27
+ }
28
+ //# sourceMappingURL=subscription.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../../src/reactivity/subscription.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,yBAAyB,EAA8B,MAAM,WAAW,CAAC;AAsClF,4EAA4E;AAC5E,MAAM,UAAU,wBAAwB,CAAC,MAAuB;IAC/D,OAAO;QACN,IAAI,EAAE,YAAY;QAClB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC;QACtC,aAAa,EAAE,MAAM,CAAC,aAAa;KACnC,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,wBAAwB,CAAC,MAAuB;IAC/D,OAAO,yBAAyB,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC,CAAC;AACpE,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Reactivity — rotating, tail-anchored topic.
3
+ *
4
+ * Transcribed from `docs/reactivity.md` §Anchor:
5
+ *
6
+ * ```
7
+ * topicId(collection C, tail T) = H(T.blockId ‖ "reactivity")
8
+ * ```
9
+ *
10
+ * Unlike matchmaking (whose anchor is a stable `(kind, label)`), the reactivity anchor **rotates** with
11
+ * the collection's tail block: when the tail fills and a new tail block is born, `topicId` changes and
12
+ * the cohort-topic layer treats it as an entirely new topic. The whole-tree migration that follows is
13
+ * the rotation ticket's concern; this module owns only the pure derivation.
14
+ *
15
+ * The resulting `topicId` is fed verbatim into cohort-topic tier addressing (`coord_d(self, topicId)`),
16
+ * so it is derived with the **same** {@link IRingHash} primitive cohort-topic uses for `coord_d` input —
17
+ * db-core's own SHA-256 truncated to the ring width, **not** a FRET import. The trailing `"reactivity"`
18
+ * literal domain-separates the reactivity tree from any other application anchoring on the same tail id.
19
+ *
20
+ * Concatenation is delimiter-free, exactly as the spec writes it; the constant suffix is unambiguous
21
+ * because no tail-id byte string can alias a `(tailId, "reactivity")` pair of a different length.
22
+ *
23
+ * `reactivityTopicId` is the small pure helper the ticket asks for once and the rotation ticket
24
+ * ([reactivity-rotation-backpressure-policy]) reuses per-emission — define it here, not at the call site.
25
+ */
26
+ import type { IRingHash } from "../cohort-topic/ports.js";
27
+ /**
28
+ * `H(tailId ‖ "reactivity")` over the injected ring hash — the cohort-topic `topicId` for the
29
+ * reactivity tree anchored on `tailId` (the collection's current tail block id, as raw bytes).
30
+ *
31
+ * The shared helper consumed by subscriber attachment, origination, and (per-emission) the rotation
32
+ * ticket. `hash` defaults to db-core's own 256-bit SHA-256, byte-identical to the cohort-topic host's.
33
+ */
34
+ export declare function reactivityTopicId(tailId: Uint8Array, hash?: IRingHash): Uint8Array;
35
+ /** Derives the rotating `topicId` for a collection's current tail. */
36
+ export interface ReactivityTopicAnchor {
37
+ /** `H(tailId ‖ "reactivity")` for the given tail block id (bytes). */
38
+ topicId(tailId: Uint8Array): Uint8Array;
39
+ }
40
+ /**
41
+ * Build a {@link ReactivityTopicAnchor} over the injected hash. db-p2p passes the same {@link IRingHash}
42
+ * it binds to FRET's `RING_BITS` so the anchor and cohort-topic routing keys line up; the default
43
+ * constructs db-core's own {@link createRingHash} (256-bit SHA-256).
44
+ */
45
+ export declare function createReactivityTopicAnchor(hash?: IRingHash): ReactivityTopicAnchor;
46
+ //# sourceMappingURL=topic-anchor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topic-anchor.d.ts","sourceRoot":"","sources":["../../../src/reactivity/topic-anchor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAO1D;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,GAAE,SAA4B,GAAG,UAAU,CAMpG;AAED,sEAAsE;AACtE,MAAM,WAAW,qBAAqB;IACrC,sEAAsE;IACtE,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;CACxC;AAUD;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,GAAE,SAA4B,GAAG,qBAAqB,CAErG"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Reactivity — rotating, tail-anchored topic.
3
+ *
4
+ * Transcribed from `docs/reactivity.md` §Anchor:
5
+ *
6
+ * ```
7
+ * topicId(collection C, tail T) = H(T.blockId ‖ "reactivity")
8
+ * ```
9
+ *
10
+ * Unlike matchmaking (whose anchor is a stable `(kind, label)`), the reactivity anchor **rotates** with
11
+ * the collection's tail block: when the tail fills and a new tail block is born, `topicId` changes and
12
+ * the cohort-topic layer treats it as an entirely new topic. The whole-tree migration that follows is
13
+ * the rotation ticket's concern; this module owns only the pure derivation.
14
+ *
15
+ * The resulting `topicId` is fed verbatim into cohort-topic tier addressing (`coord_d(self, topicId)`),
16
+ * so it is derived with the **same** {@link IRingHash} primitive cohort-topic uses for `coord_d` input —
17
+ * db-core's own SHA-256 truncated to the ring width, **not** a FRET import. The trailing `"reactivity"`
18
+ * literal domain-separates the reactivity tree from any other application anchoring on the same tail id.
19
+ *
20
+ * Concatenation is delimiter-free, exactly as the spec writes it; the constant suffix is unambiguous
21
+ * because no tail-id byte string can alias a `(tailId, "reactivity")` pair of a different length.
22
+ *
23
+ * `reactivityTopicId` is the small pure helper the ticket asks for once and the rotation ticket
24
+ * ([reactivity-rotation-backpressure-policy]) reuses per-emission — define it here, not at the call site.
25
+ */
26
+ import { createRingHash } from "../cohort-topic/ring-hash.js";
27
+ /** Domain-separation suffix mixed into every reactivity anchor. */
28
+ const REACTIVITY_SUFFIX = "reactivity";
29
+ const utf8 = new TextEncoder();
30
+ /**
31
+ * `H(tailId ‖ "reactivity")` over the injected ring hash — the cohort-topic `topicId` for the
32
+ * reactivity tree anchored on `tailId` (the collection's current tail block id, as raw bytes).
33
+ *
34
+ * The shared helper consumed by subscriber attachment, origination, and (per-emission) the rotation
35
+ * ticket. `hash` defaults to db-core's own 256-bit SHA-256, byte-identical to the cohort-topic host's.
36
+ */
37
+ export function reactivityTopicId(tailId, hash = createRingHash()) {
38
+ const suffixBytes = utf8.encode(REACTIVITY_SUFFIX);
39
+ const input = new Uint8Array(tailId.length + suffixBytes.length);
40
+ input.set(tailId, 0);
41
+ input.set(suffixBytes, tailId.length);
42
+ return hash.H(input);
43
+ }
44
+ class HashReactivityTopicAnchor {
45
+ hash;
46
+ constructor(hash) {
47
+ this.hash = hash;
48
+ }
49
+ topicId(tailId) {
50
+ return reactivityTopicId(tailId, this.hash);
51
+ }
52
+ }
53
+ /**
54
+ * Build a {@link ReactivityTopicAnchor} over the injected hash. db-p2p passes the same {@link IRingHash}
55
+ * it binds to FRET's `RING_BITS` so the anchor and cohort-topic routing keys line up; the default
56
+ * constructs db-core's own {@link createRingHash} (256-bit SHA-256).
57
+ */
58
+ export function createReactivityTopicAnchor(hash = createRingHash()) {
59
+ return new HashReactivityTopicAnchor(hash);
60
+ }
61
+ //# sourceMappingURL=topic-anchor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topic-anchor.js","sourceRoot":"","sources":["../../../src/reactivity/topic-anchor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAG9D,mEAAmE;AACnE,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAEvC,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;AAE/B;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAkB,EAAE,OAAkB,cAAc,EAAE;IACvF,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACrB,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACtB,CAAC;AAQD,MAAM,yBAAyB;IACD;IAA7B,YAA6B,IAAe;QAAf,SAAI,GAAJ,IAAI,CAAW;IAAG,CAAC;IAEhD,OAAO,CAAC,MAAkB;QACzB,OAAO,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;CACD;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,OAAkB,cAAc,EAAE;IAC7E,OAAO,IAAI,yBAAyB,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Reactivity — subscriber/forwarder notification verification seam
3
+ * (`docs/reactivity.md` §Propagation, §Delivery, §Authentication).
4
+ *
5
+ * A forwarder and a subscriber both verify a notification's threshold signature against the **tail
6
+ * cohort's** `MembershipCertV1` before trusting it — forwarders never re-sign, so the same end-to-end
7
+ * signature is verified regardless of hop count. The standard cohort-topic membership-snapshot path
8
+ * ({@link MembershipVerifier}) already provides the **one fetch-and-retry** on a stale/missing cached
9
+ * cert, so this module is a thin adapter: derive the tail cohort's `coord_0(_, topicId)` from the
10
+ * notification's `tailId`, then hand `(signers, coord, tier, digest, sig)` to the verifier.
11
+ *
12
+ * The signed payload is the commit `digest` (the commit cert's threshold signature is over the commit
13
+ * hash — see {@link import("./notification.js").buildNotificationV1}). `signers` arrive base64url-encoded
14
+ * as the cohort member-id bytes the verifier compares against `cert.members`; a custom `signersToBytes`
15
+ * seam is exposed for bindings that carry signers in a different encoding.
16
+ */
17
+ import { Tier } from "../cohort-topic/tiers.js";
18
+ import type { IRingHash } from "../cohort-topic/ports.js";
19
+ import type { MembershipVerifier, VerifyResult } from "../cohort-topic/membership/verifier.js";
20
+ import type { NotificationV1 } from "./wire.js";
21
+ /** Verifies a {@link NotificationV1}'s threshold signature against the tail cohort's membership. */
22
+ export interface NotificationVerifier {
23
+ /** `"verified"` iff `sig` is a valid `≥ minSigs` cohort signature over the commit digest. */
24
+ verify(n: NotificationV1): Promise<VerifyResult>;
25
+ }
26
+ /** Construction inputs for the default {@link NotificationVerifier}. */
27
+ export interface NotificationVerifierDeps {
28
+ /** The cohort-topic participant-side membership verifier (owns the one fetch-and-retry). */
29
+ readonly verifier: MembershipVerifier;
30
+ /** Ring hash for `topicId` / `coord_0` derivation. Default db-core 256-bit SHA-256. */
31
+ readonly hash?: IRingHash;
32
+ /** Fan-out `F` for tier addressing. Default {@link DEFAULT_FANOUT}. */
33
+ readonly fanout?: number;
34
+ /** Reactivity runs at T3; overridable for tests. */
35
+ readonly tier?: Tier;
36
+ /** Map a wire signer string to the verifier's member-id bytes. Default base64url decode. */
37
+ readonly signersToBytes?: (signer: string) => Uint8Array;
38
+ }
39
+ /** Build the default {@link NotificationVerifier} over the cohort-topic {@link MembershipVerifier}. */
40
+ export declare function createNotificationVerifier(deps: NotificationVerifierDeps): NotificationVerifier;
41
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/reactivity/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAE/F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,oGAAoG;AACpG,MAAM,WAAW,oBAAoB;IACpC,6FAA6F;IAC7F,MAAM,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACjD;AAED,wEAAwE;AACxE,MAAM,WAAW,wBAAwB;IACxC,4FAA4F;IAC5F,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,uFAAuF;IACvF,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,4FAA4F;IAC5F,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,UAAU,CAAC;CACzD;AAyBD,uGAAuG;AACvG,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,wBAAwB,GAAG,oBAAoB,CAE/F"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Reactivity — subscriber/forwarder notification verification seam
3
+ * (`docs/reactivity.md` §Propagation, §Delivery, §Authentication).
4
+ *
5
+ * A forwarder and a subscriber both verify a notification's threshold signature against the **tail
6
+ * cohort's** `MembershipCertV1` before trusting it — forwarders never re-sign, so the same end-to-end
7
+ * signature is verified regardless of hop count. The standard cohort-topic membership-snapshot path
8
+ * ({@link MembershipVerifier}) already provides the **one fetch-and-retry** on a stale/missing cached
9
+ * cert, so this module is a thin adapter: derive the tail cohort's `coord_0(_, topicId)` from the
10
+ * notification's `tailId`, then hand `(signers, coord, tier, digest, sig)` to the verifier.
11
+ *
12
+ * The signed payload is the commit `digest` (the commit cert's threshold signature is over the commit
13
+ * hash — see {@link import("./notification.js").buildNotificationV1}). `signers` arrive base64url-encoded
14
+ * as the cohort member-id bytes the verifier compares against `cert.members`; a custom `signersToBytes`
15
+ * seam is exposed for bindings that carry signers in a different encoding.
16
+ */
17
+ import { createTierAddressing, DEFAULT_FANOUT } from "../cohort-topic/addressing.js";
18
+ import { createRingHash } from "../cohort-topic/ring-hash.js";
19
+ import { b64urlToBytes } from "../cohort-topic/wire/codec.js";
20
+ import { Tier } from "../cohort-topic/tiers.js";
21
+ import { reactivityTopicId } from "./topic-anchor.js";
22
+ class MembershipNotificationVerifier {
23
+ deps;
24
+ addressing;
25
+ hash;
26
+ tier;
27
+ signersToBytes;
28
+ constructor(deps) {
29
+ this.deps = deps;
30
+ this.hash = deps.hash ?? createRingHash();
31
+ this.addressing = createTierAddressing(this.hash, deps.fanout ?? DEFAULT_FANOUT);
32
+ this.tier = deps.tier ?? Tier.T3;
33
+ this.signersToBytes = deps.signersToBytes ?? b64urlToBytes;
34
+ }
35
+ async verify(n) {
36
+ const topicId = reactivityTopicId(b64urlToBytes(n.tailId), this.hash);
37
+ const expectedCoord = this.addressing.coord0(topicId);
38
+ const signers = n.signers.map(this.signersToBytes);
39
+ const payload = b64urlToBytes(n.digest);
40
+ const sig = b64urlToBytes(n.sig);
41
+ return this.deps.verifier.verifyMessage(signers, expectedCoord, this.tier, payload, sig);
42
+ }
43
+ }
44
+ /** Build the default {@link NotificationVerifier} over the cohort-topic {@link MembershipVerifier}. */
45
+ export function createNotificationVerifier(deps) {
46
+ return new MembershipNotificationVerifier(deps);
47
+ }
48
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/reactivity/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAGhD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAuBtD,MAAM,8BAA8B;IAMN;IALZ,UAAU,CAA0C;IACpD,IAAI,CAAY;IAChB,IAAI,CAAO;IACX,cAAc,CAAiC;IAEhE,YAA6B,IAA8B;QAA9B,SAAI,GAAJ,IAAI,CAA0B;QAC1D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,IAAI,cAAc,CAAC,CAAC;QACjF,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QACjC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,aAAa,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,CAAiB;QAC7B,MAAM,OAAO,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACtE,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC1F,CAAC;CACD;AAED,uGAAuG;AACvG,MAAM,UAAU,0BAA0B,CAAC,IAA8B;IACxE,OAAO,IAAI,8BAA8B,CAAC,IAAI,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Reactivity — shared wire-validation primitives.
3
+ *
4
+ * The reactivity message codecs ({@link import("./wire.js")}, {@link import("./push-state.js")},
5
+ * {@link import("./backfill.js")}, {@link import("./resume.js")}) all decode untrusted JSON into
6
+ * validated V1 shapes with the same structural checks. Those primitives live here so each codec module
7
+ * narrows fields the same way (DRY) — every helper throws {@link CohortWireError} on a defect, matching
8
+ * the cohort-topic wire conventions (base64url byte fields, finite/integer numbers, `v: 1`).
9
+ */
10
+ /** Throw a {@link CohortWireError} with `message`. */
11
+ export declare function failWire(message: string): never;
12
+ /** Narrow `value` to a plain object (not null, not an array), or throw. */
13
+ export declare function asObject(value: unknown, what: string): Record<string, unknown>;
14
+ /** Require `obj.v === 1`. */
15
+ export declare function requireV1(obj: Record<string, unknown>, what: string): void;
16
+ /** Require `obj[key]` to be a string; returns it. */
17
+ export declare function reqString(obj: Record<string, unknown>, key: string, what: string): string;
18
+ /** Require `obj[key]` to be a boolean; returns it. */
19
+ export declare function reqBoolean(obj: Record<string, unknown>, key: string, what: string): boolean;
20
+ /** Require `obj[key]` to be a finite number; returns it. */
21
+ export declare function reqFiniteNumber(obj: Record<string, unknown>, key: string, what: string): number;
22
+ /** Require `obj[key]` to be an integer `>= min` (and `<= max` when supplied); returns it. */
23
+ export declare function reqIntInRange(obj: Record<string, unknown>, key: string, what: string, min: number, max?: number): number;
24
+ /** Assert a base64url string decodes cleanly; returns it unchanged. */
25
+ export declare function b64urlField(value: string, key: string, what: string): string;
26
+ /** Require `value` to be an array of strings; returns it (callers map each element through {@link b64urlField}). */
27
+ export declare function reqStringArray(value: unknown, key: string, what: string): string[];
28
+ //# sourceMappingURL=wire-validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire-validate.d.ts","sourceRoot":"","sources":["../../../src/reactivity/wire-validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,sDAAsD;AACtD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAE/C;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAK9E;AAED,6BAA6B;AAC7B,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAI1E;AAED,qDAAqD;AACrD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMzF;AAED,sDAAsD;AACtD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAM3F;AAED,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM/F;AAED,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAOxH;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAO5E;AAED,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKlF"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Reactivity — shared wire-validation primitives.
3
+ *
4
+ * The reactivity message codecs ({@link import("./wire.js")}, {@link import("./push-state.js")},
5
+ * {@link import("./backfill.js")}, {@link import("./resume.js")}) all decode untrusted JSON into
6
+ * validated V1 shapes with the same structural checks. Those primitives live here so each codec module
7
+ * narrows fields the same way (DRY) — every helper throws {@link CohortWireError} on a defect, matching
8
+ * the cohort-topic wire conventions (base64url byte fields, finite/integer numbers, `v: 1`).
9
+ */
10
+ import { b64urlToBytes } from "../cohort-topic/wire/codec.js";
11
+ import { CohortWireError } from "../cohort-topic/wire/validate.js";
12
+ /** Throw a {@link CohortWireError} with `message`. */
13
+ export function failWire(message) {
14
+ throw new CohortWireError(message);
15
+ }
16
+ /** Narrow `value` to a plain object (not null, not an array), or throw. */
17
+ export function asObject(value, what) {
18
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
19
+ failWire(`${what}: expected an object`);
20
+ }
21
+ return value;
22
+ }
23
+ /** Require `obj.v === 1`. */
24
+ export function requireV1(obj, what) {
25
+ if (obj["v"] !== 1) {
26
+ failWire(`${what}: expected v === 1, got ${JSON.stringify(obj["v"])}`);
27
+ }
28
+ }
29
+ /** Require `obj[key]` to be a string; returns it. */
30
+ export function reqString(obj, key, what) {
31
+ const value = obj[key];
32
+ if (typeof value !== "string") {
33
+ failWire(`${what}: field "${key}" must be a string`);
34
+ }
35
+ return value;
36
+ }
37
+ /** Require `obj[key]` to be a boolean; returns it. */
38
+ export function reqBoolean(obj, key, what) {
39
+ const value = obj[key];
40
+ if (typeof value !== "boolean") {
41
+ failWire(`${what}: field "${key}" must be a boolean`);
42
+ }
43
+ return value;
44
+ }
45
+ /** Require `obj[key]` to be a finite number; returns it. */
46
+ export function reqFiniteNumber(obj, key, what) {
47
+ const value = obj[key];
48
+ if (typeof value !== "number" || !Number.isFinite(value)) {
49
+ failWire(`${what}: field "${key}" must be a finite number`);
50
+ }
51
+ return value;
52
+ }
53
+ /** Require `obj[key]` to be an integer `>= min` (and `<= max` when supplied); returns it. */
54
+ export function reqIntInRange(obj, key, what, min, max) {
55
+ const value = reqFiniteNumber(obj, key, what);
56
+ if (!Number.isInteger(value) || value < min || (max !== undefined && value > max)) {
57
+ const bound = max === undefined ? `>= ${min}` : `in ${min}..${max}`;
58
+ failWire(`${what}: field "${key}" must be an integer ${bound}, got ${value}`);
59
+ }
60
+ return value;
61
+ }
62
+ /** Assert a base64url string decodes cleanly; returns it unchanged. */
63
+ export function b64urlField(value, key, what) {
64
+ try {
65
+ b64urlToBytes(value);
66
+ }
67
+ catch {
68
+ failWire(`${what}: field "${key}" is not valid base64url`);
69
+ }
70
+ return value;
71
+ }
72
+ /** Require `value` to be an array of strings; returns it (callers map each element through {@link b64urlField}). */
73
+ export function reqStringArray(value, key, what) {
74
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
75
+ failWire(`${what}: field "${key}" must be an array of strings`);
76
+ }
77
+ return value;
78
+ }
79
+ //# sourceMappingURL=wire-validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire-validate.js","sourceRoot":"","sources":["../../../src/reactivity/wire-validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnE,sDAAsD;AACtD,MAAM,UAAU,QAAQ,CAAC,OAAe;IACvC,MAAM,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,QAAQ,CAAC,KAAc,EAAE,IAAY;IACpD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzE,QAAQ,CAAC,GAAG,IAAI,sBAAsB,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,KAAgC,CAAC;AACzC,CAAC;AAED,6BAA6B;AAC7B,MAAM,UAAU,SAAS,CAAC,GAA4B,EAAE,IAAY;IACnE,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,QAAQ,CAAC,GAAG,IAAI,2BAA2B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;AACF,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,SAAS,CAAC,GAA4B,EAAE,GAAW,EAAE,IAAY;IAChF,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,QAAQ,CAAC,GAAG,IAAI,YAAY,GAAG,oBAAoB,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,UAAU,CAAC,GAA4B,EAAE,GAAW,EAAE,IAAY;IACjF,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,QAAQ,CAAC,GAAG,IAAI,YAAY,GAAG,qBAAqB,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,eAAe,CAAC,GAA4B,EAAE,GAAW,EAAE,IAAY;IACtF,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,QAAQ,CAAC,GAAG,IAAI,YAAY,GAAG,2BAA2B,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,aAAa,CAAC,GAA4B,EAAE,GAAW,EAAE,IAAY,EAAE,GAAW,EAAE,GAAY;IAC/G,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,GAAG,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC;QACnF,MAAM,KAAK,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,GAAG,EAAE,CAAC;QACpE,QAAQ,CAAC,GAAG,IAAI,YAAY,GAAG,wBAAwB,KAAK,SAAS,KAAK,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,GAAW,EAAE,IAAY;IACnE,IAAI,CAAC;QACJ,aAAa,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACR,QAAQ,CAAC,GAAG,IAAI,YAAY,GAAG,0BAA0B,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,oHAAoH;AACpH,MAAM,UAAU,cAAc,CAAC,KAAc,EAAE,GAAW,EAAE,IAAY;IACvE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,EAAE,CAAC;QAC/E,QAAQ,CAAC,GAAG,IAAI,YAAY,GAAG,+BAA+B,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,KAAiB,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Reactivity — V1 wire types, codecs, and per-message validation.
3
+ *
4
+ * Transcribed from `docs/reactivity.md` §Wire formats. Reactivity reuses the cohort-topic `RegisterV1`
5
+ * / `RenewV1` envelopes **unchanged**; the reactivity-specific shapes live in two places:
6
+ *
7
+ * 1. **Subscribe app payload** ({@link SubscribeAppPayloadV1}) carried opaquely inside
8
+ * `RegisterV1.appPayload`. Serialized to UTF-8 JSON bytes and handed to the cohort-topic
9
+ * {@link import("../cohort-topic/service.js").RegisterRequest}`.appPayload` slot, which base64url-encodes
10
+ * it on the wire. It is therefore **not** length-framed here — the cohort-topic `RegisterV1` frame
11
+ * wraps it. The subscribe RPC's authentication (peer-key signature over `correlationId` + `timestamp`)
12
+ * is the cohort-topic `RegisterV1` envelope's job, so the payload itself carries no signature.
13
+ *
14
+ * 2. **Notification** ({@link NotificationV1}) sent as a standalone RPC over the reactivity application
15
+ * protocol. It rides the same length-prefixed UTF-8 JSON framing as cohort-topic messages
16
+ * ({@link encodeCohortMessage}). Its `sig` is **bit-for-bit** the commit certificate's threshold
17
+ * signature — reactivity never re-signs (`docs/reactivity.md` §Notification origination).
18
+ *
19
+ * Conventions (matching the cohort-topic wire conventions): all JSON, byte fields base64url (no
20
+ * padding), unix-millisecond timestamps, per-message structural validation on decode, byte-fidelity
21
+ * round-trips (encode→decode→encode is stable). `collectionId` / `tailId` travel as the collection's
22
+ * base64url block ids verbatim. The `BackfillV1` / `ResumeV1` codecs belong to the sibling tickets.
23
+ */
24
+ /** Ceiling for an opaque subscribe app payload, guarding decode allocation. */
25
+ export declare const DEFAULT_MAX_SUBSCRIBE_PAYLOAD_BYTES: number;
26
+ /** A subscriber's registration payload (`RegisterV1.appPayload`, `kind == "reactivity"`). */
27
+ export interface SubscribeAppPayloadV1 {
28
+ kind: "reactivity";
29
+ /** Stable collection identity, base64url (the collection's id block id). */
30
+ collectionId: string;
31
+ /** Tail block id at registration time, base64url (the subscriber-side rotation detector). */
32
+ tailIdAtAttach: string;
33
+ /** Last revision the subscriber already holds; `0` for a fresh subscribe. */
34
+ lastKnownRev: number;
35
+ /** Max delta bytes the subscriber accepts; `0` declines delta payloads (Edge). */
36
+ deltaMaxBytes: number;
37
+ }
38
+ /** The tail cohort's rotation pre-announce, carried inside (and signed by) a {@link NotificationV1}. */
39
+ export interface RotationHintV1 {
40
+ /** New tail block id the topic anchor is rotating to, base64url. */
41
+ newTailId: string;
42
+ /** Revision at which the new tail becomes effective. */
43
+ effectiveAtRevision: number;
44
+ }
45
+ /** A signed change notification fanned out through the reactivity tree (`docs/reactivity.md` §Notification origination). */
46
+ export interface NotificationV1 {
47
+ v: 1;
48
+ /** Collection id, base64url. */
49
+ collectionId: string;
50
+ /** Tail block id the reactivity topic is anchored on, base64url. */
51
+ tailId: string;
52
+ /** Per-collection monotonic revision. */
53
+ revision: number;
54
+ /**
55
+ * The commit-vote **signed payload** `utf8(commitHash + ":approve")`, base64url — the exact bytes the
56
+ * threshold signature {@link sig} was computed over. A subscriber threshold-verifies {@link sig} over
57
+ * `b64urlToBytes(digest)`, so this reproduces the signed image against real Ed25519.
58
+ */
59
+ digest: string;
60
+ /** Optional bounded delta, base64url; omitted when `delta_max == 0` or the collection declines it. */
61
+ delta?: string;
62
+ /** Unix ms. */
63
+ timestamp: number;
64
+ /** Threshold signature, base64url — **= the commit cert**, never re-signed. */
65
+ sig: string;
66
+ /** PeerIds contributing to {@link sig}, base64url of the cohort member-id bytes. */
67
+ signers: string[];
68
+ /** Tail-rotation pre-announce, when this notification carries one (rotation ticket fills it). */
69
+ rotationHint?: RotationHintV1;
70
+ /**
71
+ * `true` iff this notification announces a durable **invalidation** (a reversal of a previously
72
+ * committed action proven invalid by dispute) rather than an ordinary commit
73
+ * (`docs/reactivity.md` §Notification origination, `docs/right-is-right.md` §Durable Invalidation).
74
+ * An invalidation is a committed collection change like any other and rides the same notification
75
+ * path, reusing the **invalidation's** commit cert as {@link sig} (never re-signed) — so it verifies
76
+ * against the tail cohort exactly like a commit notification. The flag is a hint that lets a
77
+ * subscriber react (drop derived results + resubmit) rather than merely refresh; a subscriber that
78
+ * ignores it still re-reads the authoritative reverted state. Omitted (falsy) on commit notifications.
79
+ */
80
+ invalidation?: boolean;
81
+ /**
82
+ * When {@link invalidation} is set, the original action id that was reversed
83
+ * (`InvalidationEntry.invalidatedActionId`). Lets a client dedup/coalesce the several cascade
84
+ * notifications a single dispute can produce by the action they reverse. Omitted on commits.
85
+ */
86
+ invalidatedActionId?: string;
87
+ }
88
+ /** Narrow an already-parsed value to {@link SubscribeAppPayloadV1}, throwing on any defect. */
89
+ export declare function validateSubscribeAppPayloadV1(value: unknown): SubscribeAppPayloadV1;
90
+ /** Serialize a {@link SubscribeAppPayloadV1} to the opaque UTF-8 JSON bytes for `RegisterV1.appPayload`. */
91
+ export declare function encodeSubscribeAppPayload(payload: SubscribeAppPayloadV1): Uint8Array;
92
+ /** Decode opaque `RegisterV1.appPayload` bytes back to a validated {@link SubscribeAppPayloadV1}. */
93
+ export declare function decodeSubscribeAppPayload(bytes: Uint8Array, maxBytes?: number): SubscribeAppPayloadV1;
94
+ /** Narrow an already-parsed value to {@link NotificationV1}, throwing on any defect. */
95
+ export declare function validateNotificationV1(value: unknown): NotificationV1;
96
+ /** Validate an array of {@link NotificationV1} (the `entries`/`recentEntries` carried in backfill/resume replies). */
97
+ export declare function validateNotificationArray(value: unknown, what: string): NotificationV1[];
98
+ /** Encode a {@link NotificationV1} as a length-prefixed UTF-8 JSON frame. */
99
+ export declare function encodeNotificationV1(msg: NotificationV1, maxMessageBytes?: number): Uint8Array;
100
+ /** Decode a length-prefixed {@link NotificationV1} frame. */
101
+ export declare function decodeNotificationV1(bytes: Uint8Array, maxMessageBytes?: number): NotificationV1;
102
+ //# sourceMappingURL=wire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../../src/reactivity/wire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAsBH,+EAA+E;AAC/E,eAAO,MAAM,mCAAmC,QAAY,CAAC;AAI7D,6FAA6F;AAC7F,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,YAAY,CAAC;IACnB,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,cAAc,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,aAAa,EAAE,MAAM,CAAC;CACtB;AAID,wGAAwG;AACxG,MAAM,WAAW,cAAc;IAC9B,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,mBAAmB,EAAE,MAAM,CAAC;CAC5B;AAED,4HAA4H;AAC5H,MAAM,WAAW,cAAc;IAC9B,CAAC,EAAE,CAAC,CAAC;IACL,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,sGAAsG;IACtG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,GAAG,EAAE,MAAM,CAAC;IACZ,oFAAoF;IACpF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,iGAAiG;IACjG,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAgBD,+FAA+F;AAC/F,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,qBAAqB,CAanF;AAED,4GAA4G;AAC5G,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,CAEpF;AAED,qGAAqG;AACrG,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,GAAE,MAA4C,GAAG,qBAAqB,CAE1I;AAsBD,wFAAwF;AACxF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CA4BrE;AAED,sHAAsH;AACtH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAKxF;AAED,6EAA6E;AAC7E,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,cAAc,EAAE,eAAe,GAAE,MAAkC,GAAG,UAAU,CAEzH;AAED,6DAA6D;AAC7D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,cAAc,CAEhG"}