keri-ts 2.0.1 → 2.2.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 (450) hide show
  1. package/README.md +30 -2
  2. package/esm/keri/npm/src/acdc/authoring.js +195 -0
  3. package/esm/keri/npm/src/acdc/chaining.js +223 -89
  4. package/esm/keri/npm/src/acdc/custody.js +164 -0
  5. package/esm/keri/npm/src/acdc/dhking.js +244 -32
  6. package/esm/keri/npm/src/acdc/observing.js +2 -2
  7. package/esm/keri/npm/src/acdc/regbasing.js +30 -29
  8. package/esm/keri/npm/src/acdc/regengine.js +4 -6
  9. package/esm/keri/npm/src/acdc/registering.js +13 -10
  10. package/esm/keri/npm/src/acdc/registraring.js +4 -9
  11. package/esm/keri/npm/src/acdc/salting.js +143 -26
  12. package/esm/keri/npm/src/acdc/scheming.js +93 -54
  13. package/esm/keri/npm/src/acdc/unblinding.js +120 -99
  14. package/esm/keri/npm/src/app/bootstrap/authenticating.js +4 -6
  15. package/esm/keri/npm/src/app/bootstrap/oobi-resolving.js +41 -0
  16. package/esm/keri/npm/src/app/bootstrap/oobiery.js +5 -7
  17. package/esm/keri/npm/src/app/credentials/credential-revoking.js +1 -0
  18. package/esm/keri/npm/src/app/credentials/credential-workflows.js +2 -0
  19. package/esm/keri/npm/src/app/credentials/registry-settling.js +44 -0
  20. package/esm/keri/npm/src/app/credentials/root-replicating.js +131 -0
  21. package/esm/keri/npm/src/app/credentials/root-replicator.js +198 -0
  22. package/esm/keri/npm/src/app/credentials/tel-completion.js +36 -0
  23. package/esm/keri/npm/src/app/credentials/verifying.js +12 -3
  24. package/esm/keri/npm/src/app/delivery/forwarding.js +64 -9
  25. package/esm/keri/npm/src/app/exchanges/exchanging.js +24 -15
  26. package/esm/keri/npm/src/app/identity/challenging.js +50 -0
  27. package/esm/keri/npm/src/app/identity/configing.js +17 -43
  28. package/esm/keri/npm/src/app/identity/delegating.js +77 -77
  29. package/esm/keri/npm/src/app/identity/delegation-approval.js +333 -0
  30. package/esm/keri/npm/src/app/identity/event-completion.js +154 -0
  31. package/esm/keri/npm/src/app/identity/habbing.js +183 -41
  32. package/esm/keri/npm/src/app/identity/keeping.js +78 -5
  33. package/esm/keri/npm/src/app/identity/lmdb-habery.js +12 -0
  34. package/esm/keri/npm/src/app/ipex/group-ipex.js +327 -0
  35. package/esm/keri/npm/src/app/ipex/group-issuance.js +902 -0
  36. package/esm/keri/npm/src/app/ipex/ipex-admitting.js +120 -0
  37. package/esm/keri/npm/src/app/ipex/ipex-conversation.js +197 -0
  38. package/esm/keri/npm/src/app/ipex/ipex-discloser.js +591 -0
  39. package/esm/keri/npm/src/app/ipex/ipex-granting.js +93 -0
  40. package/esm/keri/npm/src/app/ipex/ipex-graph.js +7 -70
  41. package/esm/keri/npm/src/app/ipex/ipex-grouping.js +42 -16
  42. package/esm/keri/npm/src/app/ipex/ipex-v2.js +21 -5
  43. package/esm/keri/npm/src/app/ipex/ipexing.js +1 -1
  44. package/esm/keri/npm/src/app/ipex/issuance.js +888 -0
  45. package/esm/keri/npm/src/app/ipex/pending-presentations.js +46 -0
  46. package/esm/keri/npm/src/app/ipex/presentation-files.js +200 -0
  47. package/esm/keri/npm/src/app/ipex/presenting.js +401 -0
  48. package/esm/keri/npm/src/app/ipex/receive-issuance.js +86 -0
  49. package/esm/keri/npm/src/app/ipex/unblinding-workflow.js +660 -0
  50. package/esm/keri/npm/src/app/mailbox/ipex-arrival.js +103 -0
  51. package/esm/keri/npm/src/app/mailbox/kel-publisher.js +322 -0
  52. package/esm/keri/npm/src/app/mailbox/kel-publishing.js +65 -0
  53. package/esm/keri/npm/src/app/mailbox/kel-submission.js +24 -0
  54. package/esm/keri/npm/src/app/mailbox/mailbox-admin.js +208 -0
  55. package/esm/keri/npm/src/app/mailbox/mailbox-poller.js +212 -47
  56. package/esm/keri/npm/src/app/mailbox/mailboxing.js +15 -14
  57. package/esm/keri/npm/src/app/multisig/counseling.js +482 -0
  58. package/esm/keri/npm/src/app/multisig/group-members.js +32 -0
  59. package/esm/keri/npm/src/app/multisig/grouping.js +4 -3
  60. package/esm/keri/npm/src/app/multisig/multisig-workflows.js +101 -141
  61. package/esm/keri/npm/src/app/multisig/proposals.js +281 -0
  62. package/esm/keri/npm/src/app/multisig/proposing.js +122 -0
  63. package/esm/keri/npm/src/app/notifications/notifying.js +5 -9
  64. package/esm/keri/npm/src/app/notifications/signaling.js +5 -5
  65. package/esm/keri/npm/src/app/protocol/parsering.js +26 -1
  66. package/esm/keri/npm/src/app/protocol/protocol-processing.js +44 -6
  67. package/esm/keri/npm/src/app/queries/query-workflows.js +98 -0
  68. package/esm/keri/npm/src/app/queries/witness-inquisitor.js +2 -2
  69. package/esm/keri/npm/src/app/runtime/agent-runtime.js +113 -65
  70. package/esm/keri/npm/src/app/runtime/cue-runtime.js +3 -6
  71. package/esm/keri/npm/src/app/runtime/delivery-outbox.js +87 -0
  72. package/esm/keri/npm/src/app/runtime/doing.js +17 -0
  73. package/esm/keri/npm/src/app/runtime/ipex-auxiliaries.js +207 -0
  74. package/esm/keri/npm/src/app/runtime/operation-owners.js +151 -0
  75. package/esm/keri/npm/src/app/runtime/retry-backoff.js +93 -0
  76. package/esm/keri/npm/src/app/runtime/workflow-contract.js +80 -0
  77. package/esm/keri/npm/src/app/transport/byte-source.js +6 -42
  78. package/esm/keri/npm/src/app/transport/cesr-egress.js +77 -13
  79. package/esm/keri/npm/src/app/transport/file-bytes.js +41 -0
  80. package/esm/keri/npm/src/app/transport/http-client.js +25 -6
  81. package/esm/keri/npm/src/app/transport/http-messenger.js +14 -9
  82. package/esm/keri/npm/src/app/transport/message-source.js +1 -1
  83. package/esm/keri/npm/src/app/transport/messengering.js +3 -4
  84. package/esm/keri/npm/src/app/transport/node-http-client.js +21 -0
  85. package/esm/keri/npm/src/app/transport/tcp-dialer.js +14 -0
  86. package/esm/keri/npm/src/app/witness/http-endpoints.js +4 -4
  87. package/esm/keri/npm/src/app/witness/receipt-client.js +2 -2
  88. package/esm/keri/npm/src/cli/common/context.js +2 -2
  89. package/esm/keri/npm/src/cli/common/event-completion.js +49 -0
  90. package/esm/keri/npm/src/cli/common/existing.js +3 -5
  91. package/esm/keri/npm/src/cli/common/runtime-workers.js +23 -0
  92. package/esm/keri/npm/src/cli/credentials/ipex.js +159 -191
  93. package/esm/keri/npm/src/cli/credentials/vc.js +53 -72
  94. package/esm/keri/npm/src/cli/endpoints/did.js +12 -3
  95. package/esm/keri/npm/src/cli/endpoints/oobi-clean.js +4 -3
  96. package/esm/keri/npm/src/cli/endpoints/oobi.js +12 -15
  97. package/esm/keri/npm/src/cli/identity/challenge.js +9 -35
  98. package/esm/keri/npm/src/cli/identity/delegate.js +81 -258
  99. package/esm/keri/npm/src/cli/identity/incept.js +17 -34
  100. package/esm/keri/npm/src/cli/identity/init.js +4 -3
  101. package/esm/keri/npm/src/cli/identity/interact.js +7 -19
  102. package/esm/keri/npm/src/cli/identity/rotate.js +10 -38
  103. package/esm/keri/npm/src/cli/index.js +3 -1
  104. package/esm/keri/npm/src/cli/messaging/exchange.js +2 -2
  105. package/esm/keri/npm/src/cli/messaging/group-join.js +79 -0
  106. package/esm/keri/npm/src/cli/messaging/group-wait.js +88 -0
  107. package/esm/keri/npm/src/cli/messaging/multisig.js +187 -250
  108. package/esm/keri/npm/src/cli/messaging/root-copy-lines.js +31 -0
  109. package/esm/keri/npm/src/cli/tools/annotate.js +2 -1
  110. package/esm/keri/npm/src/cli/tools/benchmark.js +2 -1
  111. package/esm/keri/npm/src/cli/tools/db-dump.js +1 -4
  112. package/esm/keri/npm/src/core/bytes.js +9 -0
  113. package/esm/keri/npm/src/core/kel/delegation-ancestry.js +92 -0
  114. package/esm/keri/npm/src/core/kel/eventing.js +67 -12
  115. package/esm/keri/npm/src/core/kel/kever.js +11 -9
  116. package/esm/keri/npm/src/core/mailbox/kram-policy.js +41 -9
  117. package/esm/keri/npm/src/core/mailbox/kram-pruning.js +15 -22
  118. package/esm/keri/npm/src/core/mailbox/kram-staging.js +2 -2
  119. package/esm/keri/npm/src/core/mailbox/kraming.js +2 -0
  120. package/esm/keri/npm/src/core/records.js +23 -0
  121. package/esm/keri/npm/src/core/routing.js +15 -2
  122. package/esm/keri/npm/src/db/basing.js +183 -205
  123. package/esm/keri/npm/src/db/core/dber.js +1062 -0
  124. package/esm/keri/npm/src/db/core/index.js +4 -2
  125. package/esm/keri/npm/src/db/core/indexeddb-persistence.js +221 -0
  126. package/esm/keri/npm/src/db/core/lmdb-opener.js +30 -0
  127. package/esm/keri/npm/src/db/core/lmdber.js +199 -1067
  128. package/esm/keri/npm/src/db/core/memstore.js +532 -0
  129. package/esm/keri/npm/src/db/core/path-manager.js +109 -223
  130. package/esm/keri/npm/src/db/core/store-owner.js +104 -0
  131. package/esm/keri/npm/src/db/core/webdber.js +252 -0
  132. package/esm/keri/npm/src/db/escrowing.js +2 -2
  133. package/esm/keri/npm/src/db/exchange/exchange-nests.js +3 -2
  134. package/esm/keri/npm/src/db/indexeddb.js +98 -0
  135. package/esm/keri/npm/src/db/keeping.js +38 -123
  136. package/esm/keri/npm/src/db/koming.js +1 -1
  137. package/esm/keri/npm/src/db/lmdb-stores.js +68 -0
  138. package/esm/keri/npm/src/db/lmdb.js +6 -0
  139. package/esm/keri/npm/src/db/mailbox/mailboxing.js +12 -65
  140. package/esm/keri/npm/src/db/noting.js +11 -55
  141. package/esm/keri/npm/src/db/reger.js +43 -105
  142. package/esm/keri/npm/src/db/replay/witness-replay.js +2 -20
  143. package/esm/keri/npm/src/db/store-lock.js +150 -0
  144. package/esm/keri/npm/src/db/subing.js +1 -1
  145. package/esm/keri/npm/src/npm/db-indexeddb.browser.js +2 -0
  146. package/esm/keri/npm/src/npm/db-indexeddb.js +3 -0
  147. package/esm/keri/npm/src/npm/db-lmdb.js +3 -0
  148. package/esm/keri/npm/src/npm/db.browser.js +2 -0
  149. package/esm/keri/npm/src/npm/index.browser.js +9 -0
  150. package/esm/keri/npm/src/npm/runtime-node.js +3 -0
  151. package/esm/keri/npm/src/npm/runtime-web.browser.js +2 -0
  152. package/esm/keri/npm/src/npm/runtime-web.js +3 -0
  153. package/esm/keri/npm/src/npm/runtime.browser.js +2 -0
  154. package/esm/keri/npm/src/runtime/index.js +58 -12
  155. package/esm/keri/npm/src/runtime/node.js +14 -0
  156. package/esm/keri/npm/src/runtime/web/output-barrier.js +47 -0
  157. package/esm/keri/npm/src/runtime/web/persistent-storage.js +37 -0
  158. package/esm/keri/npm/src/runtime/web.js +10 -0
  159. package/esm/keri/npm/src/vdr/eventing.js +1 -1
  160. package/esm/keri/npm/src/vdr/tel-publication.js +19 -3
  161. package/esm/keri/npm/src/version.js +2 -2
  162. package/package.json +24 -4
  163. package/types/acdc/authoring.d.ts +54 -0
  164. package/types/acdc/authoring.d.ts.map +1 -0
  165. package/types/acdc/chaining.d.ts +56 -6
  166. package/types/acdc/chaining.d.ts.map +1 -1
  167. package/types/acdc/custody.d.ts +77 -0
  168. package/types/acdc/custody.d.ts.map +1 -0
  169. package/types/acdc/dhking.d.ts +94 -3
  170. package/types/acdc/dhking.d.ts.map +1 -1
  171. package/types/acdc/regbasing.d.ts +11 -6
  172. package/types/acdc/regbasing.d.ts.map +1 -1
  173. package/types/acdc/regengine.d.ts.map +1 -1
  174. package/types/acdc/registering.d.ts +8 -4
  175. package/types/acdc/registering.d.ts.map +1 -1
  176. package/types/acdc/registraring.d.ts.map +1 -1
  177. package/types/acdc/salting.d.ts +59 -7
  178. package/types/acdc/salting.d.ts.map +1 -1
  179. package/types/acdc/scheming.d.ts +2 -0
  180. package/types/acdc/scheming.d.ts.map +1 -1
  181. package/types/acdc/unblinding.d.ts +58 -19
  182. package/types/acdc/unblinding.d.ts.map +1 -1
  183. package/types/app/bootstrap/authenticating.d.ts +3 -1
  184. package/types/app/bootstrap/authenticating.d.ts.map +1 -1
  185. package/types/app/bootstrap/oobi-resolving.d.ts +92 -0
  186. package/types/app/bootstrap/oobi-resolving.d.ts.map +1 -0
  187. package/types/app/bootstrap/oobiery.d.ts +3 -1
  188. package/types/app/bootstrap/oobiery.d.ts.map +1 -1
  189. package/types/app/credentials/credential-revoking.d.ts +3 -0
  190. package/types/app/credentials/credential-revoking.d.ts.map +1 -1
  191. package/types/app/credentials/credential-workflows.d.ts +5 -0
  192. package/types/app/credentials/credential-workflows.d.ts.map +1 -1
  193. package/types/app/credentials/registry-settling.d.ts +85 -0
  194. package/types/app/credentials/registry-settling.d.ts.map +1 -0
  195. package/types/app/credentials/root-replicating.d.ts +97 -0
  196. package/types/app/credentials/root-replicating.d.ts.map +1 -0
  197. package/types/app/credentials/root-replicator.d.ts +105 -0
  198. package/types/app/credentials/root-replicator.d.ts.map +1 -0
  199. package/types/app/credentials/tel-completion.d.ts +55 -0
  200. package/types/app/credentials/tel-completion.d.ts.map +1 -0
  201. package/types/app/credentials/verifying.d.ts +2 -1
  202. package/types/app/credentials/verifying.d.ts.map +1 -1
  203. package/types/app/delivery/forwarding.d.ts +16 -0
  204. package/types/app/delivery/forwarding.d.ts.map +1 -1
  205. package/types/app/exchanges/exchanging.d.ts +2 -0
  206. package/types/app/exchanges/exchanging.d.ts.map +1 -1
  207. package/types/app/identity/challenging.d.ts +54 -0
  208. package/types/app/identity/challenging.d.ts.map +1 -1
  209. package/types/app/identity/configing.d.ts +7 -5
  210. package/types/app/identity/configing.d.ts.map +1 -1
  211. package/types/app/identity/delegating.d.ts +21 -4
  212. package/types/app/identity/delegating.d.ts.map +1 -1
  213. package/types/app/identity/delegation-approval.d.ts +228 -0
  214. package/types/app/identity/delegation-approval.d.ts.map +1 -0
  215. package/types/app/identity/event-completion.d.ts +151 -0
  216. package/types/app/identity/event-completion.d.ts.map +1 -0
  217. package/types/app/identity/habbing.d.ts +90 -7
  218. package/types/app/identity/habbing.d.ts.map +1 -1
  219. package/types/app/identity/keeping.d.ts +50 -4
  220. package/types/app/identity/keeping.d.ts.map +1 -1
  221. package/types/app/identity/lmdb-habery.d.ts +6 -0
  222. package/types/app/identity/lmdb-habery.d.ts.map +1 -0
  223. package/types/app/ipex/group-ipex.d.ts +247 -0
  224. package/types/app/ipex/group-ipex.d.ts.map +1 -0
  225. package/types/app/ipex/group-issuance.d.ts +281 -0
  226. package/types/app/ipex/group-issuance.d.ts.map +1 -0
  227. package/types/app/ipex/ipex-admitting.d.ts +47 -0
  228. package/types/app/ipex/ipex-admitting.d.ts.map +1 -0
  229. package/types/app/ipex/ipex-conversation.d.ts +195 -0
  230. package/types/app/ipex/ipex-conversation.d.ts.map +1 -0
  231. package/types/app/ipex/ipex-discloser.d.ts +156 -0
  232. package/types/app/ipex/ipex-discloser.d.ts.map +1 -0
  233. package/types/app/ipex/ipex-granting.d.ts +145 -0
  234. package/types/app/ipex/ipex-granting.d.ts.map +1 -0
  235. package/types/app/ipex/ipex-graph.d.ts +4 -4
  236. package/types/app/ipex/ipex-graph.d.ts.map +1 -1
  237. package/types/app/ipex/ipex-grouping.d.ts +18 -0
  238. package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
  239. package/types/app/ipex/ipex-v2.d.ts +11 -2
  240. package/types/app/ipex/ipex-v2.d.ts.map +1 -1
  241. package/types/app/ipex/ipexing.d.ts +3 -0
  242. package/types/app/ipex/ipexing.d.ts.map +1 -1
  243. package/types/app/ipex/issuance.d.ts +443 -0
  244. package/types/app/ipex/issuance.d.ts.map +1 -0
  245. package/types/app/ipex/pending-presentations.d.ts +25 -0
  246. package/types/app/ipex/pending-presentations.d.ts.map +1 -0
  247. package/types/app/ipex/presentation-files.d.ts +47 -0
  248. package/types/app/ipex/presentation-files.d.ts.map +1 -0
  249. package/types/app/ipex/presenting.d.ts +298 -0
  250. package/types/app/ipex/presenting.d.ts.map +1 -0
  251. package/types/app/ipex/receive-issuance.d.ts +99 -0
  252. package/types/app/ipex/receive-issuance.d.ts.map +1 -0
  253. package/types/app/ipex/unblinding-workflow.d.ts +255 -0
  254. package/types/app/ipex/unblinding-workflow.d.ts.map +1 -0
  255. package/types/app/mailbox/ipex-arrival.d.ts +104 -0
  256. package/types/app/mailbox/ipex-arrival.d.ts.map +1 -0
  257. package/types/app/mailbox/kel-publisher.d.ts +141 -0
  258. package/types/app/mailbox/kel-publisher.d.ts.map +1 -0
  259. package/types/app/mailbox/kel-publishing.d.ts +70 -0
  260. package/types/app/mailbox/kel-publishing.d.ts.map +1 -0
  261. package/types/app/mailbox/kel-submission.d.ts +18 -0
  262. package/types/app/mailbox/kel-submission.d.ts.map +1 -0
  263. package/types/app/mailbox/mailbox-admin.d.ts +113 -0
  264. package/types/app/mailbox/mailbox-admin.d.ts.map +1 -0
  265. package/types/app/mailbox/mailbox-poller.d.ts +92 -3
  266. package/types/app/mailbox/mailbox-poller.d.ts.map +1 -1
  267. package/types/app/mailbox/mailboxing.d.ts +4 -1
  268. package/types/app/mailbox/mailboxing.d.ts.map +1 -1
  269. package/types/app/multisig/counseling.d.ts +196 -0
  270. package/types/app/multisig/counseling.d.ts.map +1 -0
  271. package/types/app/multisig/group-members.d.ts +20 -0
  272. package/types/app/multisig/group-members.d.ts.map +1 -1
  273. package/types/app/multisig/grouping.d.ts +39 -20
  274. package/types/app/multisig/grouping.d.ts.map +1 -1
  275. package/types/app/multisig/multisig-workflows.d.ts +93 -23
  276. package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
  277. package/types/app/multisig/proposals.d.ts +129 -0
  278. package/types/app/multisig/proposals.d.ts.map +1 -0
  279. package/types/app/multisig/proposing.d.ts +125 -0
  280. package/types/app/multisig/proposing.d.ts.map +1 -0
  281. package/types/app/notifications/notifying.d.ts +1 -1
  282. package/types/app/notifications/notifying.d.ts.map +1 -1
  283. package/types/app/notifications/signaling.d.ts +3 -1
  284. package/types/app/notifications/signaling.d.ts.map +1 -1
  285. package/types/app/protocol/parsering.d.ts +16 -1
  286. package/types/app/protocol/parsering.d.ts.map +1 -1
  287. package/types/app/protocol/protocol-processing.d.ts +9 -1
  288. package/types/app/protocol/protocol-processing.d.ts.map +1 -1
  289. package/types/app/queries/query-workflows.d.ts +98 -0
  290. package/types/app/queries/query-workflows.d.ts.map +1 -0
  291. package/types/app/runtime/agent-runtime.d.ts +79 -25
  292. package/types/app/runtime/agent-runtime.d.ts.map +1 -1
  293. package/types/app/runtime/cue-runtime.d.ts +2 -1
  294. package/types/app/runtime/cue-runtime.d.ts.map +1 -1
  295. package/types/app/runtime/delivery-outbox.d.ts +68 -0
  296. package/types/app/runtime/delivery-outbox.d.ts.map +1 -0
  297. package/types/app/runtime/doing.d.ts +27 -0
  298. package/types/app/runtime/doing.d.ts.map +1 -0
  299. package/types/app/runtime/ipex-auxiliaries.d.ts +74 -0
  300. package/types/app/runtime/ipex-auxiliaries.d.ts.map +1 -0
  301. package/types/app/runtime/operation-owners.d.ts +137 -0
  302. package/types/app/runtime/operation-owners.d.ts.map +1 -0
  303. package/types/app/runtime/retry-backoff.d.ts +49 -0
  304. package/types/app/runtime/retry-backoff.d.ts.map +1 -0
  305. package/types/app/runtime/workflow-contract.d.ts +79 -0
  306. package/types/app/runtime/workflow-contract.d.ts.map +1 -0
  307. package/types/app/transport/byte-source.d.ts +13 -10
  308. package/types/app/transport/byte-source.d.ts.map +1 -1
  309. package/types/app/transport/cesr-egress.d.ts +21 -7
  310. package/types/app/transport/cesr-egress.d.ts.map +1 -1
  311. package/types/app/transport/file-bytes.d.ts +11 -0
  312. package/types/app/transport/file-bytes.d.ts.map +1 -0
  313. package/types/app/transport/http-client.d.ts +3 -0
  314. package/types/app/transport/http-client.d.ts.map +1 -1
  315. package/types/app/transport/http-messenger.d.ts +15 -10
  316. package/types/app/transport/http-messenger.d.ts.map +1 -1
  317. package/types/app/transport/message-source.d.ts +1 -1
  318. package/types/app/transport/messengering.d.ts +2 -2
  319. package/types/app/transport/messengering.d.ts.map +1 -1
  320. package/types/app/transport/node-http-client.d.ts +10 -0
  321. package/types/app/transport/node-http-client.d.ts.map +1 -0
  322. package/types/app/transport/tcp-dialer.d.ts +21 -0
  323. package/types/app/transport/tcp-dialer.d.ts.map +1 -0
  324. package/types/cli/common/event-completion.d.ts +26 -0
  325. package/types/cli/common/event-completion.d.ts.map +1 -0
  326. package/types/cli/common/existing.d.ts.map +1 -1
  327. package/types/cli/common/runtime-workers.d.ts +23 -0
  328. package/types/cli/common/runtime-workers.d.ts.map +1 -0
  329. package/types/cli/credentials/ipex.d.ts.map +1 -1
  330. package/types/cli/credentials/vc.d.ts +1 -1
  331. package/types/cli/credentials/vc.d.ts.map +1 -1
  332. package/types/cli/endpoints/did.d.ts.map +1 -1
  333. package/types/cli/endpoints/oobi-clean.d.ts.map +1 -1
  334. package/types/cli/endpoints/oobi.d.ts +3 -1
  335. package/types/cli/endpoints/oobi.d.ts.map +1 -1
  336. package/types/cli/identity/challenge.d.ts +1 -1
  337. package/types/cli/identity/challenge.d.ts.map +1 -1
  338. package/types/cli/identity/delegate.d.ts +14 -1
  339. package/types/cli/identity/delegate.d.ts.map +1 -1
  340. package/types/cli/identity/incept.d.ts.map +1 -1
  341. package/types/cli/identity/init.d.ts.map +1 -1
  342. package/types/cli/identity/interact.d.ts.map +1 -1
  343. package/types/cli/identity/rotate.d.ts.map +1 -1
  344. package/types/cli/index.d.ts +4 -2
  345. package/types/cli/index.d.ts.map +1 -1
  346. package/types/cli/messaging/group-join.d.ts +53 -0
  347. package/types/cli/messaging/group-join.d.ts.map +1 -0
  348. package/types/cli/messaging/group-wait.d.ts +34 -0
  349. package/types/cli/messaging/group-wait.d.ts.map +1 -0
  350. package/types/cli/messaging/multisig.d.ts +36 -4
  351. package/types/cli/messaging/multisig.d.ts.map +1 -1
  352. package/types/cli/messaging/root-copy-lines.d.ts +39 -0
  353. package/types/cli/messaging/root-copy-lines.d.ts.map +1 -0
  354. package/types/cli/tools/annotate.d.ts.map +1 -1
  355. package/types/cli/tools/benchmark.d.ts.map +1 -1
  356. package/types/cli/tools/db-dump.d.ts.map +1 -1
  357. package/types/core/bytes.d.ts +2 -0
  358. package/types/core/bytes.d.ts.map +1 -1
  359. package/types/core/cues.d.ts +11 -0
  360. package/types/core/cues.d.ts.map +1 -1
  361. package/types/core/kel/delegation-ancestry.d.ts +41 -0
  362. package/types/core/kel/delegation-ancestry.d.ts.map +1 -0
  363. package/types/core/kel/eventing.d.ts.map +1 -1
  364. package/types/core/kel/kever.d.ts +5 -4
  365. package/types/core/kel/kever.d.ts.map +1 -1
  366. package/types/core/mailbox/kram-policy.d.ts +14 -0
  367. package/types/core/mailbox/kram-policy.d.ts.map +1 -1
  368. package/types/core/mailbox/kram-pruning.d.ts +1 -3
  369. package/types/core/mailbox/kram-pruning.d.ts.map +1 -1
  370. package/types/core/mailbox/kraming.d.ts +1 -1
  371. package/types/core/mailbox/kraming.d.ts.map +1 -1
  372. package/types/core/records.d.ts +61 -0
  373. package/types/core/records.d.ts.map +1 -1
  374. package/types/core/routing.d.ts +6 -0
  375. package/types/core/routing.d.ts.map +1 -1
  376. package/types/db/basing.d.ts +22 -25
  377. package/types/db/basing.d.ts.map +1 -1
  378. package/types/db/core/dber.d.ts +505 -0
  379. package/types/db/core/dber.d.ts.map +1 -0
  380. package/types/db/core/index.d.ts +4 -2
  381. package/types/db/core/index.d.ts.map +1 -1
  382. package/types/db/core/indexeddb-persistence.d.ts +59 -0
  383. package/types/db/core/indexeddb-persistence.d.ts.map +1 -0
  384. package/types/db/core/lmdb-opener.d.ts +17 -0
  385. package/types/db/core/lmdb-opener.d.ts.map +1 -0
  386. package/types/db/core/lmdber.d.ts +60 -383
  387. package/types/db/core/lmdber.d.ts.map +1 -1
  388. package/types/db/core/memstore.d.ts +129 -0
  389. package/types/db/core/memstore.d.ts.map +1 -0
  390. package/types/db/core/path-manager.d.ts +22 -45
  391. package/types/db/core/path-manager.d.ts.map +1 -1
  392. package/types/db/core/store-owner.d.ts +59 -0
  393. package/types/db/core/store-owner.d.ts.map +1 -0
  394. package/types/db/core/webdber.d.ts +127 -0
  395. package/types/db/core/webdber.d.ts.map +1 -0
  396. package/types/db/escrowing.d.ts +3 -3
  397. package/types/db/escrowing.d.ts.map +1 -1
  398. package/types/db/exchange/exchange-nests.d.ts.map +1 -1
  399. package/types/db/indexeddb.d.ts +37 -0
  400. package/types/db/indexeddb.d.ts.map +1 -0
  401. package/types/db/keeping.d.ts +14 -25
  402. package/types/db/keeping.d.ts.map +1 -1
  403. package/types/db/koming.d.ts +7 -8
  404. package/types/db/koming.d.ts.map +1 -1
  405. package/types/db/lmdb-stores.d.ts +45 -0
  406. package/types/db/lmdb-stores.d.ts.map +1 -0
  407. package/types/db/lmdb.d.ts +7 -0
  408. package/types/db/lmdb.d.ts.map +1 -0
  409. package/types/db/mailbox/mailboxing.d.ts +7 -21
  410. package/types/db/mailbox/mailboxing.d.ts.map +1 -1
  411. package/types/db/noting.d.ts +7 -12
  412. package/types/db/noting.d.ts.map +1 -1
  413. package/types/db/reger.d.ts +7 -11
  414. package/types/db/reger.d.ts.map +1 -1
  415. package/types/db/replay/witness-replay.d.ts +0 -2
  416. package/types/db/replay/witness-replay.d.ts.map +1 -1
  417. package/types/db/store-lock.d.ts +72 -0
  418. package/types/db/store-lock.d.ts.map +1 -0
  419. package/types/db/subing.d.ts +24 -25
  420. package/types/db/subing.d.ts.map +1 -1
  421. package/types/npm/db-indexeddb.d.ts +4 -0
  422. package/types/npm/db-indexeddb.d.ts.map +1 -0
  423. package/types/npm/db-lmdb.d.ts +4 -0
  424. package/types/npm/db-lmdb.d.ts.map +1 -0
  425. package/types/npm/runtime-node.d.ts +4 -0
  426. package/types/npm/runtime-node.d.ts.map +1 -0
  427. package/types/npm/runtime-web.d.ts +4 -0
  428. package/types/npm/runtime-web.d.ts.map +1 -0
  429. package/types/runtime/index.d.ts +48 -14
  430. package/types/runtime/index.d.ts.map +1 -1
  431. package/types/runtime/node.d.ts +15 -0
  432. package/types/runtime/node.d.ts.map +1 -0
  433. package/types/runtime/web/output-barrier.d.ts +30 -0
  434. package/types/runtime/web/output-barrier.d.ts.map +1 -0
  435. package/types/runtime/web/persistent-storage.d.ts +36 -0
  436. package/types/runtime/web/persistent-storage.d.ts.map +1 -0
  437. package/types/runtime/web.d.ts +11 -0
  438. package/types/runtime/web.d.ts.map +1 -0
  439. package/types/vdr/tel-publication.d.ts +6 -0
  440. package/types/vdr/tel-publication.d.ts.map +1 -1
  441. package/types/version.d.ts +2 -2
  442. package/esm/keri/npm/src/acdc/relating.js +0 -59
  443. package/esm/keri/npm/src/cli/common/tel-completion.js +0 -24
  444. package/esm/keri/npm/src/db/baser-defaults.js +0 -11
  445. package/types/acdc/relating.d.ts +0 -21
  446. package/types/acdc/relating.d.ts.map +0 -1
  447. package/types/cli/common/tel-completion.d.ts +0 -8
  448. package/types/cli/common/tel-completion.d.ts.map +0 -1
  449. package/types/db/baser-defaults.d.ts +0 -5
  450. package/types/db/baser-defaults.d.ts.map +0 -1
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Mailbox administration for a single-signature controller: authorize or revoke
3
+ * a remote mailbox through a provider's admin endpoint, owned by the library so
4
+ * that every host (CLI, wallet, service) runs one implementation.
5
+ *
6
+ * Operations follow the workflow contract: `addMailbox` and `removeMailbox`
7
+ * are explicit, sign the endpoint-role reply, post it to the provider and
8
+ * return after the reply is accepted locally. `mailboxStatus` is a pure read of
9
+ * the accepted end-role state. `waitForMailboxState` only observes: it never
10
+ * starts workers and returns a timed-out value instead of throwing.
11
+ *
12
+ * Boundaries:
13
+ * - Dependencies are the concrete collaborators below, not an AgentRuntime
14
+ * (ADR-0013). The host owns their lifetimes.
15
+ * - The provider is reached through the supplied fetch-only `HttpClient`; nothing
16
+ * here needs TCP, files or `node:` modules, so a browser can call it.
17
+ * - Group controllers do not use these operations: their propose/complete split
18
+ * needs the Poster worker (to deliver the proposal to co-signers) and the
19
+ * group coordinator, which a library `proposeMailbox` would have to take as
20
+ * collaborators. `completeMailboxAdmin` is the shared tail they reuse.
21
+ */
22
+ import { concatBytes } from "cesr-ts";
23
+ import { call, sleep } from "effection";
24
+ import { ValidationError } from "../../core/errors.js";
25
+ import { Roles } from "../../core/roles.js";
26
+ import { endpointRoleAccepted, loadAcceptedEndpointRole, proposeGroupEndpointRole, } from "../identity/endpoint-roleing.js";
27
+ import { systemClock } from "../runtime/runtime-clock.js";
28
+ import { buildCesrStreamRequest } from "../transport/cesr-http.js";
29
+ import { kelHeads, pinKelPublished } from "./kel-publishing.js";
30
+ import { collectKelSubmission } from "./kel-submission.js";
31
+ import { fetchEndpointUrls, preferredUrl } from "./mailboxing.js";
32
+ /** Derive the mailbox-admin URL relative to one hosted endpoint path. */
33
+ export function mailboxAdminUrl(url) {
34
+ try {
35
+ const parsed = new URL(url);
36
+ const pathname = parsed.pathname.replace(/\/+$/, "") || "/";
37
+ const base = pathname === "/" ? "" : pathname;
38
+ return `${parsed.protocol}//${parsed.host}${base}/mailboxes`;
39
+ }
40
+ catch (error) {
41
+ if (error instanceof ValidationError) {
42
+ throw error;
43
+ }
44
+ throw new ValidationError(`Invalid mailbox URL: ${url}`);
45
+ }
46
+ }
47
+ /**
48
+ * Preferred accepted URL of a mailbox endpoint.
49
+ *
50
+ * @throws ValidationError when no location reply has been accepted for it.
51
+ */
52
+ export function requireMailboxEndpointUrl(hby, mailbox) {
53
+ const url = preferredUrl(fetchEndpointUrls(hby, mailbox));
54
+ if (!url) {
55
+ throw new ValidationError(`No endpoint URL is stored for mailbox ${mailbox}.`);
56
+ }
57
+ return url;
58
+ }
59
+ /** Read the accepted mailbox end-role state for `pre`; mutates nothing. */
60
+ export function mailboxStatus(hby, pre, mailbox) {
61
+ const end = hby.db.ends.get([pre, Roles.mailbox, mailbox]);
62
+ if (!end)
63
+ return { mailbox, state: "absent" };
64
+ return { mailbox, state: end.allowed ? "authorized" : "revoked" };
65
+ }
66
+ /**
67
+ * Authorize `mailbox` for `hab`: sign (or reload) the mailbox end-role reply,
68
+ * post it to the provider and accept it locally.
69
+ *
70
+ * @throws ValidationError for a missing endpoint URL, a provider HTTP failure or a reply that local state does not accept.
71
+ */
72
+ export function* addMailbox(deps, hab, mailbox) {
73
+ const url = requireMailboxEndpointUrl(deps.hby, mailbox);
74
+ const existing = deps.hby.db.ends.get([hab.pre, Roles.mailbox, mailbox]);
75
+ const rpy = existing?.allowed
76
+ ? hab.loadEndRole(hab.pre, mailbox, Roles.mailbox)
77
+ : hab.makeEndRole(mailbox, Roles.mailbox, true);
78
+ return yield* completeMailboxAdmin(deps, hab, mailbox, url, rpy, true);
79
+ }
80
+ /**
81
+ * Revoke `mailbox` for `hab`: sign a mailbox end-role cut, post it to the
82
+ * provider and accept it locally. Single-signature controllers only.
83
+ *
84
+ * @throws ValidationError as for `addMailbox`.
85
+ */
86
+ export function* removeMailbox(deps, hab, mailbox) {
87
+ const url = requireMailboxEndpointUrl(deps.hby, mailbox);
88
+ const rpy = hab.makeEndRole(mailbox, Roles.mailbox, false);
89
+ return yield* completeMailboxAdmin(deps, hab, mailbox, url, rpy, false);
90
+ }
91
+ /**
92
+ * Post one signed mailbox end-role reply to the provider, accept it locally and
93
+ * confirm the resulting state. Also the completion step of a group add whose
94
+ * role was already approved.
95
+ *
96
+ * @param allow True when the reply grants the role; false when it cuts it.
97
+ * @throws ValidationError when the reply is empty, the provider refuses it, or local state does not reflect it.
98
+ */
99
+ export function* completeMailboxAdmin(deps, hab, mailbox, endpointUrl, rpy, allow) {
100
+ if (rpy.length === 0) {
101
+ throw new ValidationError(`No accepted mailbox role reply is available for ${hab.pre}.`);
102
+ }
103
+ // The request carries the KEL up to this establishment event, which the mailbox then holds.
104
+ const established = kelHeads(deps.hby, hab.pre);
105
+ const response = yield* postMailboxAdmin(deps.http, endpointUrl, mailbox, collectKelSubmission(deps.hby, hab.pre), rpy);
106
+ if (!response.ok) {
107
+ throw new ValidationError(`Mailbox admin request failed with HTTP ${response.status}: ${response.body}`);
108
+ }
109
+ yield* deps.reactor.processBytes(rpy, {});
110
+ yield* deps.protocol.processEscrowsOnce();
111
+ const status = mailboxStatus(deps.hby, hab.pre, mailbox);
112
+ if (allow && status.state !== "authorized") {
113
+ throw new ValidationError("Mailbox add was not accepted into local state.");
114
+ }
115
+ if (!allow && status.state !== "revoked") {
116
+ throw new ValidationError("Mailbox removal was not accepted into local state.");
117
+ }
118
+ // The publisher need not send a KEL this request just carried.
119
+ if (allow && established)
120
+ pinKelPublished(deps.hby.db, hab.pre, mailbox, established, systemClock);
121
+ deps.publisher?.prompt(hab.pre);
122
+ return status;
123
+ }
124
+ /**
125
+ * Propose a group's mailbox authorization (`/end/role/add`) to the other members, who
126
+ * approve it with `approveGroupProposal`. Returns without waiting and sends nothing
127
+ * to the provider; {@link completeGroupMailbox} does that once the role is accepted.
128
+ * The caller runs the Poster's delivery for the duration.
129
+ */
130
+ export function* proposeGroupMailbox(hby, protocol, postman, group, mailbox) {
131
+ return yield* proposeGroupEndpointRole(hby, protocol, postman, group, {
132
+ eid: mailbox,
133
+ role: Roles.mailbox,
134
+ allow: true,
135
+ });
136
+ }
137
+ /**
138
+ * Finish a group mailbox add whose end-role reply the members approved: post the
139
+ * accepted reply to the provider and confirm local state.
140
+ *
141
+ * @throws ValidationError while the group has not accepted the mailbox role, or as for `completeMailboxAdmin`.
142
+ */
143
+ export function* completeGroupMailbox(deps, group, mailbox) {
144
+ if (!endpointRoleAccepted(deps.hby, group.pre, Roles.mailbox, mailbox)) {
145
+ throw new ValidationError(`Mailbox role for ${mailbox} is not yet approved for group ${group.pre}.`);
146
+ }
147
+ const url = requireMailboxEndpointUrl(deps.hby, mailbox);
148
+ const rpy = loadAcceptedEndpointRole(group, mailbox, Roles.mailbox);
149
+ return yield* completeMailboxAdmin(deps, group, mailbox, url, rpy, true);
150
+ }
151
+ /**
152
+ * Observe `read` until it reports the wanted state or the deadline passes. It
153
+ * starts no workers: whoever owns the runtime makes the state change.
154
+ */
155
+ export function* waitForMailboxState(read, { want, deadline, clock = systemClock, pollMs = 250 }) {
156
+ while (true) {
157
+ const status = read();
158
+ if (status.state === want)
159
+ return { outcome: "settled", status };
160
+ const remaining = deadline - clock.now();
161
+ if (remaining <= 0)
162
+ return { outcome: "timed-out", status };
163
+ yield* sleep(Math.min(pollMs, remaining));
164
+ }
165
+ }
166
+ /**
167
+ * Submit one admin request: the raw `application/cesr` body first, then the
168
+ * legacy multipart form when the provider answers 406 or 415.
169
+ */
170
+ function* postMailboxAdmin(http, url, mailbox, submission, rpy) {
171
+ const raw = yield* postMailboxAdminCesr(http, url, mailbox, concatBytes(submission.replay, rpy));
172
+ if (raw.ok || (raw.status !== 406 && raw.status !== 415))
173
+ return raw;
174
+ return yield* postMailboxAdminMultipart(http, url, mailbox, submission, rpy);
175
+ }
176
+ /** Send finite administrative CESR bytes with `CESR-DESTINATION` selecting the hosted mailbox. */
177
+ export function* postMailboxAdminCesr(http, url, mailbox, bytes) {
178
+ const request = buildCesrStreamRequest(bytes, { destination: mailbox });
179
+ const response = yield* http.request(mailboxAdminUrl(url), {
180
+ method: "POST",
181
+ headers: request.headers,
182
+ body: request.body,
183
+ });
184
+ // Administrative JSON/diagnostics are finite metadata, not an unbounded stream.
185
+ return { ok: response.ok, status: response.status, body: new TextDecoder().decode(response.body) };
186
+ }
187
+ /**
188
+ * Send the legacy multipart form (`kel`, optional `delkel`, `rpy`). The platform
189
+ * encoder runs once so the generated boundary stays consistent with the body.
190
+ */
191
+ export function* postMailboxAdminMultipart(http, url, mailbox, submission, rpy) {
192
+ const decoder = new TextDecoder();
193
+ const form = new FormData();
194
+ form.append("kel", decoder.decode(submission.kel));
195
+ if (submission.delkel.length > 0) {
196
+ form.append("delkel", decoder.decode(submission.delkel));
197
+ }
198
+ form.append("rpy", decoder.decode(rpy));
199
+ const prepared = new Response(form);
200
+ prepared.headers.set("CESR-DESTINATION", mailbox);
201
+ const bytes = yield* call(() => prepared.arrayBuffer());
202
+ const response = yield* http.request(mailboxAdminUrl(url), {
203
+ method: "POST",
204
+ headers: prepared.headers,
205
+ body: bytes,
206
+ });
207
+ return { ok: response.ok, status: response.status, body: decoder.decode(response.body) };
208
+ }
@@ -1,12 +1,34 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var _MailboxPoller_dirty;
1
7
  /** Recipient mailbox polling: signed queries, awaited SSE intake and persisted cursor progression. */
2
8
  import { call, scoped, spawn } from "effection";
3
9
  import { abortable } from "../runtime/abortable.js";
10
+ import { doEvery, PROTOCOL_TOCK_MS } from "../runtime/doing.js";
4
11
  import { runtimeTurn } from "../runtime/runtime-turn.js";
12
+ import { waitOnClock } from "../runtime/workflow-contract.js";
5
13
  import { isLegacyCesrMediaRejection, readResponseDetail } from "../transport/cesr-egress.js";
6
- import { buildCesrRequest, CESR_CONTENT_TYPE, KERIPY_CESR_JSON_CONTENT_TYPE } from "../transport/cesr-http.js";
14
+ import { buildCesrRequest, CESR_CONTENT_TYPE, KERIPY_CESR_JSON_CONTENT_TYPE, } from "../transport/cesr-http.js";
7
15
  import { requestWithHeaderTimeout } from "../transport/httping.js";
16
+ import { TransportError } from "../transport/transport-error.js";
8
17
  import { consumeMailboxSse } from "./mailbox-sse.js";
9
18
  import { mailboxPollEndpoints } from "./mailboxing.js";
19
+ /** Tocks between the poller's full re-selection of workers: 160 tocks of 31.25 ms is five seconds. */
20
+ export const MAILBOX_POLLER_SWEEP_TOCKS = 160;
21
+ /**
22
+ * The production pacing of the mailbox poller. Between sweeps it re-selects workers only when the registered
23
+ * topics or the number of identifiers change, or for an identifier passed to {@link MailboxPoller.prompt} (the
24
+ * runtime prompts one when a mailbox end role is accepted). Endpoint changes other than an accepted mailbox end
25
+ * role (a rotated-in witness, a location accepted after its role, another process writing the same store) are
26
+ * therefore picked up within five seconds.
27
+ */
28
+ export const MAILBOX_POLLER_PACING = Object.freeze({
29
+ tockMs: PROTOCOL_TOCK_MS,
30
+ sweepTocks: MAILBOX_POLLER_SWEEP_TOCKS,
31
+ });
10
32
  /**
11
33
  * Retrieve recipient messages from remote mailbox or witness endpoints over HTTP/SSE.
12
34
  *
@@ -60,7 +82,25 @@ export class MailboxPoller {
60
82
  writable: true,
61
83
  value: void 0
62
84
  });
63
- const { timeouts } = options;
85
+ /** Told after each poll a mailbox served. */
86
+ Object.defineProperty(this, "onPolled", {
87
+ enumerable: true,
88
+ configurable: true,
89
+ writable: true,
90
+ value: void 0
91
+ });
92
+ /** Told when a mailbox answers 403. */
93
+ Object.defineProperty(this, "onUnauthorized", {
94
+ enumerable: true,
95
+ configurable: true,
96
+ writable: true,
97
+ value: void 0
98
+ });
99
+ /** Identifiers whose mailbox endpoints changed; the poller re-selects their workers on the next tock. */
100
+ _MailboxPoller_dirty.set(this, new Set());
101
+ const { timeouts, onPolled, onUnauthorized } = options;
102
+ this.onPolled = onPolled;
103
+ this.onUnauthorized = onUnauthorized;
64
104
  this.hby = hby;
65
105
  this.mailboxDirector = mailboxDirector;
66
106
  this.timeoutPolicy = normalizeMailboxPollingTimeoutPolicy(timeouts);
@@ -84,14 +124,29 @@ export class MailboxPoller {
84
124
  * @param onBatch Awaited endpoint-batch consumer; the durable event cursor advances only after it succeeds. Failure or cancellation leaves that event available for later retrieval.
85
125
  * @throws Consumer/transport failures propagate; endpoint workers are joined on scope exit.
86
126
  */
87
- *pollDo(onBatch) {
127
+ *pollDo(onBatch, pacing = MAILBOX_POLLER_PACING) {
88
128
  const remoteWorkers = new Map();
129
+ // deno-lint-ignore no-this-alias -- Generator callbacks have no lexical this.
130
+ const self = this;
131
+ let habs = -1, shape = "";
89
132
  try {
90
- while (true) {
91
- const topics = this.mailboxDirector.registeredTopics();
92
- yield* this.syncRemoteWorkers(remoteWorkers, onBatch, topics);
93
- yield* runtimeTurn();
94
- }
133
+ return yield* doEvery(this.clock, pacing.tockMs, function* (tock) {
134
+ const topics = self.mailboxDirector.registeredTopics();
135
+ // Every tock looks only at what changed: the topics, the number of identifiers, and the identifiers
136
+ // prompted since. Everything else is found by the sweep on tock 0 and every `sweepTocks`.
137
+ const changed = topics.join("|") !== shape || self.hby.habs.size !== habs;
138
+ if (tock % pacing.sweepTocks === 0 || changed) {
139
+ shape = topics.join("|");
140
+ habs = self.hby.habs.size;
141
+ __classPrivateFieldGet(self, _MailboxPoller_dirty, "f").clear();
142
+ yield* self.syncRemoteWorkers(remoteWorkers, onBatch, topics);
143
+ }
144
+ else if (__classPrivateFieldGet(self, _MailboxPoller_dirty, "f").size) {
145
+ const only = new Set(__classPrivateFieldGet(self, _MailboxPoller_dirty, "f"));
146
+ __classPrivateFieldGet(self, _MailboxPoller_dirty, "f").clear();
147
+ yield* self.syncRemoteWorkers(remoteWorkers, onBatch, topics, only);
148
+ }
149
+ });
95
150
  }
96
151
  finally {
97
152
  for (const task of [...remoteWorkers.values()].reverse()) {
@@ -99,19 +154,27 @@ export class MailboxPoller {
99
154
  }
100
155
  }
101
156
  }
157
+ /**
158
+ * Tell the poller `pre`'s mailbox roles or endpoints changed, so its workers are re-selected on the next tock
159
+ * instead of at the next sweep.
160
+ */
161
+ prompt(pre) {
162
+ __classPrivateFieldGet(this, _MailboxPoller_dirty, "f").add(pre);
163
+ }
102
164
  /**
103
165
  * Stream one remote response through its consumer before recording cursor progress.
104
166
  *
105
167
  * @param target Mailbox subject habitat plus the actual local signer (a member for groups).
106
168
  * @param endpoint Selected remote endpoint AID and HTTP(S) URL.
107
169
  * @param onBatch Awaited consumer; successful completion precedes durable cursor advancement.
170
+ * @returns How the poll ended; see {@link PollOutcome}.
108
171
  */
109
172
  *pollRemoteEndpointOnce(target, endpoint, onBatch) {
110
173
  const cursor = this.mailboxDirector.remoteQueryCursor(target.targetPre, endpoint.eid);
111
174
  // deno-lint-ignore no-this-alias -- Generator callbacks have no lexical this.
112
175
  const self = this;
113
176
  // The concrete HTTP/SSE operation owns and joins this whole poll attempt.
114
- yield* call(() => fetchMailboxMessages(target.signerHab, target.targetPre, endpoint.eid, endpoint.url, cursor, mailboxFetchTimeoutPolicy(this.timeoutPolicy), this.http, this.clock, function* deliverThenAdvanceCursor(message) {
177
+ return yield* call(() => fetchMailboxMessages(target.signerHab, target.targetPre, endpoint.eid, endpoint.url, cursor, mailboxFetchTimeoutPolicy(this.timeoutPolicy), this.http, this.clock, function* deliverThenAdvanceCursor(message) {
115
178
  yield* call(() => onBatch({ pre: target.targetPre, eid: endpoint.eid, messages: [message.msg] }));
116
179
  self.mailboxDirector.updateRemoteCursor(target.targetPre, endpoint.eid, message.topic, message.idx);
117
180
  }));
@@ -123,10 +186,10 @@ export class MailboxPoller {
123
186
  * @param onBatch Shared awaited consumer used independently by each endpoint worker.
124
187
  * @param topics Current registered topics; no topics means no remote workers.
125
188
  */
126
- *syncRemoteWorkers(remoteWorkers, onBatch, topics) {
189
+ *syncRemoteWorkers(remoteWorkers, onBatch, topics, only) {
127
190
  const active = new Set();
128
191
  if (topics.length > 0) {
129
- for (const target of this.remotePollTargets()) {
192
+ for (const target of this.remotePollTargets(only)) {
130
193
  for (const endpoint of mailboxPollEndpoints(target.hab)) {
131
194
  const workerKey = `${target.targetPre}:${endpoint.key}`;
132
195
  active.add(workerKey);
@@ -139,7 +202,7 @@ export class MailboxPoller {
139
202
  }
140
203
  }
141
204
  for (const [workerKey, task] of [...remoteWorkers.entries()]) {
142
- if (active.has(workerKey)) {
205
+ if (active.has(workerKey) || (only && !only.has(workerKey.slice(0, workerKey.indexOf(":"))))) {
143
206
  continue;
144
207
  }
145
208
  yield* task.halt();
@@ -150,26 +213,50 @@ export class MailboxPoller {
150
213
  * Poll one remote endpoint continuously in the long-lived runtime shape.
151
214
  *
152
215
  * This keeps KERIpy's "one poller per endpoint" behavior while preserving
153
- * `keri-ts`'s split between mailbox transport and runtime parser ownership.
216
+ * `keri-ts`'s split between mailbox transport and runtime parser ownership. Each poll ends in a
217
+ * {@link PollOutcome}; {@link nextPoll} maps it and the backoff state to the next action. A mailbox that is
218
+ * unreachable or refuses is retried on {@link MailboxPoller.RefusalBackoff}, never in a tight loop and never
219
+ * by failing the runtime. A 403 also prompts the KEL publisher, which owns posting the KEL.
154
220
  *
155
221
  * @param target Mailbox subject habitat plus the actual local signer (a member for groups).
156
222
  * @param endpoint Selected remote endpoint AID and HTTP(S) URL.
157
223
  * @param onBatch Awaited consumer; successful completion precedes durable cursor advancement.
158
224
  */
159
225
  *remoteEndpointWorker(target, endpoint, onBatch) {
226
+ let state = { backoffMs: 0 };
160
227
  while (true) {
161
- yield* this.pollRemoteEndpointOnce(target, endpoint, onBatch);
162
- yield* runtimeTurn();
228
+ const outcome = yield* this.pollRemoteEndpointOnce(target, endpoint, onBatch);
229
+ const step = nextPoll(state, outcome, {
230
+ initialMs: this.timeoutPolicy.refusalInitialMs,
231
+ maxMs: this.timeoutPolicy.refusalMaxMs,
232
+ });
233
+ state = step.state;
234
+ switch (step.action.kind) {
235
+ case "poll":
236
+ this.onPolled?.(target.targetPre, endpoint.eid);
237
+ yield* runtimeTurn();
238
+ break;
239
+ case "prompt-publisher":
240
+ this.onUnauthorized?.(target.targetPre, endpoint.eid);
241
+ yield* waitOnClock(this.clock, step.action.ms);
242
+ break;
243
+ case "wait":
244
+ yield* waitOnClock(this.clock, step.action.ms);
245
+ break;
246
+ }
163
247
  }
164
248
  }
165
249
  /**
166
250
  * Select locally pollable subjects without substituting the group for its member signer.
167
251
  *
252
+ * @param only When given, only these identifiers are considered.
168
253
  * @returns Local subject/signing pairs; groups without an available local member are omitted.
169
254
  */
170
- remotePollTargets() {
255
+ remotePollTargets(only) {
171
256
  const targets = [];
172
257
  for (const hab of this.hby.habs.values()) {
258
+ if (only && !only.has(hab.pre))
259
+ continue;
173
260
  const signerHab = this.pollSignerHab(hab);
174
261
  if (!signerHab) {
175
262
  continue;
@@ -195,6 +282,7 @@ export class MailboxPoller {
195
282
  return this.hby.habs.get(mid) ?? null;
196
283
  }
197
284
  }
285
+ _MailboxPoller_dirty = new WeakMap();
198
286
  /**
199
287
  * Default header acquisition (5 seconds) and absolute poll window (30 seconds).
200
288
  */
@@ -205,10 +293,13 @@ Object.defineProperty(MailboxPoller, "DefaultTimeoutPolicy", {
205
293
  value: Object.freeze({
206
294
  requestOpenTimeoutMs: 5_000,
207
295
  maxPollDurationMs: 30_000,
296
+ readIdleTimeoutMs: 500,
297
+ refusalInitialMs: 1_000,
298
+ refusalMaxMs: 30_000,
208
299
  })
209
300
  });
210
301
  /**
211
- * Idle read window after the first complete event, in milliseconds.
302
+ * Default idle read window after the first complete event, in milliseconds.
212
303
  */
213
304
  Object.defineProperty(MailboxPoller, "ReadIdleTimeoutMs", {
214
305
  enumerable: true,
@@ -216,15 +307,61 @@ Object.defineProperty(MailboxPoller, "ReadIdleTimeoutMs", {
216
307
  writable: true,
217
308
  value: 500
218
309
  });
310
+ /**
311
+ * Wait after a poll that was not served (a refused status, a 403, no response headers, or an unreachable
312
+ * host), in milliseconds: it starts at `initialMs`, doubles with each consecutive failure up to `maxMs` and
313
+ * starts over after a served poll. Without a wait the worker would repeat the same signed request as fast as
314
+ * the loop turns.
315
+ */
316
+ Object.defineProperty(MailboxPoller, "RefusalBackoff", {
317
+ enumerable: true,
318
+ configurable: true,
319
+ writable: true,
320
+ value: Object.freeze({
321
+ initialMs: 1_000,
322
+ maxMs: 30_000,
323
+ })
324
+ });
325
+ /** Classify a non-success status: 403 is the mailbox not recognising the requester; anything else is a refusal. */
326
+ export function classifyPollRefusal(status) {
327
+ switch (status) {
328
+ case 403:
329
+ return "unauthorized";
330
+ default:
331
+ return "refused";
332
+ }
333
+ }
334
+ /** Double the backoff (or start it) and wait that long. */
335
+ export function backOff(state, backoff = MailboxPoller.RefusalBackoff) {
336
+ const backoffMs = Math.min(backoff.maxMs, state.backoffMs ? state.backoffMs * 2 : backoff.initialMs);
337
+ return { state: { backoffMs }, action: { kind: "wait", ms: backoffMs } };
338
+ }
339
+ /** The transition: where a poll's outcome leaves the worker, and what it does about it. */
340
+ export function nextPoll(state, outcome, backoff = MailboxPoller.RefusalBackoff) {
341
+ switch (outcome) {
342
+ case "served":
343
+ return { state: { backoffMs: 0 }, action: { kind: "poll" } };
344
+ case "unauthorized": {
345
+ const step = backOff(state, backoff);
346
+ return { state: step.state, action: { kind: "prompt-publisher", ms: step.state.backoffMs } };
347
+ }
348
+ case "no-response":
349
+ case "unreachable":
350
+ case "refused":
351
+ return backOff(state, backoff);
352
+ }
353
+ }
219
354
  /**
220
355
  * Query one endpoint and consume complete SSE events within one request scope.
221
- * Header timeout or non-success status ends this attempt without events. Successful
356
+ * A header timeout, a failed connection or a non-success status ends this attempt without events. Successful
222
357
  * body processing and its cleanup finish before the endpoint worker begins another poll.
223
- * The sole alternate submission is the exact pre-intake KERIpy media refusal:
358
+ * The sole second request is the exact pre-intake KERIpy media refusal:
224
359
  * drain/close that request, then reuse the same signed query and attachments with
225
360
  * legacy metadata. Authentication or protocol refusals do not take that branch.
226
361
  * consume runs inline and is awaited before the caller persists its cursor; this
227
362
  * callback is a scoped event-consumer boundary, not deferred workflow scheduling.
363
+ * A `TransportError` from the connection (opening it or reading its body) is an outcome; a failure of
364
+ * `consume`, cancellation and cleanup failures propagate.
228
365
  *
229
366
  * @param hab Local signing habitat; its state/store lifetime remains with the caller.
230
367
  * @param targetPre Mailbox subject AID; may be a group distinct from hab.
@@ -235,37 +372,62 @@ Object.defineProperty(MailboxPoller, "ReadIdleTimeoutMs", {
235
372
  * @param http Borrowed HTTP implementation selected by composition.
236
373
  * @param clock Borrowed clock with epoch-millisecond now and millisecond timer delays.
237
374
  * @param consume Awaited complete-event consumer; false stops the poll and errors propagate before remote cursor advancement.
375
+ * @returns How the poll ended.
238
376
  */
239
377
  function* fetchMailboxMessages(hab, targetPre, src, url, topics, timeouts, http, clock, consume) {
240
378
  const query = hab.query(targetPre, src, { route: "mbx", q: { topics } });
241
379
  const prepared = buildCesrRequest(query, { destination: src });
242
- for (const contentType of [CESR_CONTENT_TYPE, KERIPY_CESR_JSON_CONTENT_TYPE]) {
243
- const alternate = yield* scoped(function* () {
244
- const controller = new AbortController();
245
- const request = {
246
- method: "POST",
247
- headers: { ...prepared.headers, "Content-Type": contentType },
248
- body: prepared.body,
249
- signal: controller.signal,
250
- };
251
- const response = yield* requestWithHeaderTimeout(http, clock, url, request, timeouts.requestOpenTimeoutMs);
252
- if (!response)
253
- return false;
254
- if (!response.ok) {
255
- const detail = yield* abortable(signal => readResponseDetail(response, signal));
256
- return isLegacyCesrMediaRejection(request, response.status, detail);
257
- }
258
- yield* consumeMailboxSse(response, controller, consume, clock, {
259
- idleTimeoutMs: timeouts.readIdleTimeoutMs,
260
- maxDurationMs: timeouts.maxReadDurationMs,
380
+ // A consumer's own TransportError is the consumer's failure, not the mailbox's.
381
+ let consumerFailure;
382
+ const guarded = function* (message) {
383
+ try {
384
+ return yield* consume(message);
385
+ }
386
+ catch (error) {
387
+ consumerFailure = error;
388
+ throw error;
389
+ }
390
+ };
391
+ const attempt = function* (contentType) {
392
+ try {
393
+ // Closing a refused request is part of the scoped operation. A close failure escapes before another
394
+ // request can submit these same signed bytes.
395
+ return yield* scoped(function* () {
396
+ const controller = new AbortController();
397
+ const request = {
398
+ method: "POST",
399
+ headers: { ...prepared.headers, "Content-Type": contentType },
400
+ body: prepared.body,
401
+ signal: controller.signal,
402
+ };
403
+ const response = yield* requestWithHeaderTimeout(http, clock, url, request, timeouts.requestOpenTimeoutMs);
404
+ if (!response)
405
+ return { kind: "outcome", outcome: "no-response" };
406
+ if (!response.ok) {
407
+ const detail = yield* abortable(signal => readResponseDetail(response, signal));
408
+ if (isLegacyCesrMediaRejection(request, response.status, detail))
409
+ return { kind: "legacy-media-required" };
410
+ return { kind: "outcome", outcome: classifyPollRefusal(response.status) };
411
+ }
412
+ yield* consumeMailboxSse(response, controller, guarded, clock, {
413
+ idleTimeoutMs: timeouts.readIdleTimeoutMs,
414
+ maxDurationMs: timeouts.maxReadDurationMs,
415
+ });
416
+ return { kind: "outcome", outcome: "served" };
261
417
  });
262
- return false;
263
- });
264
- // Closing the refused request is part of the scoped operation above. A close
265
- // failure escapes before another request can submit these same signed bytes.
266
- if (!alternate)
267
- return;
268
- }
418
+ }
419
+ catch (error) {
420
+ if (error instanceof TransportError && error !== consumerFailure) {
421
+ return { kind: "outcome", outcome: "unreachable" };
422
+ }
423
+ throw error;
424
+ }
425
+ };
426
+ const first = yield* attempt(CESR_CONTENT_TYPE);
427
+ if (first.kind === "outcome")
428
+ return first.outcome;
429
+ const second = yield* attempt(KERIPY_CESR_JSON_CONTENT_TYPE);
430
+ return second.kind === "outcome" ? second.outcome : "refused";
269
431
  }
270
432
  /**
271
433
  * Normalize the caller's polling policy against the existing defaults.
@@ -278,19 +440,22 @@ function normalizeMailboxPollingTimeoutPolicy(overrides) {
278
440
  return Object.freeze({
279
441
  requestOpenTimeoutMs: positiveTimeoutMs(overrides?.requestOpenTimeoutMs, defaults.requestOpenTimeoutMs),
280
442
  maxPollDurationMs: positiveTimeoutMs(overrides?.maxPollDurationMs, defaults.maxPollDurationMs),
443
+ readIdleTimeoutMs: positiveTimeoutMs(overrides?.readIdleTimeoutMs, defaults.readIdleTimeoutMs),
444
+ refusalInitialMs: positiveTimeoutMs(overrides?.refusalInitialMs, defaults.refusalInitialMs),
445
+ refusalMaxMs: positiveTimeoutMs(overrides?.refusalMaxMs, defaults.refusalMaxMs),
281
446
  });
282
447
  }
283
448
  /**
284
449
  * Translate poller windows into the concrete request/SSE settings.
285
450
  *
286
451
  * @param timeouts Normalized poller policy.
287
- * @returns Per-attempt windows with the fixed 500 ms read-idle interval.
452
+ * @returns Per-attempt windows with the policy's read-idle interval.
288
453
  */
289
454
  function mailboxFetchTimeoutPolicy(timeouts) {
290
455
  return {
291
456
  requestOpenTimeoutMs: timeouts.requestOpenTimeoutMs,
292
457
  maxReadDurationMs: timeouts.maxPollDurationMs,
293
- readIdleTimeoutMs: MailboxPoller.ReadIdleTimeoutMs,
458
+ readIdleTimeoutMs: timeouts.readIdleTimeoutMs,
294
459
  };
295
460
  }
296
461
  /**