@enbox/dwn-sdk-js 0.0.7 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. package/dist/browser.mjs +8 -8
  2. package/dist/browser.mjs.map +4 -4
  3. package/dist/esm/generated/precompiled-validators.js +817 -911
  4. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  5. package/dist/esm/src/core/constants.js +11 -0
  6. package/dist/esm/src/core/constants.js.map +1 -0
  7. package/dist/esm/src/core/core-protocol.js +44 -0
  8. package/dist/esm/src/core/core-protocol.js.map +1 -0
  9. package/dist/esm/src/core/dwn-error.js +12 -12
  10. package/dist/esm/src/core/dwn-error.js.map +1 -1
  11. package/dist/esm/src/core/grant-authorization.js +16 -3
  12. package/dist/esm/src/core/grant-authorization.js.map +1 -1
  13. package/dist/esm/src/core/protocol-authorization-action.js +5 -0
  14. package/dist/esm/src/core/protocol-authorization-action.js.map +1 -1
  15. package/dist/esm/src/core/protocol-authorization-validation.js +91 -0
  16. package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
  17. package/dist/esm/src/core/protocol-authorization.js +53 -30
  18. package/dist/esm/src/core/protocol-authorization.js.map +1 -1
  19. package/dist/esm/src/core/records-grant-authorization.js +6 -8
  20. package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
  21. package/dist/esm/src/core/resumable-task-manager.js +2 -0
  22. package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
  23. package/dist/esm/src/dwn.js +42 -18
  24. package/dist/esm/src/dwn.js.map +1 -1
  25. package/dist/esm/src/event-stream/event-emitter-event-log.js +204 -0
  26. package/dist/esm/src/event-stream/event-emitter-event-log.js.map +1 -0
  27. package/dist/esm/src/handlers/messages-read.js +7 -11
  28. package/dist/esm/src/handlers/messages-read.js.map +1 -1
  29. package/dist/esm/src/handlers/messages-subscribe.js +22 -24
  30. package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
  31. package/dist/esm/src/handlers/messages-sync.js +11 -15
  32. package/dist/esm/src/handlers/messages-sync.js.map +1 -1
  33. package/dist/esm/src/handlers/protocols-configure.js +37 -27
  34. package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
  35. package/dist/esm/src/handlers/protocols-query.js +7 -11
  36. package/dist/esm/src/handlers/protocols-query.js.map +1 -1
  37. package/dist/esm/src/handlers/records-count.js +10 -12
  38. package/dist/esm/src/handlers/records-count.js.map +1 -1
  39. package/dist/esm/src/handlers/records-delete.js +10 -18
  40. package/dist/esm/src/handlers/records-delete.js.map +1 -1
  41. package/dist/esm/src/handlers/records-query.js +11 -15
  42. package/dist/esm/src/handlers/records-query.js.map +1 -1
  43. package/dist/esm/src/handlers/records-read.js +31 -26
  44. package/dist/esm/src/handlers/records-read.js.map +1 -1
  45. package/dist/esm/src/handlers/records-subscribe.js +39 -26
  46. package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
  47. package/dist/esm/src/handlers/records-write.js +128 -105
  48. package/dist/esm/src/handlers/records-write.js.map +1 -1
  49. package/dist/esm/src/index.js +5 -2
  50. package/dist/esm/src/index.js.map +1 -1
  51. package/dist/esm/src/interfaces/messages-subscribe.js +1 -0
  52. package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
  53. package/dist/esm/src/interfaces/protocols-configure.js +33 -3
  54. package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
  55. package/dist/esm/src/interfaces/records-count.js +1 -1
  56. package/dist/esm/src/interfaces/records-count.js.map +1 -1
  57. package/dist/esm/src/interfaces/records-delete.js +1 -1
  58. package/dist/esm/src/interfaces/records-delete.js.map +1 -1
  59. package/dist/esm/src/interfaces/records-query.js +1 -1
  60. package/dist/esm/src/interfaces/records-query.js.map +1 -1
  61. package/dist/esm/src/interfaces/records-read.js +1 -1
  62. package/dist/esm/src/interfaces/records-read.js.map +1 -1
  63. package/dist/esm/src/interfaces/records-subscribe.js +2 -1
  64. package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
  65. package/dist/esm/src/interfaces/records-write-signing.js +1 -12
  66. package/dist/esm/src/interfaces/records-write-signing.js.map +1 -1
  67. package/dist/esm/src/interfaces/records-write.js +25 -41
  68. package/dist/esm/src/interfaces/records-write.js.map +1 -1
  69. package/dist/esm/src/protocols/permission-grant.js +1 -1
  70. package/dist/esm/src/protocols/permission-grant.js.map +1 -1
  71. package/dist/esm/src/protocols/permission-request.js +1 -1
  72. package/dist/esm/src/protocols/permission-request.js.map +1 -1
  73. package/dist/esm/src/protocols/permissions.js +113 -5
  74. package/dist/esm/src/protocols/permissions.js.map +1 -1
  75. package/dist/esm/src/state-index/state-index-level.js +5 -7
  76. package/dist/esm/src/state-index/state-index-level.js.map +1 -1
  77. package/dist/esm/src/store/data-store-level.js +110 -33
  78. package/dist/esm/src/store/data-store-level.js.map +1 -1
  79. package/dist/esm/src/store/index-level.js +42 -32
  80. package/dist/esm/src/store/index-level.js.map +1 -1
  81. package/dist/esm/src/store/storage-controller.js +70 -6
  82. package/dist/esm/src/store/storage-controller.js.map +1 -1
  83. package/dist/esm/src/types/permission-types.js.map +1 -1
  84. package/dist/esm/src/types/protocols-types.js +11 -0
  85. package/dist/esm/src/types/protocols-types.js.map +1 -1
  86. package/dist/esm/src/types/records-types.js.map +1 -1
  87. package/dist/esm/src/utils/hd-key.js +0 -8
  88. package/dist/esm/src/utils/hd-key.js.map +1 -1
  89. package/dist/esm/src/utils/messages.js +16 -34
  90. package/dist/esm/src/utils/messages.js.map +1 -1
  91. package/dist/esm/src/utils/records.js +5 -43
  92. package/dist/esm/src/utils/records.js.map +1 -1
  93. package/dist/esm/tests/core/protocol-authorization.spec.js +2 -1
  94. package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
  95. package/dist/esm/tests/dwn.spec.js +32 -43
  96. package/dist/esm/tests/dwn.spec.js.map +1 -1
  97. package/dist/esm/tests/event-emitter-event-log.spec.js +305 -0
  98. package/dist/esm/tests/event-emitter-event-log.spec.js.map +1 -0
  99. package/dist/esm/tests/features/author-delegated-grant.spec.js +14 -7
  100. package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
  101. package/dist/esm/tests/features/owner-delegated-grant.spec.js +9 -5
  102. package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
  103. package/dist/esm/tests/features/owner-signature.spec.js +14 -7
  104. package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
  105. package/dist/esm/tests/features/permissions.spec.js +12 -12
  106. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  107. package/dist/esm/tests/features/protocol-composition.spec.js +636 -5
  108. package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
  109. package/dist/esm/tests/features/protocol-create-action.spec.js +4 -4
  110. package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
  111. package/dist/esm/tests/features/protocol-delete-action.spec.js +7 -7
  112. package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
  113. package/dist/esm/tests/features/protocol-update-action.spec.js +4 -4
  114. package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
  115. package/dist/esm/tests/features/records-delivery.spec.js +236 -0
  116. package/dist/esm/tests/features/records-delivery.spec.js.map +1 -0
  117. package/dist/esm/tests/features/records-immutable.spec.js +315 -0
  118. package/dist/esm/tests/features/records-immutable.spec.js.map +1 -0
  119. package/dist/esm/tests/features/records-prune.spec.js +4 -4
  120. package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
  121. package/dist/esm/tests/features/records-record-limit.spec.js +542 -0
  122. package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -0
  123. package/dist/esm/tests/features/records-squash.spec.js +1055 -0
  124. package/dist/esm/tests/features/records-squash.spec.js.map +1 -0
  125. package/dist/esm/tests/features/records-tags.spec.js +16 -4
  126. package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
  127. package/dist/esm/tests/features/resumable-tasks.spec.js +7 -8
  128. package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
  129. package/dist/esm/tests/handlers/messages-read.spec.js +11 -5
  130. package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
  131. package/dist/esm/tests/handlers/messages-subscribe.spec.js +169 -22
  132. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  133. package/dist/esm/tests/handlers/messages-sync.spec.js +103 -21
  134. package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
  135. package/dist/esm/tests/handlers/protocols-configure.spec.js +5 -5
  136. package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
  137. package/dist/esm/tests/handlers/protocols-query.spec.js +5 -5
  138. package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
  139. package/dist/esm/tests/handlers/records-count.spec.js +9 -4
  140. package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
  141. package/dist/esm/tests/handlers/records-delete.spec.js +24 -25
  142. package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
  143. package/dist/esm/tests/handlers/records-query.spec.js +68 -9
  144. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  145. package/dist/esm/tests/handlers/records-read.spec.js +24 -138
  146. package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
  147. package/dist/esm/tests/handlers/records-subscribe.spec.js +175 -35
  148. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  149. package/dist/esm/tests/handlers/records-write.spec.js +176 -72
  150. package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
  151. package/dist/esm/tests/interfaces/records-write.spec.js +52 -68
  152. package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
  153. package/dist/esm/tests/protocols/permission-grant.spec.js +6 -6
  154. package/dist/esm/tests/protocols/permission-grant.spec.js.map +1 -1
  155. package/dist/esm/tests/protocols/permission-request.spec.js +4 -4
  156. package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
  157. package/dist/esm/tests/protocols/permissions.spec.js +4 -4
  158. package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
  159. package/dist/esm/tests/scenarios/aggregator.spec.js +4 -4
  160. package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
  161. package/dist/esm/tests/scenarios/deleted-record.spec.js +350 -5
  162. package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
  163. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +4 -4
  164. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
  165. package/dist/esm/tests/scenarios/nested-roles.spec.js +4 -4
  166. package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
  167. package/dist/esm/tests/scenarios/subscriptions.spec.js +93 -40
  168. package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
  169. package/dist/esm/tests/store/data-store-level.spec.js +102 -41
  170. package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
  171. package/dist/esm/tests/test-event-stream.js +12 -13
  172. package/dist/esm/tests/test-event-stream.js.map +1 -1
  173. package/dist/esm/tests/test-suite.js +10 -4
  174. package/dist/esm/tests/test-suite.js.map +1 -1
  175. package/dist/esm/tests/utils/messages.spec.js +12 -5
  176. package/dist/esm/tests/utils/messages.spec.js.map +1 -1
  177. package/dist/esm/tests/utils/records.spec.js +8 -12
  178. package/dist/esm/tests/utils/records.spec.js.map +1 -1
  179. package/dist/esm/tests/utils/test-data-generator.js +36 -2
  180. package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
  181. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +37 -8
  182. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
  183. package/dist/types/generated/precompiled-validators.d.ts +49 -40
  184. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  185. package/dist/types/src/core/constants.d.ts +11 -0
  186. package/dist/types/src/core/constants.d.ts.map +1 -0
  187. package/dist/types/src/core/core-protocol.d.ts +89 -0
  188. package/dist/types/src/core/core-protocol.d.ts.map +1 -0
  189. package/dist/types/src/core/dwn-error.d.ts +12 -12
  190. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  191. package/dist/types/src/core/grant-authorization.d.ts +6 -2
  192. package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
  193. package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -1
  194. package/dist/types/src/core/protocol-authorization-validation.d.ts +30 -0
  195. package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
  196. package/dist/types/src/core/protocol-authorization.d.ts +19 -11
  197. package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
  198. package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
  199. package/dist/types/src/core/resumable-task-manager.d.ts +2 -1
  200. package/dist/types/src/core/resumable-task-manager.d.ts.map +1 -1
  201. package/dist/types/src/dwn.d.ts +19 -7
  202. package/dist/types/src/dwn.d.ts.map +1 -1
  203. package/dist/types/src/event-stream/event-emitter-event-log.d.ts +50 -0
  204. package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +1 -0
  205. package/dist/types/src/handlers/messages-read.d.ts +3 -8
  206. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  207. package/dist/types/src/handlers/messages-subscribe.d.ts +6 -10
  208. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  209. package/dist/types/src/handlers/messages-sync.d.ts +3 -8
  210. package/dist/types/src/handlers/messages-sync.d.ts.map +1 -1
  211. package/dist/types/src/handlers/protocols-configure.d.ts +3 -10
  212. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  213. package/dist/types/src/handlers/protocols-query.d.ts +3 -8
  214. package/dist/types/src/handlers/protocols-query.d.ts.map +1 -1
  215. package/dist/types/src/handlers/records-count.d.ts +3 -6
  216. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  217. package/dist/types/src/handlers/records-delete.d.ts +3 -8
  218. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  219. package/dist/types/src/handlers/records-query.d.ts +3 -8
  220. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  221. package/dist/types/src/handlers/records-read.d.ts +3 -8
  222. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  223. package/dist/types/src/handlers/records-subscribe.d.ts +8 -10
  224. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  225. package/dist/types/src/handlers/records-write.d.ts +12 -25
  226. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  227. package/dist/types/src/index.d.ts +8 -4
  228. package/dist/types/src/index.d.ts.map +1 -1
  229. package/dist/types/src/interfaces/messages-subscribe.d.ts +5 -0
  230. package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
  231. package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
  232. package/dist/types/src/interfaces/records-subscribe.d.ts +5 -0
  233. package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
  234. package/dist/types/src/interfaces/records-write-signing.d.ts +3 -4
  235. package/dist/types/src/interfaces/records-write-signing.d.ts.map +1 -1
  236. package/dist/types/src/interfaces/records-write.d.ts +11 -11
  237. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  238. package/dist/types/src/protocols/permission-grant.d.ts +1 -1
  239. package/dist/types/src/protocols/permission-grant.d.ts.map +1 -1
  240. package/dist/types/src/protocols/permission-request.d.ts +1 -1
  241. package/dist/types/src/protocols/permission-request.d.ts.map +1 -1
  242. package/dist/types/src/protocols/permissions.d.ts +40 -3
  243. package/dist/types/src/protocols/permissions.d.ts.map +1 -1
  244. package/dist/types/src/state-index/state-index-level.d.ts.map +1 -1
  245. package/dist/types/src/store/data-store-level.d.ts +20 -4
  246. package/dist/types/src/store/data-store-level.d.ts.map +1 -1
  247. package/dist/types/src/store/index-level.d.ts +4 -0
  248. package/dist/types/src/store/index-level.d.ts.map +1 -1
  249. package/dist/types/src/store/storage-controller.d.ts +20 -6
  250. package/dist/types/src/store/storage-controller.d.ts.map +1 -1
  251. package/dist/types/src/types/message-types.d.ts +3 -3
  252. package/dist/types/src/types/message-types.d.ts.map +1 -1
  253. package/dist/types/src/types/messages-types.d.ts +12 -3
  254. package/dist/types/src/types/messages-types.d.ts.map +1 -1
  255. package/dist/types/src/types/method-handler.d.ts +24 -3
  256. package/dist/types/src/types/method-handler.d.ts.map +1 -1
  257. package/dist/types/src/types/permission-types.d.ts +7 -0
  258. package/dist/types/src/types/permission-types.d.ts.map +1 -1
  259. package/dist/types/src/types/protocols-types.d.ts +69 -2
  260. package/dist/types/src/types/protocols-types.d.ts.map +1 -1
  261. package/dist/types/src/types/records-types.d.ts +23 -6
  262. package/dist/types/src/types/records-types.d.ts.map +1 -1
  263. package/dist/types/src/types/subscriptions.d.ts +151 -13
  264. package/dist/types/src/types/subscriptions.d.ts.map +1 -1
  265. package/dist/types/src/utils/hd-key.d.ts +1 -9
  266. package/dist/types/src/utils/hd-key.d.ts.map +1 -1
  267. package/dist/types/src/utils/messages.d.ts +7 -5
  268. package/dist/types/src/utils/messages.d.ts.map +1 -1
  269. package/dist/types/src/utils/records.d.ts +1 -11
  270. package/dist/types/src/utils/records.d.ts.map +1 -1
  271. package/dist/types/tests/dwn.spec.d.ts.map +1 -1
  272. package/dist/types/tests/event-emitter-event-log.spec.d.ts +2 -0
  273. package/dist/types/tests/event-emitter-event-log.spec.d.ts.map +1 -0
  274. package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -1
  275. package/dist/types/tests/features/owner-delegated-grant.spec.d.ts.map +1 -1
  276. package/dist/types/tests/features/owner-signature.spec.d.ts.map +1 -1
  277. package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -1
  278. package/dist/types/tests/features/records-delivery.spec.d.ts +2 -0
  279. package/dist/types/tests/features/records-delivery.spec.d.ts.map +1 -0
  280. package/dist/types/tests/features/records-immutable.spec.d.ts +2 -0
  281. package/dist/types/tests/features/records-immutable.spec.d.ts.map +1 -0
  282. package/dist/types/tests/features/records-record-limit.spec.d.ts +2 -0
  283. package/dist/types/tests/features/records-record-limit.spec.d.ts.map +1 -0
  284. package/dist/types/tests/features/records-squash.spec.d.ts +2 -0
  285. package/dist/types/tests/features/records-squash.spec.d.ts.map +1 -0
  286. package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -1
  287. package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -1
  288. package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
  289. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  290. package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -1
  291. package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
  292. package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
  293. package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
  294. package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
  295. package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
  296. package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
  297. package/dist/types/tests/scenarios/deleted-record.spec.d.ts.map +1 -1
  298. package/dist/types/tests/scenarios/subscriptions.spec.d.ts.map +1 -1
  299. package/dist/types/tests/test-event-stream.d.ts +11 -12
  300. package/dist/types/tests/test-event-stream.d.ts.map +1 -1
  301. package/dist/types/tests/test-suite.d.ts +2 -2
  302. package/dist/types/tests/test-suite.d.ts.map +1 -1
  303. package/dist/types/tests/utils/test-data-generator.d.ts +19 -0
  304. package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
  305. package/package.json +5 -4
  306. package/src/core/constants.ts +11 -0
  307. package/src/core/core-protocol.ts +129 -0
  308. package/src/core/dwn-error.ts +18 -12
  309. package/src/core/grant-authorization.ts +20 -3
  310. package/src/core/protocol-authorization-action.ts +5 -0
  311. package/src/core/protocol-authorization-validation.ts +133 -0
  312. package/src/core/protocol-authorization.ts +71 -23
  313. package/src/core/records-grant-authorization.ts +6 -8
  314. package/src/core/resumable-task-manager.ts +3 -1
  315. package/src/dwn.ts +58 -73
  316. package/src/event-stream/event-emitter-event-log.ts +283 -0
  317. package/src/handlers/messages-read.ts +8 -9
  318. package/src/handlers/messages-subscribe.ts +24 -28
  319. package/src/handlers/messages-sync.ts +10 -16
  320. package/src/handlers/protocols-configure.ts +47 -32
  321. package/src/handlers/protocols-query.ts +6 -9
  322. package/src/handlers/records-count.ts +11 -10
  323. package/src/handlers/records-delete.ts +12 -21
  324. package/src/handlers/records-query.ts +12 -12
  325. package/src/handlers/records-read.ts +34 -22
  326. package/src/handlers/records-subscribe.ts +47 -26
  327. package/src/handlers/records-write.ts +152 -119
  328. package/src/index.ts +9 -5
  329. package/src/interfaces/messages-subscribe.ts +7 -1
  330. package/src/interfaces/protocols-configure.ts +51 -3
  331. package/src/interfaces/records-count.ts +1 -1
  332. package/src/interfaces/records-delete.ts +1 -1
  333. package/src/interfaces/records-query.ts +1 -1
  334. package/src/interfaces/records-read.ts +1 -1
  335. package/src/interfaces/records-subscribe.ts +8 -1
  336. package/src/interfaces/records-write-signing.ts +2 -22
  337. package/src/interfaces/records-write.ts +35 -48
  338. package/src/protocols/permission-grant.ts +1 -1
  339. package/src/protocols/permission-request.ts +1 -1
  340. package/src/protocols/permissions.ts +148 -6
  341. package/src/state-index/state-index-level.ts +5 -7
  342. package/src/store/data-store-level.ts +124 -34
  343. package/src/store/index-level.ts +44 -35
  344. package/src/store/storage-controller.ts +89 -12
  345. package/src/types/message-types.ts +3 -3
  346. package/src/types/messages-types.ts +12 -3
  347. package/src/types/method-handler.ts +26 -4
  348. package/src/types/mitt.d.ts +28 -0
  349. package/src/types/permission-types.ts +7 -0
  350. package/src/types/protocols-types.ts +78 -1
  351. package/src/types/records-types.ts +24 -6
  352. package/src/types/subscriptions.ts +178 -14
  353. package/src/utils/hd-key.ts +0 -9
  354. package/src/utils/messages.ts +17 -37
  355. package/src/utils/records.ts +7 -58
  356. package/dist/esm/src/event-stream/event-emitter-stream.js +0 -46
  357. package/dist/esm/src/event-stream/event-emitter-stream.js.map +0 -1
  358. package/dist/esm/tests/event-stream/event-emitter-stream.spec.js +0 -68
  359. package/dist/esm/tests/event-stream/event-emitter-stream.spec.js.map +0 -1
  360. package/dist/esm/tests/event-stream/event-stream.spec.js +0 -114
  361. package/dist/esm/tests/event-stream/event-stream.spec.js.map +0 -1
  362. package/dist/types/src/event-stream/event-emitter-stream.d.ts +0 -23
  363. package/dist/types/src/event-stream/event-emitter-stream.d.ts.map +0 -1
  364. package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts +0 -2
  365. package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts.map +0 -1
  366. package/dist/types/tests/event-stream/event-stream.spec.d.ts +0 -2
  367. package/dist/types/tests/event-stream/event-stream.spec.d.ts.map +0 -1
  368. package/src/event-stream/event-emitter-stream.ts +0 -69
@@ -1,11 +1,13 @@
1
1
  import type { DataStore } from '../types/data-store.js';
2
- import type { EventStream } from '../types/subscriptions.js';
2
+ import type { EventLog } from '../types/subscriptions.js';
3
+ import type { Filter } from '../types/query-types.js';
3
4
  import type { GenericMessage } from '../types/message-types.js';
4
5
  import type { MessageStore } from '../types/message-store.js';
5
6
  import type { StateIndex } from '../types/state-index.js';
6
7
  import type { RecordsDeleteMessage, RecordsQueryReplyEntry, RecordsWriteMessage } from '../types/records-types.js';
7
8
 
8
9
  import { DwnConstant } from '../core/dwn-constant.js';
10
+ import { FilterUtility } from '../utils/filter.js';
9
11
  import { Message } from '../core/message.js';
10
12
  import { Records } from '../utils/records.js';
11
13
  import { RecordsDelete } from '../interfaces/records-delete.js';
@@ -18,6 +20,11 @@ export type ResumableRecordsDeleteData = {
18
20
  message: RecordsDeleteMessage;
19
21
  };
20
22
 
23
+ export type ResumableRecordsSquashData = {
24
+ tenant: string;
25
+ message: RecordsWriteMessage;
26
+ };
27
+
21
28
  /**
22
29
  * A class that provides an abstraction for the usage of MessageStore, DataStore, and StateIndex.
23
30
  */
@@ -26,18 +33,18 @@ export class StorageController {
26
33
  private messageStore: MessageStore;
27
34
  private dataStore: DataStore;
28
35
  private stateIndex: StateIndex;
29
- private eventStream?: EventStream;
36
+ private eventLog?: EventLog;
30
37
 
31
- public constructor({ messageStore, dataStore, stateIndex, eventStream }: {
32
- messageStore: MessageStore,
33
- dataStore: DataStore,
34
- stateIndex: StateIndex,
35
- eventStream?: EventStream}
38
+ public constructor({ messageStore, dataStore, stateIndex, eventLog }: {
39
+ messageStore : MessageStore,
40
+ dataStore : DataStore,
41
+ stateIndex : StateIndex,
42
+ eventLog? : EventLog}
36
43
  ) {
37
44
  this.messageStore = messageStore;
38
45
  this.dataStore = dataStore;
39
46
  this.stateIndex = stateIndex;
40
- this.eventStream = eventStream;
47
+ this.eventLog = eventLog;
41
48
  }
42
49
 
43
50
  public async performRecordsDelete({ tenant, message }: ResumableRecordsDeleteData): Promise<void> {
@@ -66,9 +73,9 @@ export class StorageController {
66
73
  await this.messageStore.put(tenant, message, indexes);
67
74
  await this.stateIndex.insert(tenant, messageCid, indexes);
68
75
 
69
- // only emit if the event stream is set
70
- if (this.eventStream !== undefined) {
71
- this.eventStream.emit(tenant, { message, initialWrite }, indexes);
76
+ // only emit if the event log is set
77
+ if (this.eventLog !== undefined) {
78
+ await this.eventLog.emit(tenant, { message, initialWrite }, indexes);
72
79
  }
73
80
 
74
81
  if (message.descriptor.prune) {
@@ -82,6 +89,76 @@ export class StorageController {
82
89
  );
83
90
  }
84
91
 
92
+ /**
93
+ * Performs the squash processing for a `RecordsWrite` with `squash: true`.
94
+ * Deletes all sibling records at the same protocol path and parent context whose
95
+ * `messageTimestamp` is strictly older than the squash record's `messageTimestamp`.
96
+ * Unlike normal `RecordsDelete` tombstones, squash targets are fully purged — no initial writes
97
+ * are retained.
98
+ *
99
+ * This method is idempotent — it can be safely re-run on resume after a crash.
100
+ */
101
+ public async performRecordsSquash({ tenant, message }: ResumableRecordsSquashData): Promise<void> {
102
+ const { protocol, protocolPath, messageTimestamp } = message.descriptor;
103
+
104
+ // Build a filter to find all sibling records at the same protocol path and parent context.
105
+ // We query by interface only (not method) so that both RecordsWrite and RecordsDelete messages are found.
106
+ const filter: Filter = {
107
+ interface : DwnInterfaceName.Records,
108
+ protocol,
109
+ protocolPath : protocolPath,
110
+ };
111
+
112
+ // Scope by parent context for nested records
113
+ const parentContextId = Records.getParentContextFromOfContextId(message.contextId);
114
+ if (parentContextId !== undefined && parentContextId !== '') {
115
+ const prefixFilter = FilterUtility.constructPrefixFilterAsRangeFilter(parentContextId);
116
+ filter.contextId = prefixFilter;
117
+ }
118
+
119
+ // Query for all records at this path and context
120
+ const { messages: siblingMessages } = await this.messageStore.query(tenant, [filter]);
121
+
122
+ // Group messages by recordId — RecordsWrite messages use `message.recordId`,
123
+ // RecordsDelete messages use `message.descriptor.recordId`.
124
+ const recordIdToMessages = new Map<string, GenericMessage[]>();
125
+ for (const msg of siblingMessages) {
126
+ let recordId: string;
127
+ if (Records.isRecordsWrite(msg)) {
128
+ recordId = msg.recordId;
129
+ } else {
130
+ recordId = (msg as RecordsDeleteMessage).descriptor.recordId;
131
+ }
132
+
133
+ const existing = recordIdToMessages.get(recordId);
134
+ if (existing !== undefined) {
135
+ existing.push(msg);
136
+ } else {
137
+ recordIdToMessages.set(recordId, [msg]);
138
+ }
139
+ }
140
+
141
+ // Delete all records whose newest message timestamp is strictly older than the squash timestamp.
142
+ // Skip the squash record itself.
143
+ for (const [recordId, messages] of recordIdToMessages) {
144
+ if (recordId === message.recordId) {
145
+ continue;
146
+ }
147
+
148
+ // Use the newest message's timestamp to determine if the record predates the squash.
149
+ const newestMessage = await Message.getNewestMessage(messages);
150
+ if (newestMessage === undefined) {
151
+ continue;
152
+ }
153
+
154
+ const newestTimestamp = newestMessage.descriptor.messageTimestamp;
155
+ if (newestTimestamp < messageTimestamp) {
156
+ // Fully purge this record — all messages (including initial write) and their data
157
+ await StorageController.purgeRecordMessages(tenant, messages, this.messageStore, this.dataStore, this.stateIndex);
158
+ }
159
+ }
160
+ }
161
+
85
162
  /**
86
163
  * Deletes the data referenced by the given message if needed.
87
164
  * @param message The message to check if the data it references should be deleted.
@@ -164,7 +241,7 @@ export class StorageController {
164
241
  * Purges (permanent hard-delete) all messages of the SAME `recordId` given and their associated data and events.
165
242
  * Assumes that the given `recordMessages` are all of the same `recordId`.
166
243
  */
167
- private static async purgeRecordMessages(
244
+ public static async purgeRecordMessages(
168
245
  tenant: string,
169
246
  recordMessages: GenericMessage[],
170
247
  messageStore: MessageStore,
@@ -65,13 +65,13 @@ export type DelegatedGrantRecordsWriteMessage = {
65
65
  signature: GeneralJws;
66
66
  },
67
67
  recordId: string,
68
- contextId?: string;
68
+ contextId: string;
69
69
  // NOTE: This is a direct expansion and copy of `DataEncodedRecordsWriteMessage` to avoid circular references.
70
70
  descriptor: {
71
71
  interface: DwnInterfaceName.Records;
72
72
  method: DwnMethodName.Write;
73
- protocol?: string;
74
- protocolPath?: string;
73
+ protocol: string;
74
+ protocolPath: string;
75
75
  recipient?: string;
76
76
  schema?: string;
77
77
  parentId?: string;
@@ -1,5 +1,5 @@
1
- import type { MessageEvent } from './subscriptions.js';
2
1
  import type { RangeCriterion } from './query-types.js';
2
+ import type { SubscriptionListener } from './subscriptions.js';
3
3
  import type { AuthorizationModel, GenericMessage, GenericMessageReply, MessageSubscription } from './message-types.js';
4
4
  import type { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
5
5
 
@@ -59,10 +59,13 @@ export type MessagesSyncReply = GenericMessageReply & {
59
59
  entries? : string[]; // messageCid[] (for 'leaves' action)
60
60
  };
61
61
 
62
- export type MessageSubscriptionHandler = (event: MessageEvent) => void;
62
+ /**
63
+ * @deprecated Use {@link SubscriptionListener} directly. Retained as an alias for migration.
64
+ */
65
+ export type MessageSubscriptionHandler = SubscriptionListener;
63
66
 
64
67
  export type MessagesSubscribeMessageOptions = {
65
- subscriptionHandler: MessageSubscriptionHandler;
68
+ subscriptionHandler: SubscriptionListener;
66
69
  };
67
70
 
68
71
  export type MessagesSubscribeMessage = {
@@ -80,4 +83,10 @@ export type MessagesSubscribeDescriptor = {
80
83
  messageTimestamp: string;
81
84
  filters: MessagesFilter[];
82
85
  permissionGrantId?: string;
86
+ /**
87
+ * Opaque EventLog cursor string to resume from. When provided, the handler replays
88
+ * events from the EventLog starting after this cursor instead of returning no
89
+ * initial snapshot. An EOSE marker is sent after catch-up.
90
+ */
91
+ cursor?: string;
83
92
  };
@@ -1,5 +1,10 @@
1
- import type { MessageSubscriptionHandler } from './messages-types.js';
2
- import type { RecordSubscriptionHandler } from './records-types.js';
1
+ import type { CoreProtocolRegistry } from '../core/core-protocol.js';
2
+ import type { DataStore } from './data-store.js';
3
+ import type { DidResolver } from '@enbox/dids';
4
+ import type { MessageStore } from './message-store.js';
5
+ import type { ResumableTaskManager } from '../core/resumable-task-manager.js';
6
+ import type { StateIndex } from './state-index.js';
7
+ import type { EventLog, SubscriptionListener } from './subscriptions.js';
3
8
  import type { GenericMessage, GenericMessageReply } from './message-types.js';
4
9
 
5
10
  /**
@@ -13,6 +18,23 @@ export interface MethodHandler {
13
18
  tenant: string;
14
19
  message: GenericMessage;
15
20
  dataStream?: ReadableStream<Uint8Array>
16
- subscriptionHandler?: MessageSubscriptionHandler | RecordSubscriptionHandler;
21
+ subscriptionHandler?: SubscriptionListener;
17
22
  }): Promise<GenericMessageReply>;
18
- }
23
+ }
24
+
25
+ /**
26
+ * Shared dependency bag for all DWN method handlers.
27
+ *
28
+ * Every handler receives the same object; each handler accesses only the
29
+ * dependencies it needs. Adding a new dependency here is a single-line
30
+ * change — no handler constructor signatures need updating.
31
+ */
32
+ export type HandlerDependencies = {
33
+ didResolver: DidResolver;
34
+ messageStore: MessageStore;
35
+ dataStore?: DataStore;
36
+ stateIndex?: StateIndex;
37
+ resumableTaskManager?: ResumableTaskManager;
38
+ coreProtocols?: CoreProtocolRegistry;
39
+ eventLog?: EventLog;
40
+ };
@@ -0,0 +1,28 @@
1
+ // mitt v3 does not include `"type": "module"` in its package.json, so under
2
+ // TypeScript's `NodeNext` module resolution the `export default function` in
3
+ // mitt's own typings is treated as a CJS namespace rather than a callable.
4
+ // This ambient module declaration re-exports the factory as a proper ESM
5
+ // default so `import mitt from 'mitt'` type-checks correctly.
6
+ declare module 'mitt' {
7
+ type EventType = string | symbol;
8
+ type Handler<T = unknown> = (event: T) => void;
9
+ type EventHandlerList<T = unknown> = Array<Handler<T>>;
10
+ type WildCardEventHandlerList<T = Record<string, unknown>> = Array<
11
+ (type: keyof T, event: T[keyof T]) => void
12
+ >;
13
+ type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<
14
+ keyof Events | '*',
15
+ EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>
16
+ >;
17
+
18
+ interface Emitter<Events extends Record<EventType, unknown>> {
19
+ all: EventHandlerMap<Events>;
20
+ on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;
21
+ off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void;
22
+ emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;
23
+ }
24
+
25
+ export default function mitt<Events extends Record<EventType, unknown>>(
26
+ all?: EventHandlerMap<Events>
27
+ ): Emitter<Events>;
28
+ }
@@ -76,6 +76,13 @@ export type ProtocolPermissionScope = {
76
76
  protocol?: string;
77
77
  };
78
78
 
79
+ /**
80
+ * Permission scope for the Messages interface.
81
+ *
82
+ * A `Read` scope is a unified scope that authorizes `MessagesRead`, `MessagesSubscribe`, and `MessagesSync` operations.
83
+ * The `Subscribe` and `Sync` method values are retained for backward compatibility with existing grants but are
84
+ * functionally equivalent to `Read` — new grants SHOULD use `Read` exclusively.
85
+ */
79
86
  export type MessagesPermissionScope = {
80
87
  interface: DwnInterfaceName.Messages;
81
88
  method: DwnMethodName.Read | DwnMethodName.Subscribe | DwnMethodName.Sync;
@@ -75,6 +75,7 @@ export enum ProtocolAction {
75
75
  Delete = 'delete',
76
76
  Prune = 'prune',
77
77
  Read = 'read',
78
+ Squash = 'squash',
78
79
  Update = 'update'
79
80
  }
80
81
 
@@ -154,6 +155,47 @@ export type ProtocolSizeDefinition = {
154
155
  max?: number;
155
156
  };
156
157
 
158
+ /**
159
+ * Supported strategies for handling writes that would exceed a `$recordLimit`.
160
+ */
161
+ export enum ProtocolRecordLimitStrategy {
162
+ /** Reject the incoming write with an error. The author must delete old records first. */
163
+ Reject = 'reject',
164
+ /** Automatically delete the oldest record(s) (by `dateCreated`) to make room for the new one. */
165
+ PurgeOldest = 'purgeOldest',
166
+ }
167
+
168
+ /**
169
+ * Limits the number of records at a given protocol path within the same parent context.
170
+ *
171
+ * For root-level records, the count is across the entire protocol for the tenant.
172
+ * For nested records, the count is scoped to the parent record's context.
173
+ *
174
+ * Only initial writes (new records) count toward the limit; updates to existing records do not.
175
+ */
176
+ export type ProtocolRecordLimitDefinition = {
177
+ /** Maximum number of records allowed at this path within the same parent context. Must be >= 1. */
178
+ max: number;
179
+
180
+ /**
181
+ * Strategy when the limit is reached.
182
+ * Currently only `'reject'` is implemented. Future strategies (e.g. `'purgeOldest'`)
183
+ * are defined in the wire format but not yet enforced.
184
+ */
185
+ strategy: ProtocolRecordLimitStrategy | `${ProtocolRecordLimitStrategy}` | (string & {});
186
+ };
187
+
188
+ /**
189
+ * Delivery strategy for records at a given protocol path.
190
+ * Controls how a DWN server proactively distributes records to participants' DWN endpoints.
191
+ *
192
+ * - `'direct'` — The origin DWN pushes new records to all participants' DWN endpoints.
193
+ * Best for small participant sets (2–50).
194
+ * - `'subscribe'` — Participant providers establish `RecordsSubscribe` connections to the
195
+ * origin DWN. Best for asymmetric fan-out or unbounded audiences.
196
+ */
197
+ export type ProtocolDeliveryStrategy = 'direct' | 'subscribe';
198
+
157
199
  /**
158
200
  * Tag rules for records at a given protocol path. Each non-`$`-prefixed property
159
201
  * is a JSON Schema object constraining that tag's value.
@@ -192,7 +234,7 @@ export type ProtocolTagSchema = {
192
234
  /**
193
235
  * Union of all value types that can appear as properties of a `ProtocolRuleSet`.
194
236
  * This includes:
195
- * - `$`-prefixed directive values (`$encryption`, `$actions`, `$role`, `$ref`, `$size`, `$tags`)
237
+ * - `$`-prefixed directive values (`$encryption`, `$actions`, `$role`, `$ref`, `$size`, `$tags`, `$delivery`)
196
238
  * - Child `ProtocolRuleSet` entries (non-`$` keys)
197
239
  */
198
240
  type ProtocolRuleSetValue =
@@ -201,6 +243,8 @@ type ProtocolRuleSetValue =
201
243
  | ProtocolPathEncryption
202
244
  | ProtocolTagsDefinition
203
245
  | ProtocolSizeDefinition
246
+ | ProtocolRecordLimitDefinition
247
+ | ProtocolDeliveryStrategy
204
248
  | boolean
205
249
  | string
206
250
  | undefined;
@@ -247,6 +291,39 @@ export type ProtocolRuleSet = {
247
291
  */
248
292
  $tags?: ProtocolTagsDefinition;
249
293
 
294
+ /**
295
+ * If $recordLimit is set, the number of records at this protocol path within the same
296
+ * parent context is constrained. When the limit is reached, the `strategy` determines
297
+ * whether the write is rejected or the oldest record is purged.
298
+ */
299
+ $recordLimit?: ProtocolRecordLimitDefinition;
300
+
301
+ /**
302
+ * If `$immutable` is `true`, records at this protocol path are write-once: they can be
303
+ * created but never updated after the initial write. `RecordsDelete` is still governed
304
+ * by `$actions` — immutability means the record's data cannot change, not that it
305
+ * cannot be removed.
306
+ */
307
+ $immutable?: boolean;
308
+
309
+ /**
310
+ * Delivery strategy hint for records at this protocol path.
311
+ * When set, the DWN server SHOULD proactively deliver records to participants' DWN endpoints.
312
+ *
313
+ * - `'direct'` — Origin DWN pushes to all participant DWN endpoints upon receipt.
314
+ * - `'subscribe'` — Participant providers subscribe to the origin DWN via `RecordsSubscribe`.
315
+ */
316
+ $delivery?: ProtocolDeliveryStrategy;
317
+
318
+ /**
319
+ * If `$squash` is `true`, enables squash writes at this protocol path.
320
+ * A squash write is a `RecordsWrite` with `squash: true` in the descriptor that
321
+ * atomically creates a new record (the snapshot) and deletes all sibling records
322
+ * at the same protocol path within the same parent context that have a
323
+ * `messageTimestamp` strictly older than the squash record's `messageTimestamp`.
324
+ */
325
+ $squash?: boolean;
326
+
250
327
  /**
251
328
  * Non-`$`-prefixed keys are nested child `ProtocolRuleSet` entries.
252
329
  * At runtime, JSON Schema validation ensures only valid child rule sets appear here.
@@ -1,5 +1,6 @@
1
1
  import type { GeneralJws } from './jws-types.js';
2
2
  import type { JweEncryption } from '../utils/encryption.js';
3
+ import type { SubscriptionListener } from './subscriptions.js';
3
4
  import type { AuthorizationModel, GenericMessage, GenericMessageReply, GenericSignaturePayload, MessageSubscription, Pagination } from './message-types.js';
4
5
  import type { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
5
6
  import type { PaginationCursor, RangeCriterion, RangeFilter, StartsWithFilter } from './query-types.js';
@@ -23,8 +24,8 @@ export type RecordsWriteTagsFilter = StartsWithFilter | RangeFilter | string | n
23
24
  export type RecordsWriteDescriptor = {
24
25
  interface: DwnInterfaceName.Records;
25
26
  method: DwnMethodName.Write;
26
- protocol?: string;
27
- protocolPath?: string;
27
+ protocol: string;
28
+ protocolPath: string;
28
29
  recipient?: string;
29
30
  schema?: string;
30
31
  tags?: RecordsWriteTags;
@@ -37,6 +38,14 @@ export type RecordsWriteDescriptor = {
37
38
  datePublished?: string;
38
39
  dataFormat: string;
39
40
  permissionGrantId?: string;
41
+
42
+ /**
43
+ * When `true`, this record is a squash (snapshot) write. The protocol rule set at this record's
44
+ * `protocolPath` must have `$squash: true`; otherwise the message is rejected.
45
+ * A squash write must be an initial write (a new record, not an update).
46
+ * This is an immutable property.
47
+ */
48
+ squash?: true;
40
49
  };
41
50
 
42
51
  export type RecordsWriteMessageOptions = {
@@ -57,7 +66,7 @@ export type InternalRecordsWriteMessage = GenericMessage & {
57
66
  export type RecordsWriteMessage = {
58
67
  authorization: AuthorizationModel; // overriding `GenericMessage` with `authorization` being required
59
68
  recordId: string,
60
- contextId?: string;
69
+ contextId: string;
61
70
  descriptor: RecordsWriteDescriptor;
62
71
  attestation?: GeneralJws;
63
72
  encryption?: JweEncryption;
@@ -122,6 +131,12 @@ export type RecordsSubscribeDescriptor = {
122
131
  filter: RecordsFilter;
123
132
  dateSort?: DateSort;
124
133
  pagination?: Pagination;
134
+ /**
135
+ * Opaque EventLog cursor string to resume from. When provided, the handler replays
136
+ * events from the EventLog starting after this cursor instead of querying the
137
+ * MessageStore for an initial snapshot. An EOSE marker is sent after catch-up.
138
+ */
139
+ cursor?: string;
125
140
  };
126
141
 
127
142
  export type RecordsFilter = {
@@ -157,7 +172,7 @@ export type RecordsWriteAttestationPayload = {
157
172
 
158
173
  export type RecordsWriteSignaturePayload = GenericSignaturePayload & {
159
174
  recordId: string;
160
- contextId?: string;
175
+ contextId: string;
161
176
  attestationCid?: string;
162
177
  encryptionCid?: string;
163
178
  };
@@ -176,10 +191,13 @@ export type RecordEvent = {
176
191
  initialWrite?: RecordsWriteMessage;
177
192
  };
178
193
 
179
- export type RecordSubscriptionHandler = (event: RecordEvent) => void;
194
+ /**
195
+ * @deprecated Use {@link SubscriptionListener} directly. Retained as an alias for migration.
196
+ */
197
+ export type RecordSubscriptionHandler = SubscriptionListener;
180
198
 
181
199
  export type RecordsSubscribeMessageOptions = {
182
- subscriptionHandler: RecordSubscriptionHandler;
200
+ subscriptionHandler: SubscriptionListener;
183
201
  };
184
202
 
185
203
  export type RecordsSubscribeMessage = GenericMessage & {
@@ -1,9 +1,13 @@
1
- import type { GenericMessageReply } from '../types/message-types.js';
2
- import type { KeyValues } from './query-types.js';
3
1
  import type { RecordsWriteMessage } from './records-types.js';
4
- import type { GenericMessage, MessageSubscription } from './message-types.js';
2
+ import type { Filter, KeyValues } from './query-types.js';
3
+ import type { GenericMessage, GenericMessageReply, MessageSubscription } from './message-types.js';
5
4
 
6
- export type EventListener = (tenant: string, event: MessageEvent, indexes: KeyValues) => void;
5
+ /**
6
+ * Internal listener type used by {@link EventLog.emit} to notify in-process
7
+ * subscribers. Not intended for direct consumer use — consumers should use
8
+ * {@link SubscriptionListener} via {@link EventLog.subscribe}.
9
+ */
10
+ export type EventListener = (tenant: string, event: MessageEvent, indexes: KeyValues, seq: number) => void;
7
11
 
8
12
  /**
9
13
  * MessageEvent contains the message being emitted and an optional initial write message.
@@ -14,16 +18,6 @@ export type MessageEvent = {
14
18
  initialWrite?: RecordsWriteMessage
15
19
  };
16
20
 
17
- /**
18
- * The EventStream interface implements a pub/sub system based on Message filters.
19
- */
20
- export interface EventStream {
21
- subscribe(tenant: string, id: string, listener: EventListener): Promise<EventSubscription>;
22
- emit(tenant: string, event: MessageEvent, indexes: KeyValues): void;
23
- open(): Promise<void>;
24
- close(): Promise<void>;
25
- }
26
-
27
21
  export interface EventSubscription {
28
22
  id: string;
29
23
  close: () => Promise<void>;
@@ -32,3 +26,173 @@ export interface EventSubscription {
32
26
  export type SubscriptionReply = GenericMessageReply & {
33
27
  subscription?: MessageSubscription;
34
28
  };
29
+
30
+ // ---------------------------------------------------------------------------
31
+ // Subscription events — discriminated union for event + EOSE delivery
32
+ // ---------------------------------------------------------------------------
33
+
34
+ /**
35
+ * A regular subscription event carrying a message and its EventLog cursor.
36
+ */
37
+ export type SubscriptionEvent = {
38
+ type : 'event';
39
+ /**
40
+ * Opaque cursor string assigned by the EventLog implementation. Clients should
41
+ * persist this value and pass it back to `subscribe()` or `read()` to resume
42
+ * from this point. The format is implementation-defined (e.g. numeric sequence
43
+ * for in-memory, Redis stream ID, NATS stream sequence, etc.).
44
+ */
45
+ cursor : string;
46
+ /** The event payload (message + optional initialWrite). */
47
+ event : MessageEvent;
48
+ };
49
+
50
+ /**
51
+ * End-of-Stored-Events marker. Sent after all catch-up events have been replayed
52
+ * from the EventLog. After EOSE, all subsequent events are live.
53
+ *
54
+ * Only delivered when a subscription is created with a `cursor`. Subscriptions
55
+ * without a cursor never receive EOSE.
56
+ */
57
+ export type SubscriptionEose = {
58
+ type : 'eose';
59
+ /**
60
+ * Opaque cursor string of the last stored event that was replayed.
61
+ * Echoes the input cursor when no stored events matched (i.e. already caught up).
62
+ */
63
+ cursor : string;
64
+ };
65
+
66
+ /**
67
+ * Discriminated union of subscription event types delivered to
68
+ * {@link SubscriptionListener} callbacks.
69
+ */
70
+ export type SubscriptionMessage = SubscriptionEvent | SubscriptionEose;
71
+
72
+ /**
73
+ * Callback for {@link EventLog.subscribe}. Receives either a regular event
74
+ * (with cursor) or an EOSE marker indicating catch-up replay is complete.
75
+ */
76
+ export type SubscriptionListener = (message: SubscriptionMessage) => void;
77
+
78
+ /**
79
+ * Options for {@link EventLog.subscribe}.
80
+ */
81
+ export type EventLogSubscribeOptions = {
82
+ /**
83
+ * Opaque cursor string to resume from (exclusive — events after this cursor
84
+ * are replayed). When provided, stored events are replayed first, followed by
85
+ * an EOSE marker, then live events. When omitted, only live events are delivered.
86
+ *
87
+ * Cursor values are implementation-defined and must be obtained from a prior
88
+ * interaction with the same EventLog instance (e.g. `SubscriptionEvent.cursor`,
89
+ * `EventLogReadResult.cursor`, or the return value of `emit()`).
90
+ */
91
+ cursor? : string;
92
+
93
+ /**
94
+ * Filters evaluated against event indexes. Events must match at least one
95
+ * filter (OR semantics). When omitted, all events are delivered.
96
+ */
97
+ filters? : Filter[];
98
+ };
99
+
100
+ // ---------------------------------------------------------------------------
101
+ // EventLog — persistent, cursor-based event delivery
102
+ // ---------------------------------------------------------------------------
103
+
104
+ /**
105
+ * A single entry returned by {@link EventLog.read}.
106
+ */
107
+ export type EventLogEntry = {
108
+ /** Monotonic sequence number scoped to (instance, tenant). */
109
+ seq: number;
110
+
111
+ /** The event payload. */
112
+ event: MessageEvent;
113
+
114
+ /** Indexes associated with the event (used for filter matching). */
115
+ indexes: KeyValues;
116
+ };
117
+
118
+ /**
119
+ * Options accepted by {@link EventLog.read}.
120
+ */
121
+ export type EventLogReadOptions = {
122
+ /** Opaque cursor string to resume from (exclusive — returns events after this cursor). */
123
+ cursor? : string;
124
+
125
+ /** Maximum number of events to return. */
126
+ limit? : number;
127
+
128
+ /** Optional filters evaluated server-side. Events must match at least one filter (OR semantics). */
129
+ filters?: Filter[];
130
+ };
131
+
132
+ /**
133
+ * Result returned by {@link EventLog.read}.
134
+ */
135
+ export type EventLogReadResult = {
136
+ /** Events matching the read request, ordered by ascending seq. */
137
+ events : EventLogEntry[];
138
+
139
+ /**
140
+ * Opaque cursor string for resuming subsequent reads or subscriptions.
141
+ *
142
+ * - When events are returned: cursor of the last event.
143
+ * - When no events are returned but a cursor was provided: the input cursor
144
+ * (meaning "you are caught up, nothing new since this point").
145
+ * - When no events exist and no cursor was provided: `undefined`.
146
+ */
147
+ cursor? : string;
148
+ };
149
+
150
+ /**
151
+ * The EventLog interface provides persistent, ordered event storage with
152
+ * cursor-based reads and subscription support.
153
+ *
154
+ * It persists events before delivery, exposing opaque cursor strings
155
+ * that enable cursor-based resume after disconnects.
156
+ *
157
+ * The interface is intentionally transport-agnostic — implementations can be
158
+ * backed by LevelDB (embedded), SQL, NATS JetStream, Redis Streams, etc.
159
+ * Each implementation owns the catch-up + live transition strategy appropriate
160
+ * to its backend (e.g., NATS pull consumers, Redis XREAD, in-memory buffering).
161
+ */
162
+ export interface EventLog {
163
+ /**
164
+ * Persist an event and notify in-process subscribers.
165
+ * @returns The opaque cursor string assigned to the event, or empty string on failure.
166
+ */
167
+ emit(tenant: string, event: MessageEvent, indexes: KeyValues): Promise<string>;
168
+
169
+ /**
170
+ * Read events from the log starting after `cursor`, optionally filtered.
171
+ */
172
+ read(tenant: string, options?: EventLogReadOptions): Promise<EventLogReadResult>;
173
+
174
+ /**
175
+ * Subscribe to events for a tenant.
176
+ *
177
+ * When `options.cursor` is provided, the implementation replays stored events
178
+ * from that cursor through the listener, delivers an EOSE marker, then
179
+ * continues with live events. The catch-up → live transition (including
180
+ * buffering and deduplication) is owned by the implementation.
181
+ *
182
+ * When `options.cursor` is omitted, only live events are delivered.
183
+ *
184
+ * @param tenant The tenant DID to subscribe to.
185
+ * @param id A unique subscription identifier (used for close/tracking).
186
+ * @param listener Callback that receives {@link SubscriptionMessage} events.
187
+ * @param options Optional cursor and filters for catch-up replay.
188
+ */
189
+ subscribe(tenant: string, id: string, listener: SubscriptionListener, options?: EventLogSubscribeOptions): Promise<EventSubscription>;
190
+
191
+ /**
192
+ * Delete events older than the given sequence number or ISO-8601 timestamp.
193
+ */
194
+ trim(tenant: string, olderThan: number | string): Promise<void>;
195
+
196
+ open(): Promise<void>;
197
+ close(): Promise<void>;
198
+ }