@optimystic/db-core 0.13.5 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 @@
1
+ {"version":3,"file":"threshold.js","sourceRoot":"","sources":["../../../../src/cohort-topic/sig/threshold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,wEAAwE;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAanC,MAAM,kBAAkB;IACM;IAAiD;IAA9E,YAA6B,MAA8B,EAAmB,OAAe;QAAhE,WAAM,GAAN,MAAM,CAAwB;QAAmB,YAAO,GAAP,OAAO,CAAQ;IAAG,CAAC;IAEjG,aAAa,CAAC,OAAmB;QAChC,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;IAED,eAAe,CAAC,OAAmB,EAAE,GAAe,EAAE,OAA8B,EAAE,IAAsB,EAAE,OAAe;QAC5H,IAAI,OAAO,CAAC,MAAM,GAAG,OAAO,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACd,CAAC;QACD,kFAAkF;QAClF,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnB,OAAO,KAAK,CAAC,CAAC,0DAA0D;YACzE,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,OAAO,KAAK,CAAC,CAAC,gDAAgD;YAC/D,CAAC;QACF,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;CACD;AAED,sFAAsF;AACtF,MAAM,UAAU,kBAAkB,CAAC,MAA8B,EAAE,UAAkB,gBAAgB;IACpG,OAAO,IAAI,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Cohort-topic substrate — tier ladder (T0–T3) and node profiles (Edge / Core).
3
+ *
4
+ * Transcribed from `docs/cohort-topic.md` §Tier ladder. This module encodes only the **static**
5
+ * tier classes, the Edge/Core profiles, and the per-node override surface. The decline-policy
6
+ * *behavior* (T0 never declined while serving, T3 declined freely) and the Edge runtime overrides
7
+ * (`ttl = 60s`, `ping_interval = 20s`, sticky-cached backups) are willingness/TTL concerns owned by
8
+ * later tickets — only the profile *flags* (which tiers a node is willing to forward) live here.
9
+ */
10
+ /**
11
+ * System-wide capacity tier, in priority order (T0 essential … T3 luxury).
12
+ *
13
+ * Modeled as a frozen const-object + value-union type rather than a TS `enum`: db-core's test
14
+ * runner uses Node's native type-stripping, which rejects `enum` (non-erasable syntax). The object
15
+ * carries the named members (`Tier.T0`), the type alias carries the value union (`0 | 1 | 2 | 3`).
16
+ *
17
+ * - **T0 — essential**: transaction commit, block production, threshold-sig contribution.
18
+ * - **T1 — correctness-supporting**: chain serving, replay-window storage, partition heal.
19
+ * - **T2 — functional**: matchmaking/voting directories, capability discovery, capacity gossip.
20
+ * - **T3 — luxury**: reactivity push forwarding, anticipatory warm-up, optional delta payloads.
21
+ */
22
+ export declare const Tier: {
23
+ readonly T0: 0;
24
+ readonly T1: 1;
25
+ readonly T2: 2;
26
+ readonly T3: 3;
27
+ };
28
+ export type Tier = (typeof Tier)[keyof typeof Tier];
29
+ /** All four tiers, ascending — useful for iteration and override validation. */
30
+ export declare const ALL_TIERS: readonly Tier[];
31
+ /**
32
+ * A node's static tier classification. `willingTiers` is the set of tiers this node will take on
33
+ * *forwarder* roles for; cohort assembly under FRET is tier-blind, so this is the per-node gate the
34
+ * willingness check consults. Edge: `{T0, T1}`; Core: `{T0, T1, T2, T3}` (operator-narrowable).
35
+ */
36
+ export interface NodeProfile {
37
+ readonly kind: "edge" | "core";
38
+ readonly willingTiers: ReadonlySet<Tier>;
39
+ }
40
+ /** Per-node operator override surface. Currently the willing-tier set; widened by later tickets. */
41
+ export interface NodeProfileOverrides {
42
+ /**
43
+ * Restrict the willing-tier set. Tiers outside the profile's base set are ignored (Edge can never
44
+ * be widened to T2/T3 via override — that is a hardware/policy class, not a knob).
45
+ */
46
+ willingTiers?: Iterable<Tier>;
47
+ }
48
+ /**
49
+ * Edge profile (mobile / browser / IoT): forwards T0 + T1 only. T2/T3 willingness is permanently
50
+ * off and an operator override cannot turn it on. An override may further narrow (e.g. to `{T0}`).
51
+ */
52
+ export declare function edgeProfile(overrides?: NodeProfileOverrides): NodeProfile;
53
+ /**
54
+ * Core profile (servers / fixed infrastructure): forwards T0–T3 by default. An operator override may
55
+ * restrict it to a subset (e.g. `{T0, T1, T2}` to shed reactivity-push duty).
56
+ */
57
+ export declare function coreProfile(overrides?: NodeProfileOverrides): NodeProfile;
58
+ //# sourceMappingURL=tiers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tiers.d.ts","sourceRoot":"","sources":["../../../src/cohort-topic/tiers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,IAAI;;;;;CAA0C,CAAC;AAC5D,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,OAAO,IAAI,CAAC,CAAC;AAEpD,gFAAgF;AAChF,eAAO,MAAM,SAAS,EAAE,SAAS,IAAI,EAAyC,CAAC;AAE/E;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;CACzC;AAED,oGAAoG;AACpG,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,YAAY,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;CAC9B;AAcD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,CAAC,EAAE,oBAAoB,GAAG,WAAW,CAEzE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,CAAC,EAAE,oBAAoB,GAAG,WAAW,CAEzE"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Cohort-topic substrate — tier ladder (T0–T3) and node profiles (Edge / Core).
3
+ *
4
+ * Transcribed from `docs/cohort-topic.md` §Tier ladder. This module encodes only the **static**
5
+ * tier classes, the Edge/Core profiles, and the per-node override surface. The decline-policy
6
+ * *behavior* (T0 never declined while serving, T3 declined freely) and the Edge runtime overrides
7
+ * (`ttl = 60s`, `ping_interval = 20s`, sticky-cached backups) are willingness/TTL concerns owned by
8
+ * later tickets — only the profile *flags* (which tiers a node is willing to forward) live here.
9
+ */
10
+ /**
11
+ * System-wide capacity tier, in priority order (T0 essential … T3 luxury).
12
+ *
13
+ * Modeled as a frozen const-object + value-union type rather than a TS `enum`: db-core's test
14
+ * runner uses Node's native type-stripping, which rejects `enum` (non-erasable syntax). The object
15
+ * carries the named members (`Tier.T0`), the type alias carries the value union (`0 | 1 | 2 | 3`).
16
+ *
17
+ * - **T0 — essential**: transaction commit, block production, threshold-sig contribution.
18
+ * - **T1 — correctness-supporting**: chain serving, replay-window storage, partition heal.
19
+ * - **T2 — functional**: matchmaking/voting directories, capability discovery, capacity gossip.
20
+ * - **T3 — luxury**: reactivity push forwarding, anticipatory warm-up, optional delta payloads.
21
+ */
22
+ export const Tier = { T0: 0, T1: 1, T2: 2, T3: 3 };
23
+ /** All four tiers, ascending — useful for iteration and override validation. */
24
+ export const ALL_TIERS = [Tier.T0, Tier.T1, Tier.T2, Tier.T3];
25
+ const EDGE_BASE_TIERS = [Tier.T0, Tier.T1];
26
+ const CORE_BASE_TIERS = ALL_TIERS;
27
+ /** Intersect a requested override set with the profile's base tiers (override can only narrow). */
28
+ function resolveWillingTiers(base, overrides) {
29
+ if (!overrides?.willingTiers) {
30
+ return new Set(base);
31
+ }
32
+ const requested = new Set(overrides.willingTiers);
33
+ return new Set(base.filter((t) => requested.has(t)));
34
+ }
35
+ /**
36
+ * Edge profile (mobile / browser / IoT): forwards T0 + T1 only. T2/T3 willingness is permanently
37
+ * off and an operator override cannot turn it on. An override may further narrow (e.g. to `{T0}`).
38
+ */
39
+ export function edgeProfile(overrides) {
40
+ return { kind: "edge", willingTiers: resolveWillingTiers(EDGE_BASE_TIERS, overrides) };
41
+ }
42
+ /**
43
+ * Core profile (servers / fixed infrastructure): forwards T0–T3 by default. An operator override may
44
+ * restrict it to a subset (e.g. `{T0, T1, T2}` to shed reactivity-push duty).
45
+ */
46
+ export function coreProfile(overrides) {
47
+ return { kind: "core", willingTiers: resolveWillingTiers(CORE_BASE_TIERS, overrides) };
48
+ }
49
+ //# sourceMappingURL=tiers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tiers.js","sourceRoot":"","sources":["../../../src/cohort-topic/tiers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAW,CAAC;AAG5D,gFAAgF;AAChF,MAAM,CAAC,MAAM,SAAS,GAAoB,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;AAqB/E,MAAM,eAAe,GAAoB,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;AAC5D,MAAM,eAAe,GAAoB,SAAS,CAAC;AAEnD,mGAAmG;AACnG,SAAS,mBAAmB,CAAC,IAAqB,EAAE,SAAgC;IACnF,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,CAAC;QAC9B,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAClD,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,SAAgC;IAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,mBAAmB,CAAC,eAAe,EAAE,SAAS,CAAC,EAAE,CAAC;AACxF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,SAAgC;IAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,mBAAmB,CAAC,eAAe,EAAE,SAAS,CAAC,EAAE,CAAC;AACxF,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Cohort-topic substrate — topic-traffic signal.
3
+ *
4
+ * Transcribed from `docs/cohort-topic.md` §Topic traffic signal. A cohort tracks per-topic flow
5
+ * rates alongside the stock `directParticipants` count and returns them on registration replies so
6
+ * applications can decide whether the current tier is dense enough to settle on.
7
+ *
8
+ * Shape (`TopicTrafficV1` from the wire ticket):
9
+ * - `arrivalsPerMin` — **combines** fresh registrations and renewals into one scalar (the seeker
10
+ * uses renewals as a proxy for active matchable supply); the caller invokes {@link recordArrival}
11
+ * for both.
12
+ * - `queriesPerMin` — application-level query rate.
13
+ * - counts are **exact integers** over `windowSeconds` (default 60), *not* log-bucketed like the
14
+ * load barometer — the consumer-side matchmaking formulas are numeric.
15
+ *
16
+ * Pipeline: each member counts arrivals/queries locally ({@link recordArrival} / {@link recordQuery})
17
+ * over a sliding window; {@link TrafficCounters.publish} freezes the windowed counts into the
18
+ * member's gossiped per-topic summary each gossip round; {@link TrafficCounters.snapshot} returns the
19
+ * **gossip-derived** view (own last-published summary + siblings' last-gossiped summaries from the
20
+ * {@link CohortView}), so the reply lags by at most one round and never recomputes from raw counters
21
+ * at reply time.
22
+ *
23
+ * Resolved open question (GROUNDING): the signal is returned **only** on `accepted` and `promoted`
24
+ * replies (see {@link attachTopicTraffic}); a participant getting `Promoted(d+1)` still receives the
25
+ * outgoing cohort's traffic so it can estimate whether the redirect target is hot.
26
+ *
27
+ * Counters reset to zero on `cohortEpoch` change ({@link TrafficCounters.reset}); the first round
28
+ * after a rotation may under-report, and consumers tolerate a single zero reading.
29
+ */
30
+ import type { CohortView } from "./gossip/view.js";
31
+ import type { RegistrationStore } from "./registration/types.js";
32
+ import type { CohortTopicSummary, RegisterReplyV1, TopicTrafficV1 } from "./wire/types.js";
33
+ /** Default observation window for the rate fields (seconds). */
34
+ export declare const DEFAULT_TRAFFIC_WINDOW_SECONDS = 60;
35
+ /** Frozen per-topic counts the member last published to gossip. */
36
+ interface PublishedTopic {
37
+ readonly arrivals: number;
38
+ readonly queries: number;
39
+ }
40
+ /** Per-topic traffic counters with a gossip-derived snapshot. */
41
+ export interface TrafficCounters {
42
+ /** Record a fresh registration **or** a renewal for `topicId` at `now` (combined arrivals). */
43
+ recordArrival(topicId: Uint8Array, now: number): void;
44
+ /** Record an application-level query against `topicId` at `now`. */
45
+ recordQuery(topicId: Uint8Array, now: number): void;
46
+ /**
47
+ * Freeze the current windowed counts into the member's gossiped summary (call once per gossip
48
+ * round, at `now`). The frozen values are what {@link snapshot} and the gossip frame read.
49
+ */
50
+ publish(topicId: Uint8Array, now: number): PublishedTopic;
51
+ /** Own most-recent published `(arrivals, queries)` for `topicId`, or zeros if never published. */
52
+ published(topicId: Uint8Array): PublishedTopic;
53
+ /**
54
+ * Gossip-derived traffic for `topicId`: own last-published counts plus siblings' last-gossiped
55
+ * summaries (exact-integer sums), with `directParticipants` from the replicated store. Lags ≤ one
56
+ * round; never recomputes from raw counters.
57
+ */
58
+ snapshot(topicId: Uint8Array): TopicTrafficV1;
59
+ /** Reset all counters to zero (call on `cohortEpoch` change). */
60
+ reset(): void;
61
+ }
62
+ export interface TrafficCountersDeps {
63
+ /** Merged per-member gossip view — siblings' last-gossiped per-topic summaries. */
64
+ view: CohortView;
65
+ /** Replicated registration store — supplies the cohort-wide `directParticipants` stock count. */
66
+ store: Pick<RegistrationStore, "directParticipants">;
67
+ /** This member's own id, base64url — excluded from the sibling summary scan (counted via own published). */
68
+ selfMember: string;
69
+ /** Observation window (seconds). Default {@link DEFAULT_TRAFFIC_WINDOW_SECONDS}. */
70
+ windowSeconds?: number;
71
+ /** Tier-(d+1) cohort count for a topic (0 if not promoted); the promotion ticket owns this. */
72
+ childCohortCount?: (topicId: Uint8Array) => number;
73
+ }
74
+ /** Construct empty {@link TrafficCounters}. */
75
+ export declare function createTrafficCounters(deps: TrafficCountersDeps): TrafficCounters;
76
+ /**
77
+ * Attach the topic-traffic signal to a reply **only** when the result is `accepted` or `promoted`
78
+ * (GROUNDING-resolved: absent on `no_state`, `unwilling_member`, `unwilling_cohort`). Mutates and
79
+ * returns `reply`. A no-op for non-traffic-bearing results, so callers can pipe every reply through.
80
+ */
81
+ export declare function attachTopicTraffic(reply: RegisterReplyV1, traffic: TopicTrafficV1): RegisterReplyV1;
82
+ /** The own published counts as a `CohortTopicSummary` for the gossip frame. Callers supply tier/promotion fields. */
83
+ export declare function toCohortTopicSummary(topicId: Uint8Array, published: PublishedTopic, fields: {
84
+ tier: number;
85
+ directParticipants: number;
86
+ promoted: boolean;
87
+ childCohortCount: number;
88
+ }): CohortTopicSummary;
89
+ export {};
90
+ //# sourceMappingURL=traffic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traffic.d.ts","sourceRoot":"","sources":["../../../src/cohort-topic/traffic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE3F,gEAAgE;AAChE,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAEjD,mEAAmE;AACnE,UAAU,cAAc;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAQD,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC/B,+FAA+F;IAC/F,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACtD,oEAAoE;IACpE,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACpD;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC;IAC1D,kGAAkG;IAClG,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,cAAc,CAAC;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,cAAc,CAAC;IAC9C,iEAAiE;IACjE,KAAK,IAAI,IAAI,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IACnC,mFAAmF;IACnF,IAAI,EAAE,UAAU,CAAC;IACjB,iGAAiG;IACjG,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;IACrD,4GAA4G;IAC5G,UAAU,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+FAA+F;IAC/F,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,MAAM,CAAC;CACnD;AA6FD,+CAA+C;AAC/C,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,GAAG,eAAe,CAEhF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,GAAG,eAAe,CAKnG;AAED,qHAAqH;AACrH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,UAAU,EACnB,SAAS,EAAE,cAAc,EACzB,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GAC/F,kBAAkB,CAUpB"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Cohort-topic substrate — topic-traffic signal.
3
+ *
4
+ * Transcribed from `docs/cohort-topic.md` §Topic traffic signal. A cohort tracks per-topic flow
5
+ * rates alongside the stock `directParticipants` count and returns them on registration replies so
6
+ * applications can decide whether the current tier is dense enough to settle on.
7
+ *
8
+ * Shape (`TopicTrafficV1` from the wire ticket):
9
+ * - `arrivalsPerMin` — **combines** fresh registrations and renewals into one scalar (the seeker
10
+ * uses renewals as a proxy for active matchable supply); the caller invokes {@link recordArrival}
11
+ * for both.
12
+ * - `queriesPerMin` — application-level query rate.
13
+ * - counts are **exact integers** over `windowSeconds` (default 60), *not* log-bucketed like the
14
+ * load barometer — the consumer-side matchmaking formulas are numeric.
15
+ *
16
+ * Pipeline: each member counts arrivals/queries locally ({@link recordArrival} / {@link recordQuery})
17
+ * over a sliding window; {@link TrafficCounters.publish} freezes the windowed counts into the
18
+ * member's gossiped per-topic summary each gossip round; {@link TrafficCounters.snapshot} returns the
19
+ * **gossip-derived** view (own last-published summary + siblings' last-gossiped summaries from the
20
+ * {@link CohortView}), so the reply lags by at most one round and never recomputes from raw counters
21
+ * at reply time.
22
+ *
23
+ * Resolved open question (GROUNDING): the signal is returned **only** on `accepted` and `promoted`
24
+ * replies (see {@link attachTopicTraffic}); a participant getting `Promoted(d+1)` still receives the
25
+ * outgoing cohort's traffic so it can estimate whether the redirect target is hot.
26
+ *
27
+ * Counters reset to zero on `cohortEpoch` change ({@link TrafficCounters.reset}); the first round
28
+ * after a rotation may under-report, and consumers tolerate a single zero reading.
29
+ */
30
+ import { bytesKey } from "./registration/bytes.js";
31
+ import { bytesToB64url } from "./wire/codec.js";
32
+ /** Default observation window for the rate fields (seconds). */
33
+ export const DEFAULT_TRAFFIC_WINDOW_SECONDS = 60;
34
+ class WindowedTrafficCounters {
35
+ deps;
36
+ windows = new Map();
37
+ lastPublished = new Map();
38
+ windowMs;
39
+ constructor(deps) {
40
+ this.deps = deps;
41
+ const ws = deps.windowSeconds ?? DEFAULT_TRAFFIC_WINDOW_SECONDS;
42
+ if (!(ws > 0)) {
43
+ throw new RangeError(`windowSeconds must be > 0, got ${ws}`);
44
+ }
45
+ this.windowMs = ws * 1000;
46
+ }
47
+ recordArrival(topicId, now) {
48
+ this.windowFor(topicId).arrivals.push(now);
49
+ }
50
+ recordQuery(topicId, now) {
51
+ this.windowFor(topicId).queries.push(now);
52
+ }
53
+ publish(topicId, now) {
54
+ const w = this.windows.get(bytesKey(topicId));
55
+ const frozen = {
56
+ arrivals: w === undefined ? 0 : countWithin(w.arrivals, now, this.windowMs),
57
+ queries: w === undefined ? 0 : countWithin(w.queries, now, this.windowMs),
58
+ };
59
+ this.lastPublished.set(bytesKey(topicId), frozen);
60
+ return frozen;
61
+ }
62
+ published(topicId) {
63
+ return this.lastPublished.get(bytesKey(topicId)) ?? { arrivals: 0, queries: 0 };
64
+ }
65
+ snapshot(topicId) {
66
+ const topicB64 = bytesToB64url(topicId);
67
+ const own = this.published(topicId);
68
+ let arrivals = own.arrivals;
69
+ let queries = own.queries;
70
+ let childCohortCount = 0;
71
+ for (const [member, contribution] of this.deps.view.all()) {
72
+ if (member === this.deps.selfMember)
73
+ continue; // own contribution comes from lastPublished
74
+ const summary = contribution.topicSummaries.find((s) => s.topicId === topicB64);
75
+ if (summary === undefined)
76
+ continue;
77
+ arrivals += summary.arrivalsPerMin;
78
+ queries += summary.queriesPerMin;
79
+ if (summary.childCohortCount > childCohortCount) {
80
+ childCohortCount = summary.childCohortCount;
81
+ }
82
+ }
83
+ const childOverride = this.deps.childCohortCount?.(topicId);
84
+ return {
85
+ windowSeconds: this.windowMs / 1000,
86
+ arrivalsPerMin: arrivals,
87
+ queriesPerMin: queries,
88
+ directParticipants: this.deps.store.directParticipants(topicId),
89
+ childCohortCount: childOverride ?? childCohortCount,
90
+ };
91
+ }
92
+ reset() {
93
+ this.windows.clear();
94
+ this.lastPublished.clear();
95
+ }
96
+ windowFor(topicId) {
97
+ const key = bytesKey(topicId);
98
+ let w = this.windows.get(key);
99
+ if (w === undefined) {
100
+ w = { arrivals: [], queries: [] };
101
+ this.windows.set(key, w);
102
+ }
103
+ return w;
104
+ }
105
+ }
106
+ /** Count timestamps within `[now - windowMs, now]`, pruning anything older from `events` in place. */
107
+ function countWithin(events, now, windowMs) {
108
+ const cutoff = now - windowMs;
109
+ // Events accumulate in arrival order; drop the stale prefix so the array stays bounded.
110
+ let drop = 0;
111
+ while (drop < events.length && events[drop] < cutoff) {
112
+ drop++;
113
+ }
114
+ if (drop > 0) {
115
+ events.splice(0, drop);
116
+ }
117
+ return events.length;
118
+ }
119
+ /** Construct empty {@link TrafficCounters}. */
120
+ export function createTrafficCounters(deps) {
121
+ return new WindowedTrafficCounters(deps);
122
+ }
123
+ /**
124
+ * Attach the topic-traffic signal to a reply **only** when the result is `accepted` or `promoted`
125
+ * (GROUNDING-resolved: absent on `no_state`, `unwilling_member`, `unwilling_cohort`). Mutates and
126
+ * returns `reply`. A no-op for non-traffic-bearing results, so callers can pipe every reply through.
127
+ */
128
+ export function attachTopicTraffic(reply, traffic) {
129
+ if (reply.result === "accepted" || reply.result === "promoted") {
130
+ reply.topicTraffic = traffic;
131
+ }
132
+ return reply;
133
+ }
134
+ /** The own published counts as a `CohortTopicSummary` for the gossip frame. Callers supply tier/promotion fields. */
135
+ export function toCohortTopicSummary(topicId, published, fields) {
136
+ return {
137
+ topicId: bytesToB64url(topicId),
138
+ tier: fields.tier,
139
+ directParticipants: fields.directParticipants,
140
+ arrivalsPerMin: published.arrivals,
141
+ queriesPerMin: published.queries,
142
+ promoted: fields.promoted,
143
+ childCohortCount: fields.childCohortCount,
144
+ };
145
+ }
146
+ //# sourceMappingURL=traffic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traffic.js","sourceRoot":"","sources":["../../../src/cohort-topic/traffic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Cohort-topic substrate — walk-toward-root lookup / registration.
3
+ *
4
+ * Transcribed from `docs/cohort-topic.md` §Tree growth and lookup (§Lookup loop) and folded back
5
+ * from the simulator-validated `packages/substrate-simulator/src/walk.ts`. A participant resolves a
6
+ * topic by walking **toward the root** from `d_max`, probing one tier coordinate per RPC. The walk's
7
+ * single-direction discipline is the anti-flood backbone: it only ever moves inward (toward the root)
8
+ * on `NoState`, and the *only* outward move is following an explicit `Promoted` redirect.
9
+ *
10
+ * Reply handling (§Lookup):
11
+ * - **`accepted`** → done; return the reply (carries `primary`/`backups`/`cohortEpoch` to cache).
12
+ * - **`no_state`** at tier `d` → step one tier toward the root (`d − 1`); no traffic signal. At the
13
+ * root (`d − 1 < 0`) re-issue once at tier 0 with `bootstrap: true` (cold-start request).
14
+ * - **`promoted(targetTier)`** → recompute `coord_targetTier(self, topicId)` and register there — the
15
+ * one outward move, taken only on this explicit redirect.
16
+ * - **`unwilling_member(candidates)`** → retry the **same** coord at a named alternative member
17
+ * (spatial move within the cohort), via a direct dial.
18
+ * - **`unwilling_cohort(retryAfter)`** → back off in **time**; the walk terminates with
19
+ * {@link RetryLaterOutcome} and the caller restarts a fresh {@link WalkEngine.register} after
20
+ * `afterMs` — which begins again at `d_max`, decorrelating retries across the ring (§Anti-flood
21
+ * claim 4: never re-hit the declined coord immediately).
22
+ *
23
+ * This module is FRET-free: it drives the {@link ITopicRouter} port (db-p2p binds it to FRET's
24
+ * `RouteAndMaybeAct` / direct dial) and the {@link TierAddressing} math, and delegates building +
25
+ * signing the {@link RegisterV1} to the injected {@link RegisterMessageFactory} (participant identity
26
+ * and crypto live there, not here).
27
+ */
28
+ import type { ITopicRouter } from "./ports.js";
29
+ import type { TierAddressing } from "./addressing.js";
30
+ import type { DMaxComputer } from "./dmax.js";
31
+ import type { RegisterReplyV1, RegisterV1 } from "./wire/types.js";
32
+ /** The walk landed: the cohort accepted the registration. `reply` carries the cohort cache fields. */
33
+ export interface AcceptedWalkOutcome {
34
+ readonly kind: "accepted";
35
+ readonly reply: RegisterReplyV1;
36
+ }
37
+ /**
38
+ * The walk hit a `Promoted` redirect and the engine was configured **not** to follow it
39
+ * ({@link WalkConfig.followPromoted} `= false`): the caller recomputes `coord_targetTier` and
40
+ * registers there itself. With the default (`followPromoted = true`) the engine follows the redirect
41
+ * internally and this outcome never surfaces.
42
+ */
43
+ export interface PromotedWalkOutcome {
44
+ readonly kind: "promoted";
45
+ readonly targetTier: number;
46
+ }
47
+ /**
48
+ * The walk backed off in time (`unwilling_cohort`, exhausted sibling retries, a failed cold-start, or
49
+ * the safety step cap). The caller waits `afterMs` then calls {@link WalkEngine.register} again, which
50
+ * restarts at `d_max`.
51
+ */
52
+ export interface RetryLaterOutcome {
53
+ readonly kind: "retry_later";
54
+ readonly afterMs: number;
55
+ }
56
+ export type WalkOutcome = AcceptedWalkOutcome | PromotedWalkOutcome | RetryLaterOutcome;
57
+ /** Builds (and signs) the {@link RegisterV1} for one probe; owns participant identity + crypto. */
58
+ export interface RegisterMessageFactory {
59
+ /**
60
+ * Produce a signed `RegisterV1` for this participant at walk position `treeTier`. `bootstrap` is
61
+ * set only on the root cold-start re-issue. `appPayload` is the opaque application slot. On the
62
+ * bootstrap re-issue the factory may additionally mint and attach the signed `bootstrapEvidence`
63
+ * envelope (§Anti-DoS) via the injected builder seam before signing — keyed off `bootstrap`, so no
64
+ * extra build parameter is needed (the walk decides `bootstrap` internally, not the application).
65
+ */
66
+ build(params: {
67
+ topicId: Uint8Array;
68
+ tier: number;
69
+ treeTier: number;
70
+ bootstrap: boolean;
71
+ /** Read-only lookup probe: the factory stamps `RegisterV1.probe` and never mints bootstrap evidence. */
72
+ probe: boolean;
73
+ appPayload?: Uint8Array;
74
+ }): Promise<RegisterV1>;
75
+ }
76
+ export interface WalkConfig {
77
+ /** Cohort size requested from the router (`wantK`). Default 16. */
78
+ wantK?: number;
79
+ /** Threshold signers requested from the router (`minSigs = k − x`). Default 14. */
80
+ minSigs?: number;
81
+ /** Max `unwilling_member` sibling retries at one coord before treating it as a cohort decline. Default `wantK`. */
82
+ maxMemberRetries?: number;
83
+ /**
84
+ * Whether to follow a `Promoted` redirect internally (recompute coord + continue) or surface it as
85
+ * a {@link PromotedWalkOutcome} for the caller to drive. Default `true` (self-contained walk).
86
+ */
87
+ followPromoted?: boolean;
88
+ /**
89
+ * Hard cap on probe RPCs in one walk — a safety valve against pathological oscillation between an
90
+ * inward `NoState` step and an outward `Promoted` redirect in a malformed tree. Default scales with
91
+ * `d_max`. Exceeding it yields a {@link RetryLaterOutcome}.
92
+ */
93
+ maxSteps?: number;
94
+ /** `max_message_bytes` ceiling for the encoded register frame. Defaults to the codec default. */
95
+ maxMessageBytes?: number;
96
+ }
97
+ export interface WalkEngineDeps {
98
+ router: ITopicRouter;
99
+ addressing: TierAddressing;
100
+ /** Computes the walk start tier `d_max` from the current network-size estimate. */
101
+ dmax: DMaxComputer;
102
+ /** This participant's peer id — the `P` in `coord_d(P, topicId)`. */
103
+ self: Uint8Array;
104
+ /** Builds + signs the per-probe `RegisterV1`. */
105
+ factory: RegisterMessageFactory;
106
+ config?: WalkConfig;
107
+ }
108
+ /** Drives a participant's walk-toward-root registration over the injected router + addressing. */
109
+ export interface WalkEngine {
110
+ /**
111
+ * Walk from `d_max` toward the root registering for `topicId` at op `tier`, following `Promoted`
112
+ * redirects outward. Resolves with the terminal {@link WalkOutcome}. With `opts.probe` the walk is a
113
+ * **read-only lookup**: identical routing discipline, but the terminal cohort classifies rather than
114
+ * admits and the root `no_state` branch backs off instead of issuing a `bootstrap: true` cold-start
115
+ * (a probe never instantiates a cold root).
116
+ */
117
+ register(topicId: Uint8Array, tier: number, appPayload?: Uint8Array, opts?: {
118
+ probe?: boolean;
119
+ }): Promise<WalkOutcome>;
120
+ }
121
+ /** Build a {@link WalkEngine} over the injected router, addressing, `d_max`, and message factory. */
122
+ export declare function createWalkEngine(deps: WalkEngineDeps): WalkEngine;
123
+ //# sourceMappingURL=walk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../../../src/cohort-topic/walk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAW,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG9C,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEnE,sGAAsG;AACtG,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;CAChC;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,WAAW,GAAG,mBAAmB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAExF,mGAAmG;AACnG,MAAM,WAAW,sBAAsB;IACtC;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,EAAE;QACb,OAAO,EAAE,UAAU,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,OAAO,CAAC;QACnB,wGAAwG;QACxG,KAAK,EAAE,OAAO,CAAC;QACf,UAAU,CAAC,EAAE,UAAU,CAAC;KACxB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IAC1B,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mHAAmH;IACnH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iGAAiG;IACjG,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,cAAc,CAAC;IAC3B,mFAAmF;IACnF,IAAI,EAAE,YAAY,CAAC;IACnB,qEAAqE;IACrE,IAAI,EAAE,UAAU,CAAC;IACjB,iDAAiD;IACjD,OAAO,EAAE,sBAAsB,CAAC;IAChC,MAAM,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,kGAAkG;AAClG,MAAM,WAAW,UAAU;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACvH;AA2HD,qGAAqG;AACrG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAEjE"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Cohort-topic substrate — walk-toward-root lookup / registration.
3
+ *
4
+ * Transcribed from `docs/cohort-topic.md` §Tree growth and lookup (§Lookup loop) and folded back
5
+ * from the simulator-validated `packages/substrate-simulator/src/walk.ts`. A participant resolves a
6
+ * topic by walking **toward the root** from `d_max`, probing one tier coordinate per RPC. The walk's
7
+ * single-direction discipline is the anti-flood backbone: it only ever moves inward (toward the root)
8
+ * on `NoState`, and the *only* outward move is following an explicit `Promoted` redirect.
9
+ *
10
+ * Reply handling (§Lookup):
11
+ * - **`accepted`** → done; return the reply (carries `primary`/`backups`/`cohortEpoch` to cache).
12
+ * - **`no_state`** at tier `d` → step one tier toward the root (`d − 1`); no traffic signal. At the
13
+ * root (`d − 1 < 0`) re-issue once at tier 0 with `bootstrap: true` (cold-start request).
14
+ * - **`promoted(targetTier)`** → recompute `coord_targetTier(self, topicId)` and register there — the
15
+ * one outward move, taken only on this explicit redirect.
16
+ * - **`unwilling_member(candidates)`** → retry the **same** coord at a named alternative member
17
+ * (spatial move within the cohort), via a direct dial.
18
+ * - **`unwilling_cohort(retryAfter)`** → back off in **time**; the walk terminates with
19
+ * {@link RetryLaterOutcome} and the caller restarts a fresh {@link WalkEngine.register} after
20
+ * `afterMs` — which begins again at `d_max`, decorrelating retries across the ring (§Anti-flood
21
+ * claim 4: never re-hit the declined coord immediately).
22
+ *
23
+ * This module is FRET-free: it drives the {@link ITopicRouter} port (db-p2p binds it to FRET's
24
+ * `RouteAndMaybeAct` / direct dial) and the {@link TierAddressing} math, and delegates building +
25
+ * signing the {@link RegisterV1} to the injected {@link RegisterMessageFactory} (participant identity
26
+ * and crypto live there, not here).
27
+ */
28
+ import { backoffRetryMs } from "./willingness.js";
29
+ import { b64urlToBytes, decodeRegisterReplyV1, encodeCohortMessage } from "./wire/codec.js";
30
+ class RouterWalkEngine {
31
+ deps;
32
+ wantK;
33
+ minSigs;
34
+ maxMemberRetries;
35
+ followPromoted;
36
+ configuredMaxSteps;
37
+ maxMessageBytes;
38
+ constructor(deps) {
39
+ this.deps = deps;
40
+ const cfg = deps.config ?? {};
41
+ this.wantK = cfg.wantK ?? 16;
42
+ this.minSigs = cfg.minSigs ?? 14;
43
+ this.maxMemberRetries = cfg.maxMemberRetries ?? this.wantK;
44
+ this.followPromoted = cfg.followPromoted ?? true;
45
+ this.configuredMaxSteps = cfg.maxSteps;
46
+ this.maxMessageBytes = cfg.maxMessageBytes;
47
+ }
48
+ async register(topicId, tier, appPayload, opts) {
49
+ const dMax = this.deps.dmax.dMax();
50
+ const maxSteps = this.configuredMaxSteps ?? 2 * (dMax + 2) + this.maxMemberRetries + 8;
51
+ const probe = opts?.probe ?? false;
52
+ let d = dMax;
53
+ let bootstrap = false;
54
+ let memberAttempts = 0;
55
+ let dialTarget;
56
+ let steps = 0;
57
+ let probeFollowedPromoted = false;
58
+ for (;;) {
59
+ if (++steps > maxSteps) {
60
+ // Safety valve: a well-formed tree converges well within this bound. Surface a temporal
61
+ // back-off rather than spin.
62
+ return { kind: "retry_later", afterMs: backoffRetryMs(0) };
63
+ }
64
+ const reg = await this.deps.factory.build({ topicId, tier, treeTier: d, bootstrap, probe, appPayload });
65
+ const activity = encodeCohortMessage(reg, this.maxMessageBytes);
66
+ const raw = dialTarget !== undefined
67
+ ? await this.deps.router.dialMember(dialTarget, activity)
68
+ : await this.deps.router.routeAndAct(this.deps.addressing.coord(d, this.deps.self, topicId), activity, {
69
+ wantK: this.wantK,
70
+ minSigs: this.minSigs,
71
+ });
72
+ const reply = decodeRegisterReplyV1(raw, this.maxMessageBytes);
73
+ switch (reply.result) {
74
+ case "accepted": {
75
+ return { kind: "accepted", reply };
76
+ }
77
+ case "no_state": {
78
+ // Step toward the root. The cohort served nothing here; no spatial sibling state.
79
+ dialTarget = undefined;
80
+ memberAttempts = 0;
81
+ if (probe && probeFollowedPromoted) {
82
+ // The promoted child is cold (not yet instantiated). A probe never instantiates it,
83
+ // so back off immediately — walking inward to the promoting ancestor would just
84
+ // re-trigger the Promoted redirect and loop.
85
+ return { kind: "retry_later", afterMs: backoffRetryMs(0) };
86
+ }
87
+ const next = d - 1;
88
+ if (next < 0) {
89
+ if (bootstrap) {
90
+ // Already re-issued at the root as a bootstrap and still nothing — no cohort
91
+ // anywhere will instantiate right now. Back off in time.
92
+ return { kind: "retry_later", afterMs: backoffRetryMs(0) };
93
+ }
94
+ if (probe) {
95
+ // A read-only probe never instantiates a cold root: the topic exists nowhere, so
96
+ // resolve "not found / back off" rather than re-issuing with bootstrap:true.
97
+ return { kind: "retry_later", afterMs: backoffRetryMs(0) };
98
+ }
99
+ // Root returned NoState → cold-start: re-issue once at tier 0 with bootstrap:true.
100
+ d = 0;
101
+ bootstrap = true;
102
+ break;
103
+ }
104
+ d = next;
105
+ bootstrap = false;
106
+ break;
107
+ }
108
+ case "promoted": {
109
+ dialTarget = undefined;
110
+ memberAttempts = 0;
111
+ bootstrap = false;
112
+ const targetTier = reply.targetTier ?? d + 1;
113
+ if (probe) {
114
+ probeFollowedPromoted = true;
115
+ }
116
+ if (!this.followPromoted) {
117
+ return { kind: "promoted", targetTier };
118
+ }
119
+ d = targetTier; // the one outward move — recompute coord at the redirect target
120
+ break;
121
+ }
122
+ case "unwilling_member": {
123
+ const candidates = reply.candidateMembers ?? [];
124
+ if (candidates.length === 0 || memberAttempts >= this.maxMemberRetries) {
125
+ // Exhausted the named siblings (or none offered) → fall through to a cohort-level
126
+ // temporal back-off, restarting at d_max on the caller's retry.
127
+ return { kind: "retry_later", afterMs: backoffRetryMs(0) };
128
+ }
129
+ // Retry the SAME coord at a named alternative member (spatial move within the cohort).
130
+ dialTarget = { id: b64urlToBytes(candidates[memberAttempts % candidates.length]) };
131
+ memberAttempts++;
132
+ break;
133
+ }
134
+ case "unwilling_cohort": {
135
+ // Back off in TIME, no spatial move; the caller restarts at d_max after the delay.
136
+ return { kind: "retry_later", afterMs: reply.retryAfterMs ?? backoffRetryMs(0) };
137
+ }
138
+ default: {
139
+ // Exhaustive over RegisterResult; an unknown result is treated as a temporal decline.
140
+ return { kind: "retry_later", afterMs: backoffRetryMs(0) };
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+ /** Build a {@link WalkEngine} over the injected router, addressing, `d_max`, and message factory. */
147
+ export function createWalkEngine(deps) {
148
+ return new RouterWalkEngine(deps);
149
+ }
150
+ //# sourceMappingURL=walk.js.map