@enbox/dwn-sdk-js 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (522) hide show
  1. package/README.md +4 -4
  2. package/dist/browser.mjs +3 -10
  3. package/dist/browser.mjs.map +4 -4
  4. package/dist/esm/generated/precompiled-validators.js +799 -885
  5. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  6. package/dist/esm/src/core/dwn-constant.js +5 -0
  7. package/dist/esm/src/core/dwn-constant.js.map +1 -1
  8. package/dist/esm/src/core/dwn-error.js +12 -4
  9. package/dist/esm/src/core/dwn-error.js.map +1 -1
  10. package/dist/esm/src/core/grant-authorization.js +9 -18
  11. package/dist/esm/src/core/grant-authorization.js.map +1 -1
  12. package/dist/esm/src/core/message-reply.js.map +1 -1
  13. package/dist/esm/src/core/messages-grant-authorization.js +28 -45
  14. package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
  15. package/dist/esm/src/core/protocol-authorization-action.js +25 -27
  16. package/dist/esm/src/core/protocol-authorization-action.js.map +1 -1
  17. package/dist/esm/src/core/protocol-authorization-validation.js +34 -89
  18. package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
  19. package/dist/esm/src/core/protocol-authorization.js +44 -118
  20. package/dist/esm/src/core/protocol-authorization.js.map +1 -1
  21. package/dist/esm/src/core/protocols-grant-authorization.js +5 -5
  22. package/dist/esm/src/core/protocols-grant-authorization.js.map +1 -1
  23. package/dist/esm/src/core/recording-validation-state-reader.js +84 -0
  24. package/dist/esm/src/core/recording-validation-state-reader.js.map +1 -0
  25. package/dist/esm/src/core/records-grant-authorization.js +11 -11
  26. package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
  27. package/dist/esm/src/core/replication-apply.js +123 -28
  28. package/dist/esm/src/core/replication-apply.js.map +1 -1
  29. package/dist/esm/src/core/resumable-task-manager.js +5 -4
  30. package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
  31. package/dist/esm/src/core/validation-state-reader.js +237 -0
  32. package/dist/esm/src/core/validation-state-reader.js.map +1 -0
  33. package/dist/esm/src/dwn.js +165 -132
  34. package/dist/esm/src/dwn.js.map +1 -1
  35. package/dist/esm/src/enums/dwn-interface-method.js +0 -1
  36. package/dist/esm/src/enums/dwn-interface-method.js.map +1 -1
  37. package/dist/esm/src/event-stream/durable-event-log.js +365 -0
  38. package/dist/esm/src/event-stream/durable-event-log.js.map +1 -0
  39. package/dist/esm/src/event-stream/event-emitter-wake-publisher.js +25 -0
  40. package/dist/esm/src/event-stream/event-emitter-wake-publisher.js.map +1 -0
  41. package/dist/esm/src/handlers/messages-query.js +159 -0
  42. package/dist/esm/src/handlers/messages-query.js.map +1 -0
  43. package/dist/esm/src/handlers/messages-read.js +5 -5
  44. package/dist/esm/src/handlers/messages-read.js.map +1 -1
  45. package/dist/esm/src/handlers/messages-subscribe.js +8 -8
  46. package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
  47. package/dist/esm/src/handlers/protocols-configure.js +30 -49
  48. package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
  49. package/dist/esm/src/handlers/protocols-query.js +1 -1
  50. package/dist/esm/src/handlers/protocols-query.js.map +1 -1
  51. package/dist/esm/src/handlers/records-count.js +20 -11
  52. package/dist/esm/src/handlers/records-count.js.map +1 -1
  53. package/dist/esm/src/handlers/records-delete.js +20 -16
  54. package/dist/esm/src/handlers/records-delete.js.map +1 -1
  55. package/dist/esm/src/handlers/records-query.js +35 -11
  56. package/dist/esm/src/handlers/records-query.js.map +1 -1
  57. package/dist/esm/src/handlers/records-read.js +52 -42
  58. package/dist/esm/src/handlers/records-read.js.map +1 -1
  59. package/dist/esm/src/handlers/records-subscribe.js +107 -11
  60. package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
  61. package/dist/esm/src/handlers/records-write.js +62 -116
  62. package/dist/esm/src/handlers/records-write.js.map +1 -1
  63. package/dist/esm/src/index.js +6 -7
  64. package/dist/esm/src/index.js.map +1 -1
  65. package/dist/esm/src/interfaces/{messages-sync.js → messages-query.js} +21 -15
  66. package/dist/esm/src/interfaces/messages-query.js.map +1 -0
  67. package/dist/esm/src/interfaces/protocols-configure.js +12 -9
  68. package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
  69. package/dist/esm/src/interfaces/protocols-query.js +3 -4
  70. package/dist/esm/src/interfaces/protocols-query.js.map +1 -1
  71. package/dist/esm/src/interfaces/records-count.js +4 -3
  72. package/dist/esm/src/interfaces/records-count.js.map +1 -1
  73. package/dist/esm/src/interfaces/records-delete.js +21 -4
  74. package/dist/esm/src/interfaces/records-delete.js.map +1 -1
  75. package/dist/esm/src/interfaces/records-query.js +4 -3
  76. package/dist/esm/src/interfaces/records-query.js.map +1 -1
  77. package/dist/esm/src/interfaces/records-read.js +3 -3
  78. package/dist/esm/src/interfaces/records-read.js.map +1 -1
  79. package/dist/esm/src/interfaces/records-subscribe.js +4 -3
  80. package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
  81. package/dist/esm/src/interfaces/records-write.js +27 -13
  82. package/dist/esm/src/interfaces/records-write.js.map +1 -1
  83. package/dist/esm/src/protocols/permissions.js +27 -34
  84. package/dist/esm/src/protocols/permissions.js.map +1 -1
  85. package/dist/esm/src/store/index-level.js +24 -9
  86. package/dist/esm/src/store/index-level.js.map +1 -1
  87. package/dist/esm/src/store/level-wrapper.js +7 -0
  88. package/dist/esm/src/store/level-wrapper.js.map +1 -1
  89. package/dist/esm/src/store/message-store-level.js +536 -42
  90. package/dist/esm/src/store/message-store-level.js.map +1 -1
  91. package/dist/esm/src/store/storage-controller.js +58 -49
  92. package/dist/esm/src/store/storage-controller.js.map +1 -1
  93. package/dist/esm/src/types/message-types.js.map +1 -1
  94. package/dist/esm/src/types/validation-state-reader.js +2 -0
  95. package/dist/esm/src/types/validation-state-reader.js.map +1 -0
  96. package/dist/esm/src/utils/messages.js +17 -0
  97. package/dist/esm/src/utils/messages.js.map +1 -1
  98. package/dist/esm/src/utils/protocol-tags.js +262 -0
  99. package/dist/esm/src/utils/protocol-tags.js.map +1 -0
  100. package/dist/esm/src/utils/record-limit-occupancy.js +244 -0
  101. package/dist/esm/src/utils/record-limit-occupancy.js.map +1 -0
  102. package/dist/esm/src/utils/records.js +50 -14
  103. package/dist/esm/src/utils/records.js.map +1 -1
  104. package/dist/esm/src/utils/replication.js +85 -0
  105. package/dist/esm/src/utils/replication.js.map +1 -0
  106. package/dist/esm/tests/core/grant-authorization.spec.js +4 -4
  107. package/dist/esm/tests/core/grant-authorization.spec.js.map +1 -1
  108. package/dist/esm/tests/core/process-message-parity.spec.js +222 -0
  109. package/dist/esm/tests/core/process-message-parity.spec.js.map +1 -0
  110. package/dist/esm/tests/core/protocol-authorization.spec.js +5 -2
  111. package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
  112. package/dist/esm/tests/core/records-grant-authorization.spec.js +5 -5
  113. package/dist/esm/tests/core/records-grant-authorization.spec.js.map +1 -1
  114. package/dist/esm/tests/core/replication-apply.spec.js +55 -1
  115. package/dist/esm/tests/core/replication-apply.spec.js.map +1 -1
  116. package/dist/esm/tests/core/replication-replay-property.spec.js +350 -0
  117. package/dist/esm/tests/core/replication-replay-property.spec.js.map +1 -0
  118. package/dist/esm/tests/core/validation-read-closure.spec.js +469 -0
  119. package/dist/esm/tests/core/validation-read-closure.spec.js.map +1 -0
  120. package/dist/esm/tests/core/validation-state-reader.spec.js +716 -0
  121. package/dist/esm/tests/core/validation-state-reader.spec.js.map +1 -0
  122. package/dist/esm/tests/durable-event-log.spec.js +373 -0
  123. package/dist/esm/tests/durable-event-log.spec.js.map +1 -0
  124. package/dist/esm/tests/dwn.spec.js +504 -35
  125. package/dist/esm/tests/dwn.spec.js.map +1 -1
  126. package/dist/esm/tests/features/author-delegated-grant.spec.js +9 -6
  127. package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
  128. package/dist/esm/tests/features/owner-delegated-grant.spec.js +1 -4
  129. package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
  130. package/dist/esm/tests/features/owner-signature.spec.js +1 -4
  131. package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
  132. package/dist/esm/tests/features/permissions.spec.js +165 -4
  133. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  134. package/dist/esm/tests/features/protocol-composition.spec.js +8 -11
  135. package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
  136. package/dist/esm/tests/features/protocol-create-action.spec.js +1 -4
  137. package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
  138. package/dist/esm/tests/features/protocol-delete-action.spec.js +3 -5
  139. package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
  140. package/dist/esm/tests/features/protocol-update-action.spec.js +3 -6
  141. package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
  142. package/dist/esm/tests/features/records-delivery.spec.js +1 -4
  143. package/dist/esm/tests/features/records-delivery.spec.js.map +1 -1
  144. package/dist/esm/tests/features/records-immutable.spec.js +1 -4
  145. package/dist/esm/tests/features/records-immutable.spec.js.map +1 -1
  146. package/dist/esm/tests/features/records-nested-query-scope.spec.js +281 -0
  147. package/dist/esm/tests/features/records-nested-query-scope.spec.js.map +1 -0
  148. package/dist/esm/tests/features/records-prune-cross-protocol.spec.js +3 -7
  149. package/dist/esm/tests/features/records-prune-cross-protocol.spec.js.map +1 -1
  150. package/dist/esm/tests/features/records-prune.spec.js +11 -22
  151. package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
  152. package/dist/esm/tests/features/records-record-limit.spec.js +441 -231
  153. package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -1
  154. package/dist/esm/tests/features/records-squash.spec.js +6 -4
  155. package/dist/esm/tests/features/records-squash.spec.js.map +1 -1
  156. package/dist/esm/tests/features/records-tags.spec.js +1 -4
  157. package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
  158. package/dist/esm/tests/features/resumable-tasks.spec.js +3 -5
  159. package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
  160. package/dist/esm/tests/fuzz/message-store.fuzz.spec.js +1 -2
  161. package/dist/esm/tests/fuzz/message-store.fuzz.spec.js.map +1 -1
  162. package/dist/esm/tests/fuzz/process-message.fuzz.spec.js +2 -4
  163. package/dist/esm/tests/fuzz/process-message.fuzz.spec.js.map +1 -1
  164. package/dist/esm/tests/fuzz/schema-validation.fuzz.spec.js +1 -1
  165. package/dist/esm/tests/fuzz/schema-validation.fuzz.spec.js.map +1 -1
  166. package/dist/esm/tests/handlers/messages-query.spec.js +246 -0
  167. package/dist/esm/tests/handlers/messages-query.spec.js.map +1 -0
  168. package/dist/esm/tests/handlers/messages-read.spec.js +2 -5
  169. package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
  170. package/dist/esm/tests/handlers/messages-subscribe.spec.js +3 -14
  171. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  172. package/dist/esm/tests/handlers/protocols-configure.spec.js +27 -26
  173. package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
  174. package/dist/esm/tests/handlers/protocols-query.spec.js +1 -4
  175. package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
  176. package/dist/esm/tests/handlers/records-count.spec.js +1 -4
  177. package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
  178. package/dist/esm/tests/handlers/records-delete.spec.js +312 -30
  179. package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
  180. package/dist/esm/tests/handlers/records-query.spec.js +32 -9
  181. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  182. package/dist/esm/tests/handlers/records-read.spec.js +4 -4
  183. package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
  184. package/dist/esm/tests/handlers/records-subscribe.spec.js +33 -14
  185. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  186. package/dist/esm/tests/handlers/records-write.spec.js +82 -36
  187. package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
  188. package/dist/esm/tests/interfaces/records-delete.spec.js +69 -2
  189. package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -1
  190. package/dist/esm/tests/interfaces/records-write.spec.js +4 -3
  191. package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
  192. package/dist/esm/tests/protocols/permissions.spec.js +55 -6
  193. package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
  194. package/dist/esm/tests/scenarios/aggregator.spec.js +1 -4
  195. package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
  196. package/dist/esm/tests/scenarios/deleted-record.spec.js +1 -4
  197. package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
  198. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +1 -4
  199. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
  200. package/dist/esm/tests/scenarios/nested-roles.spec.js +1 -4
  201. package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
  202. package/dist/esm/tests/scenarios/subscriptions.spec.js +1 -4
  203. package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
  204. package/dist/esm/tests/store/message-store-level.spec.js +361 -5
  205. package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
  206. package/dist/esm/tests/store/message-store.spec.js +60 -0
  207. package/dist/esm/tests/store/message-store.spec.js.map +1 -1
  208. package/dist/esm/tests/test-event-stream.js +7 -3
  209. package/dist/esm/tests/test-event-stream.js.map +1 -1
  210. package/dist/esm/tests/test-stores.js +19 -9
  211. package/dist/esm/tests/test-stores.js.map +1 -1
  212. package/dist/esm/tests/test-suite.js +4 -2
  213. package/dist/esm/tests/test-suite.js.map +1 -1
  214. package/dist/esm/tests/utils/protocol-tags.spec.js +96 -0
  215. package/dist/esm/tests/utils/protocol-tags.spec.js.map +1 -0
  216. package/dist/esm/tests/utils/test-data-generator.js +25 -0
  217. package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
  218. package/dist/esm/tests/utils/test-stub-generator.js.map +1 -1
  219. package/dist/esm/tests/utils/test-validation-state-reader.js +16 -0
  220. package/dist/esm/tests/utils/test-validation-state-reader.js.map +1 -0
  221. package/dist/types/generated/precompiled-validators.d.ts +6 -6
  222. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  223. package/dist/types/src/core/core-protocol.d.ts +3 -3
  224. package/dist/types/src/core/core-protocol.d.ts.map +1 -1
  225. package/dist/types/src/core/dwn-constant.d.ts +5 -0
  226. package/dist/types/src/core/dwn-constant.d.ts.map +1 -1
  227. package/dist/types/src/core/dwn-error.d.ts +12 -4
  228. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  229. package/dist/types/src/core/grant-authorization.d.ts +5 -5
  230. package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
  231. package/dist/types/src/core/message-reply.d.ts +5 -4
  232. package/dist/types/src/core/message-reply.d.ts.map +1 -1
  233. package/dist/types/src/core/messages-grant-authorization.d.ts +12 -14
  234. package/dist/types/src/core/messages-grant-authorization.d.ts.map +1 -1
  235. package/dist/types/src/core/protocol-authorization-action.d.ts +4 -5
  236. package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -1
  237. package/dist/types/src/core/protocol-authorization-validation.d.ts +14 -17
  238. package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
  239. package/dist/types/src/core/protocol-authorization.d.ts +8 -33
  240. package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
  241. package/dist/types/src/core/protocols-grant-authorization.d.ts +4 -4
  242. package/dist/types/src/core/protocols-grant-authorization.d.ts.map +1 -1
  243. package/dist/types/src/core/recording-validation-state-reader.d.ts +75 -0
  244. package/dist/types/src/core/recording-validation-state-reader.d.ts.map +1 -0
  245. package/dist/types/src/core/records-grant-authorization.d.ts +8 -8
  246. package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
  247. package/dist/types/src/core/replication-apply.d.ts +36 -0
  248. package/dist/types/src/core/replication-apply.d.ts.map +1 -1
  249. package/dist/types/src/core/resumable-task-manager.d.ts +1 -1
  250. package/dist/types/src/core/resumable-task-manager.d.ts.map +1 -1
  251. package/dist/types/src/core/validation-state-reader.d.ts +79 -0
  252. package/dist/types/src/core/validation-state-reader.d.ts.map +1 -0
  253. package/dist/types/src/dwn.d.ts +33 -20
  254. package/dist/types/src/dwn.d.ts.map +1 -1
  255. package/dist/types/src/enums/dwn-interface-method.d.ts +0 -1
  256. package/dist/types/src/enums/dwn-interface-method.d.ts.map +1 -1
  257. package/dist/types/src/event-stream/durable-event-log.d.ts +69 -0
  258. package/dist/types/src/event-stream/durable-event-log.d.ts.map +1 -0
  259. package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts +13 -0
  260. package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts.map +1 -0
  261. package/dist/types/src/handlers/messages-query.d.ts +20 -0
  262. package/dist/types/src/handlers/messages-query.d.ts.map +1 -0
  263. package/dist/types/src/handlers/messages-read.d.ts +1 -1
  264. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  265. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  266. package/dist/types/src/handlers/protocols-configure.d.ts +0 -5
  267. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  268. package/dist/types/src/handlers/records-count.d.ts +2 -1
  269. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  270. package/dist/types/src/handlers/records-delete.d.ts +2 -2
  271. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  272. package/dist/types/src/handlers/records-query.d.ts +1 -1
  273. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  274. package/dist/types/src/handlers/records-read.d.ts +2 -1
  275. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  276. package/dist/types/src/handlers/records-subscribe.d.ts +4 -5
  277. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  278. package/dist/types/src/handlers/records-write.d.ts +3 -11
  279. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  280. package/dist/types/src/index.d.ts +14 -16
  281. package/dist/types/src/index.d.ts.map +1 -1
  282. package/dist/types/src/interfaces/messages-query.d.ts +23 -0
  283. package/dist/types/src/interfaces/messages-query.d.ts.map +1 -0
  284. package/dist/types/src/interfaces/protocols-configure.d.ts +3 -3
  285. package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
  286. package/dist/types/src/interfaces/protocols-query.d.ts +2 -2
  287. package/dist/types/src/interfaces/protocols-query.d.ts.map +1 -1
  288. package/dist/types/src/interfaces/records-count.d.ts +3 -3
  289. package/dist/types/src/interfaces/records-count.d.ts.map +1 -1
  290. package/dist/types/src/interfaces/records-delete.d.ts +11 -3
  291. package/dist/types/src/interfaces/records-delete.d.ts.map +1 -1
  292. package/dist/types/src/interfaces/records-query.d.ts +3 -3
  293. package/dist/types/src/interfaces/records-query.d.ts.map +1 -1
  294. package/dist/types/src/interfaces/records-read.d.ts +3 -3
  295. package/dist/types/src/interfaces/records-read.d.ts.map +1 -1
  296. package/dist/types/src/interfaces/records-subscribe.d.ts +3 -3
  297. package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
  298. package/dist/types/src/interfaces/records-write.d.ts +15 -7
  299. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  300. package/dist/types/src/protocols/permissions.d.ts +9 -12
  301. package/dist/types/src/protocols/permissions.d.ts.map +1 -1
  302. package/dist/types/src/store/index-level.d.ts +10 -1
  303. package/dist/types/src/store/index-level.d.ts.map +1 -1
  304. package/dist/types/src/store/level-wrapper.d.ts +5 -0
  305. package/dist/types/src/store/level-wrapper.d.ts.map +1 -1
  306. package/dist/types/src/store/message-store-level.d.ts +94 -14
  307. package/dist/types/src/store/message-store-level.d.ts.map +1 -1
  308. package/dist/types/src/store/storage-controller.d.ts +17 -14
  309. package/dist/types/src/store/storage-controller.d.ts.map +1 -1
  310. package/dist/types/src/types/message-store.d.ts +29 -1
  311. package/dist/types/src/types/message-store.d.ts.map +1 -1
  312. package/dist/types/src/types/message-types.d.ts +2 -0
  313. package/dist/types/src/types/message-types.d.ts.map +1 -1
  314. package/dist/types/src/types/messages-types.d.ts +21 -37
  315. package/dist/types/src/types/messages-types.d.ts.map +1 -1
  316. package/dist/types/src/types/method-handler.d.ts +2 -2
  317. package/dist/types/src/types/method-handler.d.ts.map +1 -1
  318. package/dist/types/src/types/permission-types.d.ts +1 -1
  319. package/dist/types/src/types/subscriptions.d.ts +50 -39
  320. package/dist/types/src/types/subscriptions.d.ts.map +1 -1
  321. package/dist/types/src/types/validation-state-reader.d.ts +116 -0
  322. package/dist/types/src/types/validation-state-reader.d.ts.map +1 -0
  323. package/dist/types/src/utils/messages.d.ts +10 -0
  324. package/dist/types/src/utils/messages.d.ts.map +1 -1
  325. package/dist/types/src/utils/protocol-tags.d.ts +15 -0
  326. package/dist/types/src/utils/protocol-tags.d.ts.map +1 -0
  327. package/dist/types/src/utils/record-limit-occupancy.d.ts +40 -0
  328. package/dist/types/src/utils/record-limit-occupancy.d.ts.map +1 -0
  329. package/dist/types/src/utils/records.d.ts +25 -3
  330. package/dist/types/src/utils/records.d.ts.map +1 -1
  331. package/dist/types/src/utils/replication.d.ts +22 -0
  332. package/dist/types/src/utils/replication.d.ts.map +1 -0
  333. package/dist/types/tests/core/process-message-parity.spec.d.ts +2 -0
  334. package/dist/types/tests/core/process-message-parity.spec.d.ts.map +1 -0
  335. package/dist/types/tests/core/replication-replay-property.spec.d.ts +2 -0
  336. package/dist/types/tests/core/replication-replay-property.spec.d.ts.map +1 -0
  337. package/dist/types/tests/core/validation-read-closure.spec.d.ts +2 -0
  338. package/dist/types/tests/core/validation-read-closure.spec.d.ts.map +1 -0
  339. package/dist/types/tests/core/validation-state-reader.spec.d.ts +2 -0
  340. package/dist/types/tests/core/validation-state-reader.spec.d.ts.map +1 -0
  341. package/dist/types/tests/durable-event-log.spec.d.ts +2 -0
  342. package/dist/types/tests/durable-event-log.spec.d.ts.map +1 -0
  343. package/dist/types/tests/dwn.spec.d.ts.map +1 -1
  344. package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -1
  345. package/dist/types/tests/features/owner-delegated-grant.spec.d.ts.map +1 -1
  346. package/dist/types/tests/features/owner-signature.spec.d.ts.map +1 -1
  347. package/dist/types/tests/features/permissions.spec.d.ts.map +1 -1
  348. package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -1
  349. package/dist/types/tests/features/protocol-create-action.spec.d.ts.map +1 -1
  350. package/dist/types/tests/features/protocol-delete-action.spec.d.ts.map +1 -1
  351. package/dist/types/tests/features/protocol-update-action.spec.d.ts.map +1 -1
  352. package/dist/types/tests/features/records-delivery.spec.d.ts.map +1 -1
  353. package/dist/types/tests/features/records-immutable.spec.d.ts.map +1 -1
  354. package/dist/types/tests/features/records-nested-query-scope.spec.d.ts +2 -0
  355. package/dist/types/tests/features/records-nested-query-scope.spec.d.ts.map +1 -0
  356. package/dist/types/tests/features/records-prune-cross-protocol.spec.d.ts.map +1 -1
  357. package/dist/types/tests/features/records-prune.spec.d.ts.map +1 -1
  358. package/dist/types/tests/features/records-record-limit.spec.d.ts.map +1 -1
  359. package/dist/types/tests/features/records-squash.spec.d.ts.map +1 -1
  360. package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -1
  361. package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -1
  362. package/dist/types/tests/handlers/messages-query.spec.d.ts +2 -0
  363. package/dist/types/tests/handlers/messages-query.spec.d.ts.map +1 -0
  364. package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
  365. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  366. package/dist/types/tests/handlers/protocols-configure.spec.d.ts.map +1 -1
  367. package/dist/types/tests/handlers/protocols-query.spec.d.ts.map +1 -1
  368. package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
  369. package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
  370. package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
  371. package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
  372. package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
  373. package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
  374. package/dist/types/tests/scenarios/deleted-record.spec.d.ts.map +1 -1
  375. package/dist/types/tests/scenarios/end-to-end-tests.spec.d.ts.map +1 -1
  376. package/dist/types/tests/scenarios/nested-roles.spec.d.ts.map +1 -1
  377. package/dist/types/tests/scenarios/subscriptions.spec.d.ts.map +1 -1
  378. package/dist/types/tests/store/message-store.spec.d.ts.map +1 -1
  379. package/dist/types/tests/test-event-stream.d.ts +1 -1
  380. package/dist/types/tests/test-event-stream.d.ts.map +1 -1
  381. package/dist/types/tests/test-stores.d.ts +5 -4
  382. package/dist/types/tests/test-stores.d.ts.map +1 -1
  383. package/dist/types/tests/test-suite.d.ts +1 -2
  384. package/dist/types/tests/test-suite.d.ts.map +1 -1
  385. package/dist/types/tests/utils/protocol-tags.spec.d.ts +2 -0
  386. package/dist/types/tests/utils/protocol-tags.spec.d.ts.map +1 -0
  387. package/dist/types/tests/utils/test-data-generator.d.ts +20 -1
  388. package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
  389. package/dist/types/tests/utils/test-validation-state-reader.d.ts +15 -0
  390. package/dist/types/tests/utils/test-validation-state-reader.d.ts.map +1 -0
  391. package/package.json +2 -2
  392. package/src/core/core-protocol.ts +3 -3
  393. package/src/core/dwn-constant.ts +7 -1
  394. package/src/core/dwn-error.ts +12 -4
  395. package/src/core/grant-authorization.ts +11 -20
  396. package/src/core/message-reply.ts +6 -5
  397. package/src/core/messages-grant-authorization.ts +37 -70
  398. package/src/core/protocol-authorization-action.ts +29 -38
  399. package/src/core/protocol-authorization-validation.ts +47 -121
  400. package/src/core/protocol-authorization.ts +56 -202
  401. package/src/core/protocols-grant-authorization.ts +9 -9
  402. package/src/core/recording-validation-state-reader.ts +130 -0
  403. package/src/core/records-grant-authorization.ts +16 -16
  404. package/src/core/replication-apply.ts +172 -32
  405. package/src/core/resumable-task-manager.ts +10 -8
  406. package/src/core/validation-state-reader.ts +350 -0
  407. package/src/dwn.ts +285 -192
  408. package/src/enums/dwn-interface-method.ts +0 -1
  409. package/src/event-stream/durable-event-log.ts +509 -0
  410. package/src/event-stream/event-emitter-wake-publisher.ts +34 -0
  411. package/src/handlers/messages-query.ts +203 -0
  412. package/src/handlers/messages-read.ts +9 -10
  413. package/src/handlers/messages-subscribe.ts +12 -13
  414. package/src/handlers/protocols-configure.ts +37 -58
  415. package/src/handlers/protocols-query.ts +1 -1
  416. package/src/handlers/records-count.ts +24 -17
  417. package/src/handlers/records-delete.ts +29 -27
  418. package/src/handlers/records-query.ts +38 -17
  419. package/src/handlers/records-read.ts +63 -50
  420. package/src/handlers/records-subscribe.ts +132 -19
  421. package/src/handlers/records-write.ts +77 -168
  422. package/src/index.ts +14 -17
  423. package/src/interfaces/messages-query.ts +70 -0
  424. package/src/interfaces/protocols-configure.ts +20 -10
  425. package/src/interfaces/protocols-query.ts +4 -5
  426. package/src/interfaces/records-count.ts +9 -4
  427. package/src/interfaces/records-delete.ts +25 -5
  428. package/src/interfaces/records-query.ts +9 -4
  429. package/src/interfaces/records-read.ts +4 -4
  430. package/src/interfaces/records-subscribe.ts +9 -4
  431. package/src/interfaces/records-write.ts +41 -13
  432. package/src/protocols/permissions.ts +32 -52
  433. package/src/store/index-level.ts +30 -9
  434. package/src/store/level-wrapper.ts +9 -1
  435. package/src/store/message-store-level.ts +757 -47
  436. package/src/store/storage-controller.ts +74 -63
  437. package/src/types/message-store.ts +45 -2
  438. package/src/types/message-types.ts +3 -1
  439. package/src/types/messages-types.ts +26 -45
  440. package/src/types/method-handler.ts +3 -3
  441. package/src/types/permission-types.ts +1 -1
  442. package/src/types/subscriptions.ts +53 -42
  443. package/src/types/validation-state-reader.ts +127 -0
  444. package/src/utils/messages.ts +25 -1
  445. package/src/utils/protocol-tags.ts +366 -0
  446. package/src/utils/record-limit-occupancy.ts +377 -0
  447. package/src/utils/records.ts +69 -13
  448. package/src/utils/replication.ts +122 -0
  449. package/dist/esm/src/core/record-chain.js +0 -64
  450. package/dist/esm/src/core/record-chain.js.map +0 -1
  451. package/dist/esm/src/event-stream/event-emitter-event-log.js +0 -334
  452. package/dist/esm/src/event-stream/event-emitter-event-log.js.map +0 -1
  453. package/dist/esm/src/handlers/messages-sync.js +0 -278
  454. package/dist/esm/src/handlers/messages-sync.js.map +0 -1
  455. package/dist/esm/src/interfaces/messages-sync.js.map +0 -1
  456. package/dist/esm/src/smt/smt-store-level.js +0 -103
  457. package/dist/esm/src/smt/smt-store-level.js.map +0 -1
  458. package/dist/esm/src/smt/smt-store-memory.js +0 -41
  459. package/dist/esm/src/smt/smt-store-memory.js.map +0 -1
  460. package/dist/esm/src/smt/smt-utils.js +0 -129
  461. package/dist/esm/src/smt/smt-utils.js.map +0 -1
  462. package/dist/esm/src/smt/sparse-merkle-tree.js +0 -577
  463. package/dist/esm/src/smt/sparse-merkle-tree.js.map +0 -1
  464. package/dist/esm/src/state-index/state-index-level.js +0 -191
  465. package/dist/esm/src/state-index/state-index-level.js.map +0 -1
  466. package/dist/esm/src/types/smt-types.js +0 -5
  467. package/dist/esm/src/types/smt-types.js.map +0 -1
  468. package/dist/esm/src/types/state-index.js +0 -2
  469. package/dist/esm/src/types/state-index.js.map +0 -1
  470. package/dist/esm/tests/event-emitter-event-log.spec.js +0 -499
  471. package/dist/esm/tests/event-emitter-event-log.spec.js.map +0 -1
  472. package/dist/esm/tests/handlers/messages-sync.spec.js +0 -1088
  473. package/dist/esm/tests/handlers/messages-sync.spec.js.map +0 -1
  474. package/dist/esm/tests/smt/smt-store-level.spec.js +0 -132
  475. package/dist/esm/tests/smt/smt-store-level.spec.js.map +0 -1
  476. package/dist/esm/tests/smt/sparse-merkle-tree.spec.js +0 -732
  477. package/dist/esm/tests/smt/sparse-merkle-tree.spec.js.map +0 -1
  478. package/dist/esm/tests/state-index/state-index-level.spec.js +0 -245
  479. package/dist/esm/tests/state-index/state-index-level.spec.js.map +0 -1
  480. package/dist/types/src/core/record-chain.d.ts +0 -24
  481. package/dist/types/src/core/record-chain.d.ts.map +0 -1
  482. package/dist/types/src/event-stream/event-emitter-event-log.d.ts +0 -80
  483. package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +0 -1
  484. package/dist/types/src/handlers/messages-sync.d.ts +0 -39
  485. package/dist/types/src/handlers/messages-sync.d.ts.map +0 -1
  486. package/dist/types/src/interfaces/messages-sync.d.ts +0 -20
  487. package/dist/types/src/interfaces/messages-sync.d.ts.map +0 -1
  488. package/dist/types/src/smt/smt-store-level.d.ts +0 -32
  489. package/dist/types/src/smt/smt-store-level.d.ts.map +0 -1
  490. package/dist/types/src/smt/smt-store-memory.d.ts +0 -22
  491. package/dist/types/src/smt/smt-store-memory.d.ts.map +0 -1
  492. package/dist/types/src/smt/smt-utils.d.ts +0 -58
  493. package/dist/types/src/smt/smt-utils.d.ts.map +0 -1
  494. package/dist/types/src/smt/sparse-merkle-tree.d.ts +0 -124
  495. package/dist/types/src/smt/sparse-merkle-tree.d.ts.map +0 -1
  496. package/dist/types/src/state-index/state-index-level.d.ts +0 -83
  497. package/dist/types/src/state-index/state-index-level.d.ts.map +0 -1
  498. package/dist/types/src/types/smt-types.d.ts +0 -81
  499. package/dist/types/src/types/smt-types.d.ts.map +0 -1
  500. package/dist/types/src/types/state-index.d.ts +0 -90
  501. package/dist/types/src/types/state-index.d.ts.map +0 -1
  502. package/dist/types/tests/event-emitter-event-log.spec.d.ts +0 -2
  503. package/dist/types/tests/event-emitter-event-log.spec.d.ts.map +0 -1
  504. package/dist/types/tests/handlers/messages-sync.spec.d.ts +0 -2
  505. package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +0 -1
  506. package/dist/types/tests/smt/smt-store-level.spec.d.ts +0 -2
  507. package/dist/types/tests/smt/smt-store-level.spec.d.ts.map +0 -1
  508. package/dist/types/tests/smt/sparse-merkle-tree.spec.d.ts +0 -2
  509. package/dist/types/tests/smt/sparse-merkle-tree.spec.d.ts.map +0 -1
  510. package/dist/types/tests/state-index/state-index-level.spec.d.ts +0 -2
  511. package/dist/types/tests/state-index/state-index-level.spec.d.ts.map +0 -1
  512. package/src/core/record-chain.ts +0 -99
  513. package/src/event-stream/event-emitter-event-log.ts +0 -430
  514. package/src/handlers/messages-sync.ts +0 -403
  515. package/src/interfaces/messages-sync.ts +0 -69
  516. package/src/smt/smt-store-level.ts +0 -143
  517. package/src/smt/smt-store-memory.ts +0 -53
  518. package/src/smt/smt-utils.ts +0 -149
  519. package/src/smt/sparse-merkle-tree.ts +0 -698
  520. package/src/state-index/state-index-level.ts +0 -239
  521. package/src/types/smt-types.ts +0 -95
  522. package/src/types/state-index.ts +0 -100
@@ -1,10 +1,9 @@
1
1
  import type { DataStore } from '../types/data-store.js';
2
- import type { EventLog } from '../types/subscriptions.js';
3
2
  import type { Filter } from '../types/query-types.js';
4
3
  import type { GenericMessage } from '../types/message-types.js';
5
4
  import type { MessageStore } from '../types/message-store.js';
6
- import type { StateIndex } from '../types/state-index.js';
7
- import type { RecordsDeleteMessage, RecordsQueryReplyEntry, RecordsWriteMessage } from '../types/records-types.js';
5
+ import type { ProgressToken } from '../types/subscriptions.js';
6
+ import type { RecordsDeleteMessage, RecordsWriteMessage } from '../types/records-types.js';
8
7
 
9
8
  import { DwnConstant } from '../core/dwn-constant.js';
10
9
  import { FilterUtility } from '../utils/filter.js';
@@ -25,29 +24,28 @@ export type ResumableRecordsSquashData = {
25
24
  message: RecordsWriteMessage;
26
25
  };
27
26
 
27
+ export type RecordsDeleteTaskResult = {
28
+ position?: ProgressToken;
29
+ };
30
+
28
31
  /**
29
- * A class that provides an abstraction for the usage of MessageStore, DataStore, and StateIndex.
32
+ * A class that provides an abstraction for coordinated MessageStore and DataStore mutations.
30
33
  */
31
34
  export class StorageController {
32
35
 
33
36
  private readonly messageStore: MessageStore;
34
37
  private readonly dataStore: DataStore;
35
- private readonly stateIndex: StateIndex;
36
- private readonly eventLog?: EventLog;
37
38
 
38
- public constructor({ messageStore, dataStore, stateIndex, eventLog }: {
39
+ public constructor({ messageStore, dataStore }: {
39
40
  messageStore : MessageStore,
40
41
  dataStore : DataStore,
41
- stateIndex : StateIndex,
42
- eventLog? : EventLog}
42
+ }
43
43
  ) {
44
44
  this.messageStore = messageStore;
45
45
  this.dataStore = dataStore;
46
- this.stateIndex = stateIndex;
47
- this.eventLog = eventLog;
48
46
  }
49
47
 
50
- public async performRecordsDelete({ tenant, message }: ResumableRecordsDeleteData): Promise<void> {
48
+ public async performRecordsDelete({ tenant, message }: ResumableRecordsDeleteData): Promise<RecordsDeleteTaskResult> {
51
49
  // get existing records matching the `recordId`
52
50
  const query = {
53
51
  interface : DwnInterfaceName.Records,
@@ -58,8 +56,15 @@ export class StorageController {
58
56
  // find which message is the newest, and if the incoming message is the newest
59
57
  const newestExistingMessage = await Message.getNewestMessage(existingMessages);
60
58
 
61
- if (!Records.canPerformDeleteAgainstRecord(message, newestExistingMessage)) {
62
- return;
59
+ if (newestExistingMessage === undefined) {
60
+ return {};
61
+ }
62
+
63
+ // Same tombstone-lattice gate as the RecordsDelete handler: state can advance between
64
+ // acceptance and task replay, and a beaten delete accepted earlier must not displace the
65
+ // tombstone that has since become the record's canonical winner.
66
+ if (await Records.isDeleteBeatenByExistingTombstone(message, newestExistingMessage)) {
67
+ return {};
63
68
  }
64
69
 
65
70
  // NOTE: code above is duplicated from `RecordsDeleteHandler` and is already performed if this was invoked by the `RecordsDeleteHandler`,
@@ -68,15 +73,14 @@ export class StorageController {
68
73
 
69
74
  const recordsDelete = await RecordsDelete.parse(message);
70
75
  const initialWrite = await RecordsWrite.getInitialWrite(existingMessages);
71
- const indexes = recordsDelete.constructIndexes(initialWrite);
72
- const messageCid = await Message.getCid(message);
73
- await this.messageStore.put(tenant, message, indexes);
74
- await this.stateIndex.insert(tenant, messageCid, indexes);
75
-
76
- // only emit if the event log is set
77
- if (this.eventLog !== undefined) {
78
- await this.eventLog.emit(tenant, { message, initialWrite }, indexes, messageCid);
79
- }
76
+ const newestPreDeleteWrite = await Records.getNewestRecordsWrite(existingMessages) ?? initialWrite;
77
+
78
+ // Tombstone mutable query-visibility facts (`tag.*`, `published`, `datePublished`) come from
79
+ // the newest retained RecordsWrite. This remains true when replacing an existing tombstone:
80
+ // tombstones carry no visibility facts in their descriptors, so the retained write is the
81
+ // durable source of truth for later prune/replay/replication index reconstruction.
82
+ const indexes = recordsDelete.constructIndexes(initialWrite, newestPreDeleteWrite);
83
+ const { position } = await this.messageStore.put(tenant, message, indexes);
80
84
 
81
85
  if (message.descriptor.prune) {
82
86
  // purge/hard-delete all descendant records. Cascade is intentionally protocol-agnostic:
@@ -84,14 +88,16 @@ export class StorageController {
84
88
  // of which protocol a descendant lives in. Cross-protocol composing children (linked via
85
89
  // `$ref`/`uses`) participate in the cascade. See issue #298 for the design discussion.
86
90
  await StorageController.purgeRecordDescendants(
87
- tenant, message.descriptor.recordId, this.messageStore, this.dataStore, this.stateIndex
91
+ tenant, message.descriptor.recordId, this.messageStore, this.dataStore
88
92
  );
89
93
  }
90
94
 
91
- // delete all existing messages that are not newest, except for the initial write
92
- await StorageController.deleteAllOlderMessagesButKeepInitialWrite(
93
- tenant, existingMessages, message, this.messageStore, this.dataStore, this.stateIndex
95
+ // displace every other message for this record, retaining the writes needed for replay and future tombstone visibility
96
+ await StorageController.deleteDisplacedMessagesAndRetainWrites(
97
+ tenant, existingMessages, message, this.messageStore, this.dataStore, [newestPreDeleteWrite]
94
98
  );
99
+
100
+ return { position };
95
101
  }
96
102
 
97
103
  /**
@@ -159,7 +165,7 @@ export class StorageController {
159
165
  const newestTimestamp = newestMessage.descriptor.messageTimestamp;
160
166
  if (newestTimestamp < messageTimestamp) {
161
167
  // Fully purge this record — all messages (including initial write) and their data
162
- await StorageController.purgeRecordMessages(tenant, messages, this.messageStore, this.dataStore, this.stateIndex);
168
+ await StorageController.purgeRecordMessages(tenant, messages, this.messageStore, this.dataStore);
163
169
  }
164
170
  }
165
171
  }
@@ -216,8 +222,7 @@ export class StorageController {
216
222
  tenant: string,
217
223
  recordId: string,
218
224
  messageStore: MessageStore,
219
- dataStore: DataStore,
220
- stateIndex: StateIndex
225
+ dataStore: DataStore
221
226
  ): Promise<void> {
222
227
  const filter: Filter = {
223
228
  interface : DwnInterfaceName.Records,
@@ -244,11 +249,11 @@ export class StorageController {
244
249
  }
245
250
 
246
251
  for (const childRecordId of recordIdToMessagesMap.keys()) {
247
- await StorageController.purgeRecordDescendants(tenant, childRecordId, messageStore, dataStore, stateIndex);
252
+ await StorageController.purgeRecordDescendants(tenant, childRecordId, messageStore, dataStore);
248
253
  }
249
254
 
250
255
  for (const childRecordId of recordIdToMessagesMap.keys()) {
251
- await StorageController.purgeRecordMessages(tenant, recordIdToMessagesMap.get(childRecordId)!, messageStore, dataStore, stateIndex);
256
+ await StorageController.purgeRecordMessages(tenant, recordIdToMessagesMap.get(childRecordId)!, messageStore, dataStore);
252
257
  }
253
258
  }
254
259
 
@@ -260,8 +265,7 @@ export class StorageController {
260
265
  tenant: string,
261
266
  recordMessages: GenericMessage[],
262
267
  messageStore: MessageStore,
263
- dataStore: DataStore,
264
- stateIndex: StateIndex
268
+ dataStore: DataStore
265
269
  ): Promise<void> {
266
270
  // delete the data from the data store first so no chance of orphaned data (not having a message referencing it) in case of server crash
267
271
  // NOTE: only the `RecordsWrite` with latest timestamp can possibly have data associated with it so we do this filtering as an optimization
@@ -275,60 +279,67 @@ export class StorageController {
275
279
  const newestRecordsWrite = (await Message.getNewestMessage(recordsWrites)) as RecordsWriteMessage;
276
280
  await dataStore.delete(tenant, newestRecordsWrite.recordId, newestRecordsWrite.descriptor.dataCid);
277
281
 
278
- // then delete all events associated with the record messages before deleting the messages so we don't have orphaned events
279
282
  const messageCids = await Promise.all(recordMessages.map((message) => Message.getCid(message)));
280
- await stateIndex.delete(tenant, messageCids);
281
283
 
282
- // finally delete all record messages
283
284
  await Promise.all(messageCids.map((messageCid) => messageStore.delete(tenant, messageCid)));
284
285
  }
285
286
 
286
287
  /**
287
- * Deletes all messages in `existingMessages` that are older than the `newestMessage` in the given tenant,
288
- * but keep the initial write write for future processing by ensuring its `isLatestBaseState` index is "false".
288
+ * Deletes all messages in `existingMessages` that the `retainedMessage` displaces, while keeping
289
+ * the initial write and the caller-supplied writes as non-latest state for future replay and
290
+ * tombstone visibility reconstruction. Displacement is deliberately NOT a timestamp comparison:
291
+ * a RecordsDelete displaces even a newer RecordsWrite (delete-wins convergence), and on
292
+ * resumable-task replay the retained message itself is back in `existingMessages` and must
293
+ * survive — so membership is decided by CID.
289
294
  */
290
- public static async deleteAllOlderMessagesButKeepInitialWrite(
295
+ public static async deleteDisplacedMessagesAndRetainWrites(
291
296
  tenant: string,
292
297
  existingMessages: GenericMessage[],
293
- newestMessage: GenericMessage,
298
+ retainedMessage: GenericMessage,
294
299
  messageStore: MessageStore,
295
300
  dataStore: DataStore,
296
- stateIndex: StateIndex
301
+ additionalRetainedRecordsWrites: RecordsWriteMessage[],
297
302
  ): Promise<void> {
298
- const deletedMessageCids: string[] = [];
303
+ const retainedMessageCid = await Message.getCid(retainedMessage);
304
+ const additionalRetainedRecordsWriteCids = new Set<string>();
305
+ for (const retainedRecordsWrite of additionalRetainedRecordsWrites) {
306
+ additionalRetainedRecordsWriteCids.add(await Message.getCid(retainedRecordsWrite));
307
+ }
299
308
 
300
309
  // NOTE: under normal operation, there should only be at most two existing records per `recordId` (initial + a potential subsequent write/delete),
301
310
  // but the DWN may crash before `delete()` is called below, so we use a loop as a tactic to clean up lingering data as needed
302
311
  for (const message of existingMessages) {
303
- const messageIsOld = await Message.isOlder(message, newestMessage);
304
- if (messageIsOld) {
312
+ const messageCid = await Message.getCid(message);
313
+ const messageIsDisplaced = messageCid !== retainedMessageCid;
314
+ if (messageIsDisplaced) {
305
315
  // the easiest implementation here is delete each old messages
306
- // and re-create it with the right index (isLatestBaseState = 'false') if the message is the initial write,
316
+ // and re-create it with the right index (isLatestBaseState = 'false') if the message is a retained write,
307
317
  // but there is room for better/more efficient implementation here
308
318
 
309
- await StorageController.deleteFromDataStoreIfNeeded(dataStore, tenant, message, newestMessage);
319
+ await StorageController.deleteFromDataStoreIfNeeded(dataStore, tenant, message, retainedMessage);
310
320
 
311
- // delete message from message store
312
- const messageCid = await Message.getCid(message);
313
- await messageStore.delete(tenant, messageCid);
314
-
315
- // if the existing message is the initial write
316
- // we actually need to keep it BUT, need to ensure the message is no longer marked as the latest state
317
- const existingMessageIsInitialWrite = await RecordsWrite.isInitialWrite(message);
318
- if (existingMessageIsInitialWrite) {
319
- const existingRecordsWrite = await RecordsWrite.parse(message as RecordsWriteMessage);
321
+ // Retained writes must stay in the message store and state index so future deletes and
322
+ // replicas can reconstruct tombstone visibility, but they must no longer be latest state.
323
+ const shouldKeepAsNonLatestWrite =
324
+ await RecordsWrite.isInitialWrite(message) ||
325
+ additionalRetainedRecordsWriteCids.has(messageCid);
326
+ if (shouldKeepAsNonLatestWrite) {
327
+ const retainedRecordsWriteMessage = StorageController.stripInlineData(message as RecordsWriteMessage);
328
+ const existingRecordsWrite = await RecordsWrite.parse(retainedRecordsWriteMessage);
320
329
  const isLatestBaseState = false;
321
330
  const indexes = await existingRecordsWrite.constructIndexes(isLatestBaseState);
322
- const writeMessage = message as RecordsQueryReplyEntry;
323
- delete writeMessage.encodedData;
324
- await messageStore.put(tenant, writeMessage, indexes);
331
+ await messageStore.updateMessageAndIndexes(tenant, messageCid, retainedRecordsWriteMessage, indexes);
325
332
  } else {
326
- const messageCid = await Message.getCid(message);
327
- deletedMessageCids.push(messageCid);
333
+ // delete message from message store
334
+ await messageStore.delete(tenant, messageCid);
328
335
  }
329
336
  }
330
-
331
- await stateIndex.delete(tenant, deletedMessageCids);
332
337
  }
333
338
  }
339
+
340
+ private static stripInlineData(message: RecordsWriteMessage): RecordsWriteMessage {
341
+ const retainedMessage = { ...message } as RecordsWriteMessage & { encodedData?: string };
342
+ delete retainedMessage.encodedData;
343
+ return retainedMessage;
344
+ }
334
345
  }
@@ -1,3 +1,4 @@
1
+ import type { ProgressToken } from './subscriptions.js';
1
2
  import type { Filter, KeyValues, PaginationCursor } from './query-types.js';
2
3
  import type { GenericMessage, MessageSort, Pagination } from './message-types.js';
3
4
 
@@ -5,6 +6,24 @@ export interface MessageStoreOptions {
5
6
  signal?: AbortSignal;
6
7
  }
7
8
 
9
+ /**
10
+ * Result of a {@link MessageStore.put} operation.
11
+ */
12
+ export type MessageStorePutResult = {
13
+ /**
14
+ * `inserted` when a new row was created; `duplicate` when a row for the same
15
+ * `(tenant, messageCid)` already exists.
16
+ */
17
+ status: 'inserted' | 'duplicate';
18
+
19
+ /**
20
+ * The inserted row's log position. Present for stores that maintain a
21
+ * replication log; omitted for duplicates and store implementations whose
22
+ * durable log support has not landed.
23
+ */
24
+ position?: ProgressToken;
25
+ };
26
+
8
27
  export interface MessageStore {
9
28
  /**
10
29
  * opens a connection to the underlying store
@@ -25,7 +44,7 @@ export interface MessageStore {
25
44
  message: GenericMessage,
26
45
  indexes: KeyValues,
27
46
  options?: MessageStoreOptions
28
- ): Promise<void>;
47
+ ): Promise<MessageStorePutResult>;
29
48
 
30
49
  /**
31
50
  * Fetches a single message by `cid` from the underlying store.
@@ -56,6 +75,30 @@ export interface MessageStore {
56
75
  options?: MessageStoreOptions
57
76
  ): Promise<number>;
58
77
 
78
+ /**
79
+ * Replaces the indexes of an existing message in place: same row and same log
80
+ * sequence.
81
+ */
82
+ updateIndexes(
83
+ tenant: string,
84
+ messageCid: string,
85
+ indexes: KeyValues,
86
+ options?: MessageStoreOptions
87
+ ): Promise<void>;
88
+
89
+ /**
90
+ * Replaces the stored same-CID message payload and indexes in place: same
91
+ * row and same log sequence. The replacement message must resolve to
92
+ * `messageCid` under DWN CID rules.
93
+ */
94
+ updateMessageAndIndexes(
95
+ tenant: string,
96
+ messageCid: string,
97
+ message: GenericMessage,
98
+ indexes: KeyValues,
99
+ options?: MessageStoreOptions
100
+ ): Promise<void>;
101
+
59
102
  /**
60
103
  * Deletes the message associated with the id provided.
61
104
  */
@@ -65,4 +108,4 @@ export interface MessageStore {
65
108
  * Clears the entire store. Mainly used for cleaning up in test environment.
66
109
  */
67
110
  clear(): Promise<void>;
68
- }
111
+ }
@@ -1,4 +1,5 @@
1
1
  import type { GeneralJws } from './jws-types.js';
2
+ import type { ProgressToken } from './subscriptions.js';
2
3
  import type { PublicKeyJwk } from './jose-types.js';
3
4
  import type { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
4
5
  import type { PaginationCursor, SortDirection } from './query-types.js';
@@ -145,10 +146,11 @@ export type Status = {
145
146
 
146
147
  export type GenericMessageReply = {
147
148
  status: Status;
149
+ position?: ProgressToken;
148
150
  };
149
151
 
150
152
  export type MessageSort = {
151
153
  dateCreated?: SortDirection;
152
154
  datePublished?: SortDirection;
153
155
  messageTimestamp?: SortDirection;
154
- };
156
+ };
@@ -42,57 +42,38 @@ export type MessagesReadReply = GenericMessageReply & {
42
42
  entry?: MessagesReadReplyEntry;
43
43
  };
44
44
 
45
- export type MessagesSyncAction = 'root' | 'subtree' | 'leaves' | 'diff';
46
-
47
- export type MessagesSyncDescriptor = {
48
- interface : DwnInterfaceName.Messages;
49
- method : DwnMethodName.Sync;
50
- messageTimestamp : string;
51
- action : MessagesSyncAction;
52
- protocol? : string; // optional protocol scope
53
- prefix? : string; // bit path for subtree/leaves (e.g. "0110101...")
54
- permissionGrantIds? : string[];
55
- /**
56
- * For `action: 'diff'`: a map of `{ bitPrefix: hexHash }` representing the client's
57
- * subtree hashes at `depth`. The server compares each hash against its own tree
58
- * and returns the set difference in a single round-trip.
59
- *
60
- * Only non-default (non-empty) subtree hashes need to be included — prefixes
61
- * whose hash equals the default empty-subtree hash may be omitted.
62
- */
63
- hashes? : Record<string, string>;
64
- /**
65
- * For `action: 'diff'`: the bit depth at which the client computed its subtree
66
- * hashes. Required when `action` is `'diff'`.
67
- */
68
- depth? : number;
45
+ export type MessagesQueryDescriptor = {
46
+ interface: DwnInterfaceName.Messages;
47
+ method: DwnMethodName.Query;
48
+ messageTimestamp: string;
49
+ filters: MessagesFilter[];
50
+ permissionGrantIds?: string[];
51
+ cursor?: ProgressToken;
52
+ limit?: number;
53
+ cidsOnly?: boolean;
69
54
  };
70
55
 
71
- export type MessagesSyncMessage = GenericMessage & {
72
- authorization : AuthorizationModel; // overriding `GenericMessage` with `authorization` being required
73
- descriptor : MessagesSyncDescriptor;
56
+ export type MessagesQueryMessage = {
57
+ authorization: AuthorizationModel;
58
+ descriptor: MessagesQueryDescriptor;
74
59
  };
75
60
 
76
- /**
77
- * Entry in a diff response representing a message the server has that the
78
- * client does not (or vice versa). Optionally includes the full message
79
- * and inline data for small payloads.
80
- */
81
- export type MessagesSyncDiffEntry = {
82
- messageCid : string;
83
- message? : GenericMessage;
84
- /** Base64url-encoded data for small RecordsWrite payloads (≤ maxInlineDataSize). */
85
- encodedData? : string;
61
+ export type MessagesQueryReplyEntry = {
62
+ seq: string;
63
+ messageCid: string;
64
+ isLatestBaseState: boolean;
65
+ protocol?: string;
66
+ message?: GenericMessage;
67
+ encodedData?: string;
86
68
  };
87
69
 
88
- export type MessagesSyncReply = GenericMessageReply & {
89
- root? : string; // hex-encoded root hash (for 'root' action)
90
- hash? : string; // hex-encoded subtree hash (for 'subtree' action)
91
- entries? : string[]; // messageCid[] (for 'leaves' action)
92
- /** For 'diff' action: messageCids (or full messages) that the server has but the client doesn't. */
93
- onlyRemote? : MessagesSyncDiffEntry[];
94
- /** For 'diff' action: bit prefixes where the client has entries the server doesn't. */
95
- onlyLocal? : string[];
70
+ export type MessagesQueryReply = GenericMessageReply & {
71
+ entries?: MessagesQueryReplyEntry[];
72
+ cursor?: ProgressToken;
73
+ drained?: boolean;
74
+ fingerprint?: string;
75
+ /** Present when status.code is 410 — structured gap metadata. */
76
+ error?: { code: 'ProgressGap' } & ProgressGapInfo;
96
77
  };
97
78
 
98
79
  export type MessagesSubscribeMessageOptions = {
@@ -3,7 +3,7 @@ import type { DataStore } from './data-store.js';
3
3
  import type { DidResolver } from '@enbox/dids';
4
4
  import type { MessageStore } from './message-store.js';
5
5
  import type { ResumableTaskManager } from '../core/resumable-task-manager.js';
6
- import type { StateIndex } from './state-index.js';
6
+ import type { ValidationStateReader } from './validation-state-reader.js';
7
7
  import type { EventLog, SubscriptionListener } from './subscriptions.js';
8
8
  import type { GenericMessage, GenericMessageReply } from './message-types.js';
9
9
 
@@ -17,7 +17,7 @@ export interface MethodHandler {
17
17
  handle(input: {
18
18
  tenant: string;
19
19
  message: GenericMessage;
20
- dataStream?: ReadableStream<Uint8Array>
20
+ dataStream?: ReadableStream<Uint8Array>;
21
21
  subscriptionHandler?: SubscriptionListener;
22
22
  }): Promise<GenericMessageReply>;
23
23
  }
@@ -32,8 +32,8 @@ export interface MethodHandler {
32
32
  export type HandlerDependencies = {
33
33
  didResolver: DidResolver;
34
34
  messageStore: MessageStore;
35
+ validationStateReader: ValidationStateReader;
35
36
  dataStore?: DataStore;
36
- stateIndex?: StateIndex;
37
37
  resumableTaskManager?: ResumableTaskManager;
38
38
  coreProtocols?: CoreProtocolRegistry;
39
39
  eventLog?: EventLog;
@@ -90,7 +90,7 @@ export type ProtocolPermissionScope = {
90
90
  * Permission scope for the Messages interface.
91
91
  *
92
92
  * `Read` is the only valid method and acts as a unified scope that authorizes
93
- * `MessagesRead`, `MessagesSubscribe`, and `MessagesSync` operations.
93
+ * `MessagesRead`, `MessagesQuery`, and `MessagesSubscribe` operations.
94
94
  */
95
95
  export type MessagesPermissionScope = {
96
96
  interface: DwnInterfaceName.Messages;
@@ -23,15 +23,18 @@ export type ProgressToken = {
23
23
  epoch : string;
24
24
  /** Monotonic decimal string within `(streamId, epoch)`. Compared numerically. */
25
25
  position : string;
26
- /** The CID of the message associated with this event. */
27
- messageCid : string;
26
+ /**
27
+ * The CID of the message associated with this event. Omitted for high-water
28
+ * cursors that do not point at a delivered in-scope message.
29
+ */
30
+ messageCid? : string;
28
31
  };
29
32
 
30
33
  /**
31
34
  * Reason code for a {@link ProgressGapInfo} — explains why the cursor
32
35
  * cannot be resumed.
33
36
  */
34
- export type ProgressGapReason = 'token_too_old' | 'epoch_mismatch' | 'stream_mismatch';
37
+ export type ProgressGapReason = 'token_too_old' | 'token_too_new' | 'epoch_mismatch' | 'stream_mismatch' | 'message_mismatch';
35
38
 
36
39
  /**
37
40
  * Metadata attached to a `DwnError(DwnErrorCode.EventLogProgressGap, ...)`
@@ -51,14 +54,7 @@ export type ProgressGapInfo = {
51
54
  };
52
55
 
53
56
  /**
54
- * Internal listener type used by {@link EventLog.emit} to notify in-process
55
- * subscribers. Not intended for direct consumer use — consumers should use
56
- * {@link SubscriptionListener} via {@link EventLog.subscribe}.
57
- */
58
- export type EventListener = (tenant: string, event: MessageEvent, indexes: KeyValues, seq: number) => void;
59
-
60
- /**
61
- * MessageEvent contains the message being emitted and an optional initial write message.
57
+ * MessageEvent contains a committed message and an optional initial write message.
62
58
  */
63
59
  export type MessageEvent = {
64
60
  message: GenericMessage;
@@ -92,6 +88,16 @@ export type SubscriptionEvent = {
92
88
  cursor : ProgressToken;
93
89
  /** The event payload (message + optional initialWrite). */
94
90
  event : MessageEvent;
91
+ /** Original row sequence for this message. */
92
+ seq? : string;
93
+ /** CID of the message that produced this event. */
94
+ messageCid? : string;
95
+ /** Whether this event's source row was latest base state at read time. */
96
+ isLatestBaseState? : boolean;
97
+ /** Protocol index value associated with the source row, when present. */
98
+ protocol? : string;
99
+ /** Base64url-encoded inline data carried beside the message payload. */
100
+ encodedData? : string;
95
101
  };
96
102
 
97
103
  /**
@@ -148,8 +154,7 @@ export type EventLogSubscribeOptions = {
148
154
  * an EOSE marker, then live events. When omitted, only live events are delivered.
149
155
  *
150
156
  * Tokens must be obtained from a prior interaction with the same EventLog
151
- * instance (e.g. `SubscriptionEvent.cursor`, `EventLogReadResult.cursor`,
152
- * or the return value of `emit()`).
157
+ * instance (e.g. `SubscriptionEvent.cursor` or `EventLogReadResult.cursor`).
153
158
  */
154
159
  cursor? : ProgressToken;
155
160
 
@@ -168,18 +173,23 @@ export type EventLogSubscribeOptions = {
168
173
  * A single entry returned by {@link EventLog.read}.
169
174
  */
170
175
  export type EventLogEntry = {
171
- /** Monotonic sequence number scoped to (instance, tenant). */
172
- seq: number;
176
+ /** Monotonic sequence number scoped to (instance, tenant), as a decimal string. */
177
+ seq: string;
178
+
179
+ /** The actual delivered log position. Equal to `seq` for store-backed feeds. */
180
+ position?: string;
173
181
 
174
182
  /** The event payload. */
175
183
  event: MessageEvent;
184
+ /** Base64url-encoded inline data carried beside the message payload. */
185
+ encodedData?: string;
176
186
 
177
187
  /** Indexes associated with the event (used for filter matching). */
178
188
  indexes: KeyValues;
179
189
 
180
190
  /**
181
191
  * The CID of the message that produced this event. Populated by
182
- * implementations that track it (e.g. {@link EventEmitterEventLog}).
192
+ * implementations that track it.
183
193
  * Consumers should fall back to computing the CID from the message
184
194
  * if this is absent.
185
195
  */
@@ -207,15 +217,11 @@ export type EventLogReadResult = {
207
217
  /** Events matching the read request, ordered by ascending seq. */
208
218
  events : EventLogEntry[];
209
219
 
210
- /**
211
- * Progress token for resuming subsequent reads or subscriptions.
212
- *
213
- * - When events are returned: token of the last event.
214
- * - When no events are returned but a cursor was provided: the input cursor
215
- * (meaning "you are caught up, nothing new since this point").
216
- * - When no events exist and no cursor was provided: `undefined`.
217
- */
220
+ /** High-water progress token for resuming subsequent reads or subscriptions. */
218
221
  cursor? : ProgressToken;
222
+
223
+ /** True when the scan reached the captured tenant head. */
224
+ drained : boolean;
219
225
  };
220
226
 
221
227
  /**
@@ -226,21 +232,11 @@ export type EventLogReadResult = {
226
232
  * that enable cursor-based resume after disconnects.
227
233
  *
228
234
  * The interface is intentionally transport-agnostic — implementations can be
229
- * backed by LevelDB (embedded), SQL, NATS JetStream, Redis Streams, etc.
230
- * Each implementation owns the catch-up + live transition strategy appropriate
231
- * to its backend (e.g., NATS pull consumers, Redis XREAD, in-memory buffering).
235
+ * backed by an embedded store, SQL, or another durable ordered feed. Each
236
+ * implementation owns the catch-up + live transition strategy appropriate to
237
+ * its backend.
232
238
  */
233
239
  export interface EventLog {
234
- /**
235
- * Persist an event and notify in-process subscribers.
236
- * @param tenant The tenant DID.
237
- * @param event The event payload.
238
- * @param indexes Index values for the event.
239
- * @param messageCid The CID of the message being emitted — embedded in the returned token.
240
- * @returns A {@link ProgressToken} assigned to the event, or `undefined` on failure.
241
- */
242
- emit(tenant: string, event: MessageEvent, indexes: KeyValues, messageCid: string): Promise<ProgressToken | undefined>;
243
-
244
240
  /**
245
241
  * Read events from the log starting after `cursor`, optionally filtered.
246
242
  */
@@ -270,11 +266,26 @@ export interface EventLog {
270
266
  */
271
267
  getReplayBounds(tenant: string): Promise<{ oldest: ProgressToken; latest: ProgressToken } | undefined>;
272
268
 
273
- /**
274
- * Delete events older than the given sequence number or ISO-8601 timestamp.
275
- */
276
- trim(tenant: string, olderThan: number | string): Promise<void>;
277
-
278
269
  open(): Promise<void>;
279
270
  close(): Promise<void>;
280
271
  }
272
+
273
+ export type Wake = {
274
+ tenant : string;
275
+ seq : string;
276
+ };
277
+
278
+ export interface WakePublisher {
279
+ publish(wake: Wake): void;
280
+ }
281
+
282
+ export interface WakeSubscriber {
283
+ subscribe(listener: (wake: Wake) => void): () => void;
284
+ }
285
+
286
+ export interface ReplicationFeedReader {
287
+ logRead(tenant: string, options?: EventLogReadOptions): Promise<EventLogReadResult>;
288
+ logBounds(tenant: string): Promise<{ oldest: ProgressToken; latest: ProgressToken } | undefined>;
289
+ fingerprint(tenant: string, scopes: string[]): Promise<string>;
290
+ epoch(): Promise<string>;
291
+ }