@enbox/dwn-sdk-js 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (513) hide show
  1. package/README.md +4 -4
  2. package/dist/browser.mjs +8 -8
  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 +30 -68
  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 +7 -3
  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/record-limit-occupancy.js +244 -0
  99. package/dist/esm/src/utils/record-limit-occupancy.js.map +1 -0
  100. package/dist/esm/src/utils/records.js +50 -14
  101. package/dist/esm/src/utils/records.js.map +1 -1
  102. package/dist/esm/src/utils/replication.js +85 -0
  103. package/dist/esm/src/utils/replication.js.map +1 -0
  104. package/dist/esm/tests/core/grant-authorization.spec.js +4 -4
  105. package/dist/esm/tests/core/grant-authorization.spec.js.map +1 -1
  106. package/dist/esm/tests/core/process-message-parity.spec.js +222 -0
  107. package/dist/esm/tests/core/process-message-parity.spec.js.map +1 -0
  108. package/dist/esm/tests/core/protocol-authorization.spec.js +5 -2
  109. package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
  110. package/dist/esm/tests/core/records-grant-authorization.spec.js +5 -5
  111. package/dist/esm/tests/core/records-grant-authorization.spec.js.map +1 -1
  112. package/dist/esm/tests/core/replication-apply.spec.js +55 -1
  113. package/dist/esm/tests/core/replication-apply.spec.js.map +1 -1
  114. package/dist/esm/tests/core/replication-replay-property.spec.js +350 -0
  115. package/dist/esm/tests/core/replication-replay-property.spec.js.map +1 -0
  116. package/dist/esm/tests/core/validation-read-closure.spec.js +469 -0
  117. package/dist/esm/tests/core/validation-read-closure.spec.js.map +1 -0
  118. package/dist/esm/tests/core/validation-state-reader.spec.js +716 -0
  119. package/dist/esm/tests/core/validation-state-reader.spec.js.map +1 -0
  120. package/dist/esm/tests/durable-event-log.spec.js +373 -0
  121. package/dist/esm/tests/durable-event-log.spec.js.map +1 -0
  122. package/dist/esm/tests/dwn.spec.js +504 -35
  123. package/dist/esm/tests/dwn.spec.js.map +1 -1
  124. package/dist/esm/tests/features/author-delegated-grant.spec.js +9 -6
  125. package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
  126. package/dist/esm/tests/features/owner-delegated-grant.spec.js +1 -4
  127. package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
  128. package/dist/esm/tests/features/owner-signature.spec.js +1 -4
  129. package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
  130. package/dist/esm/tests/features/permissions.spec.js +165 -4
  131. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  132. package/dist/esm/tests/features/protocol-composition.spec.js +8 -11
  133. package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
  134. package/dist/esm/tests/features/protocol-create-action.spec.js +1 -4
  135. package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
  136. package/dist/esm/tests/features/protocol-delete-action.spec.js +3 -5
  137. package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
  138. package/dist/esm/tests/features/protocol-update-action.spec.js +3 -6
  139. package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
  140. package/dist/esm/tests/features/records-delivery.spec.js +1 -4
  141. package/dist/esm/tests/features/records-delivery.spec.js.map +1 -1
  142. package/dist/esm/tests/features/records-immutable.spec.js +1 -4
  143. package/dist/esm/tests/features/records-immutable.spec.js.map +1 -1
  144. package/dist/esm/tests/features/records-nested-query-scope.spec.js +281 -0
  145. package/dist/esm/tests/features/records-nested-query-scope.spec.js.map +1 -0
  146. package/dist/esm/tests/features/records-prune-cross-protocol.spec.js +3 -7
  147. package/dist/esm/tests/features/records-prune-cross-protocol.spec.js.map +1 -1
  148. package/dist/esm/tests/features/records-prune.spec.js +11 -22
  149. package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
  150. package/dist/esm/tests/features/records-record-limit.spec.js +441 -231
  151. package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -1
  152. package/dist/esm/tests/features/records-squash.spec.js +6 -4
  153. package/dist/esm/tests/features/records-squash.spec.js.map +1 -1
  154. package/dist/esm/tests/features/records-tags.spec.js +1 -4
  155. package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
  156. package/dist/esm/tests/features/resumable-tasks.spec.js +3 -5
  157. package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
  158. package/dist/esm/tests/fuzz/message-store.fuzz.spec.js +1 -2
  159. package/dist/esm/tests/fuzz/message-store.fuzz.spec.js.map +1 -1
  160. package/dist/esm/tests/fuzz/process-message.fuzz.spec.js +2 -4
  161. package/dist/esm/tests/fuzz/process-message.fuzz.spec.js.map +1 -1
  162. package/dist/esm/tests/fuzz/schema-validation.fuzz.spec.js +1 -1
  163. package/dist/esm/tests/fuzz/schema-validation.fuzz.spec.js.map +1 -1
  164. package/dist/esm/tests/handlers/messages-query.spec.js +246 -0
  165. package/dist/esm/tests/handlers/messages-query.spec.js.map +1 -0
  166. package/dist/esm/tests/handlers/messages-read.spec.js +2 -5
  167. package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
  168. package/dist/esm/tests/handlers/messages-subscribe.spec.js +3 -14
  169. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  170. package/dist/esm/tests/handlers/protocols-configure.spec.js +27 -26
  171. package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
  172. package/dist/esm/tests/handlers/protocols-query.spec.js +1 -4
  173. package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
  174. package/dist/esm/tests/handlers/records-count.spec.js +1 -4
  175. package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
  176. package/dist/esm/tests/handlers/records-delete.spec.js +312 -30
  177. package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
  178. package/dist/esm/tests/handlers/records-query.spec.js +32 -9
  179. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  180. package/dist/esm/tests/handlers/records-read.spec.js +4 -4
  181. package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
  182. package/dist/esm/tests/handlers/records-subscribe.spec.js +33 -14
  183. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  184. package/dist/esm/tests/handlers/records-write.spec.js +82 -36
  185. package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
  186. package/dist/esm/tests/interfaces/records-delete.spec.js +69 -2
  187. package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -1
  188. package/dist/esm/tests/interfaces/records-write.spec.js +4 -3
  189. package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
  190. package/dist/esm/tests/protocols/permissions.spec.js +55 -6
  191. package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
  192. package/dist/esm/tests/scenarios/aggregator.spec.js +1 -4
  193. package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
  194. package/dist/esm/tests/scenarios/deleted-record.spec.js +1 -4
  195. package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
  196. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +1 -4
  197. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
  198. package/dist/esm/tests/scenarios/nested-roles.spec.js +1 -4
  199. package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
  200. package/dist/esm/tests/scenarios/subscriptions.spec.js +1 -4
  201. package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
  202. package/dist/esm/tests/store/message-store-level.spec.js +361 -5
  203. package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
  204. package/dist/esm/tests/store/message-store.spec.js +60 -0
  205. package/dist/esm/tests/store/message-store.spec.js.map +1 -1
  206. package/dist/esm/tests/test-event-stream.js +7 -3
  207. package/dist/esm/tests/test-event-stream.js.map +1 -1
  208. package/dist/esm/tests/test-stores.js +19 -9
  209. package/dist/esm/tests/test-stores.js.map +1 -1
  210. package/dist/esm/tests/test-suite.js +4 -2
  211. package/dist/esm/tests/test-suite.js.map +1 -1
  212. package/dist/esm/tests/utils/test-data-generator.js +25 -0
  213. package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
  214. package/dist/esm/tests/utils/test-stub-generator.js.map +1 -1
  215. package/dist/esm/tests/utils/test-validation-state-reader.js +16 -0
  216. package/dist/esm/tests/utils/test-validation-state-reader.js.map +1 -0
  217. package/dist/types/generated/precompiled-validators.d.ts +6 -6
  218. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  219. package/dist/types/src/core/core-protocol.d.ts +3 -3
  220. package/dist/types/src/core/core-protocol.d.ts.map +1 -1
  221. package/dist/types/src/core/dwn-constant.d.ts +5 -0
  222. package/dist/types/src/core/dwn-constant.d.ts.map +1 -1
  223. package/dist/types/src/core/dwn-error.d.ts +12 -4
  224. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  225. package/dist/types/src/core/grant-authorization.d.ts +5 -5
  226. package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
  227. package/dist/types/src/core/message-reply.d.ts +5 -4
  228. package/dist/types/src/core/message-reply.d.ts.map +1 -1
  229. package/dist/types/src/core/messages-grant-authorization.d.ts +12 -14
  230. package/dist/types/src/core/messages-grant-authorization.d.ts.map +1 -1
  231. package/dist/types/src/core/protocol-authorization-action.d.ts +4 -5
  232. package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -1
  233. package/dist/types/src/core/protocol-authorization-validation.d.ts +13 -16
  234. package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
  235. package/dist/types/src/core/protocol-authorization.d.ts +8 -33
  236. package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
  237. package/dist/types/src/core/protocols-grant-authorization.d.ts +4 -4
  238. package/dist/types/src/core/protocols-grant-authorization.d.ts.map +1 -1
  239. package/dist/types/src/core/recording-validation-state-reader.d.ts +75 -0
  240. package/dist/types/src/core/recording-validation-state-reader.d.ts.map +1 -0
  241. package/dist/types/src/core/records-grant-authorization.d.ts +8 -8
  242. package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
  243. package/dist/types/src/core/replication-apply.d.ts +36 -0
  244. package/dist/types/src/core/replication-apply.d.ts.map +1 -1
  245. package/dist/types/src/core/resumable-task-manager.d.ts +1 -1
  246. package/dist/types/src/core/resumable-task-manager.d.ts.map +1 -1
  247. package/dist/types/src/core/validation-state-reader.d.ts +79 -0
  248. package/dist/types/src/core/validation-state-reader.d.ts.map +1 -0
  249. package/dist/types/src/dwn.d.ts +33 -20
  250. package/dist/types/src/dwn.d.ts.map +1 -1
  251. package/dist/types/src/enums/dwn-interface-method.d.ts +0 -1
  252. package/dist/types/src/enums/dwn-interface-method.d.ts.map +1 -1
  253. package/dist/types/src/event-stream/durable-event-log.d.ts +69 -0
  254. package/dist/types/src/event-stream/durable-event-log.d.ts.map +1 -0
  255. package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts +13 -0
  256. package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts.map +1 -0
  257. package/dist/types/src/handlers/messages-query.d.ts +20 -0
  258. package/dist/types/src/handlers/messages-query.d.ts.map +1 -0
  259. package/dist/types/src/handlers/messages-read.d.ts +1 -1
  260. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  261. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  262. package/dist/types/src/handlers/protocols-configure.d.ts +0 -5
  263. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  264. package/dist/types/src/handlers/records-count.d.ts +2 -1
  265. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  266. package/dist/types/src/handlers/records-delete.d.ts +2 -2
  267. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  268. package/dist/types/src/handlers/records-query.d.ts +1 -1
  269. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  270. package/dist/types/src/handlers/records-read.d.ts +2 -1
  271. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  272. package/dist/types/src/handlers/records-subscribe.d.ts +4 -5
  273. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  274. package/dist/types/src/handlers/records-write.d.ts +3 -11
  275. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  276. package/dist/types/src/index.d.ts +14 -16
  277. package/dist/types/src/index.d.ts.map +1 -1
  278. package/dist/types/src/interfaces/messages-query.d.ts +23 -0
  279. package/dist/types/src/interfaces/messages-query.d.ts.map +1 -0
  280. package/dist/types/src/interfaces/protocols-configure.d.ts +3 -3
  281. package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
  282. package/dist/types/src/interfaces/protocols-query.d.ts +2 -2
  283. package/dist/types/src/interfaces/protocols-query.d.ts.map +1 -1
  284. package/dist/types/src/interfaces/records-count.d.ts +3 -3
  285. package/dist/types/src/interfaces/records-count.d.ts.map +1 -1
  286. package/dist/types/src/interfaces/records-delete.d.ts +11 -3
  287. package/dist/types/src/interfaces/records-delete.d.ts.map +1 -1
  288. package/dist/types/src/interfaces/records-query.d.ts +3 -3
  289. package/dist/types/src/interfaces/records-query.d.ts.map +1 -1
  290. package/dist/types/src/interfaces/records-read.d.ts +3 -3
  291. package/dist/types/src/interfaces/records-read.d.ts.map +1 -1
  292. package/dist/types/src/interfaces/records-subscribe.d.ts +3 -3
  293. package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
  294. package/dist/types/src/interfaces/records-write.d.ts +15 -7
  295. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  296. package/dist/types/src/protocols/permissions.d.ts +9 -12
  297. package/dist/types/src/protocols/permissions.d.ts.map +1 -1
  298. package/dist/types/src/store/index-level.d.ts +10 -1
  299. package/dist/types/src/store/index-level.d.ts.map +1 -1
  300. package/dist/types/src/store/level-wrapper.d.ts +5 -0
  301. package/dist/types/src/store/level-wrapper.d.ts.map +1 -1
  302. package/dist/types/src/store/message-store-level.d.ts +94 -14
  303. package/dist/types/src/store/message-store-level.d.ts.map +1 -1
  304. package/dist/types/src/store/storage-controller.d.ts +17 -14
  305. package/dist/types/src/store/storage-controller.d.ts.map +1 -1
  306. package/dist/types/src/types/message-store.d.ts +29 -1
  307. package/dist/types/src/types/message-store.d.ts.map +1 -1
  308. package/dist/types/src/types/message-types.d.ts +2 -0
  309. package/dist/types/src/types/message-types.d.ts.map +1 -1
  310. package/dist/types/src/types/messages-types.d.ts +21 -37
  311. package/dist/types/src/types/messages-types.d.ts.map +1 -1
  312. package/dist/types/src/types/method-handler.d.ts +2 -2
  313. package/dist/types/src/types/method-handler.d.ts.map +1 -1
  314. package/dist/types/src/types/permission-types.d.ts +1 -1
  315. package/dist/types/src/types/subscriptions.d.ts +50 -39
  316. package/dist/types/src/types/subscriptions.d.ts.map +1 -1
  317. package/dist/types/src/types/validation-state-reader.d.ts +116 -0
  318. package/dist/types/src/types/validation-state-reader.d.ts.map +1 -0
  319. package/dist/types/src/utils/messages.d.ts +10 -0
  320. package/dist/types/src/utils/messages.d.ts.map +1 -1
  321. package/dist/types/src/utils/record-limit-occupancy.d.ts +40 -0
  322. package/dist/types/src/utils/record-limit-occupancy.d.ts.map +1 -0
  323. package/dist/types/src/utils/records.d.ts +25 -3
  324. package/dist/types/src/utils/records.d.ts.map +1 -1
  325. package/dist/types/src/utils/replication.d.ts +22 -0
  326. package/dist/types/src/utils/replication.d.ts.map +1 -0
  327. package/dist/types/tests/core/process-message-parity.spec.d.ts +2 -0
  328. package/dist/types/tests/core/process-message-parity.spec.d.ts.map +1 -0
  329. package/dist/types/tests/core/replication-replay-property.spec.d.ts +2 -0
  330. package/dist/types/tests/core/replication-replay-property.spec.d.ts.map +1 -0
  331. package/dist/types/tests/core/validation-read-closure.spec.d.ts +2 -0
  332. package/dist/types/tests/core/validation-read-closure.spec.d.ts.map +1 -0
  333. package/dist/types/tests/core/validation-state-reader.spec.d.ts +2 -0
  334. package/dist/types/tests/core/validation-state-reader.spec.d.ts.map +1 -0
  335. package/dist/types/tests/durable-event-log.spec.d.ts +2 -0
  336. package/dist/types/tests/durable-event-log.spec.d.ts.map +1 -0
  337. package/dist/types/tests/dwn.spec.d.ts.map +1 -1
  338. package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -1
  339. package/dist/types/tests/features/owner-delegated-grant.spec.d.ts.map +1 -1
  340. package/dist/types/tests/features/owner-signature.spec.d.ts.map +1 -1
  341. package/dist/types/tests/features/permissions.spec.d.ts.map +1 -1
  342. package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -1
  343. package/dist/types/tests/features/protocol-create-action.spec.d.ts.map +1 -1
  344. package/dist/types/tests/features/protocol-delete-action.spec.d.ts.map +1 -1
  345. package/dist/types/tests/features/protocol-update-action.spec.d.ts.map +1 -1
  346. package/dist/types/tests/features/records-delivery.spec.d.ts.map +1 -1
  347. package/dist/types/tests/features/records-immutable.spec.d.ts.map +1 -1
  348. package/dist/types/tests/features/records-nested-query-scope.spec.d.ts +2 -0
  349. package/dist/types/tests/features/records-nested-query-scope.spec.d.ts.map +1 -0
  350. package/dist/types/tests/features/records-prune-cross-protocol.spec.d.ts.map +1 -1
  351. package/dist/types/tests/features/records-prune.spec.d.ts.map +1 -1
  352. package/dist/types/tests/features/records-record-limit.spec.d.ts.map +1 -1
  353. package/dist/types/tests/features/records-squash.spec.d.ts.map +1 -1
  354. package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -1
  355. package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -1
  356. package/dist/types/tests/handlers/messages-query.spec.d.ts +2 -0
  357. package/dist/types/tests/handlers/messages-query.spec.d.ts.map +1 -0
  358. package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
  359. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  360. package/dist/types/tests/handlers/protocols-configure.spec.d.ts.map +1 -1
  361. package/dist/types/tests/handlers/protocols-query.spec.d.ts.map +1 -1
  362. package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
  363. package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
  364. package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
  365. package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
  366. package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
  367. package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
  368. package/dist/types/tests/scenarios/deleted-record.spec.d.ts.map +1 -1
  369. package/dist/types/tests/scenarios/end-to-end-tests.spec.d.ts.map +1 -1
  370. package/dist/types/tests/scenarios/nested-roles.spec.d.ts.map +1 -1
  371. package/dist/types/tests/scenarios/subscriptions.spec.d.ts.map +1 -1
  372. package/dist/types/tests/store/message-store.spec.d.ts.map +1 -1
  373. package/dist/types/tests/test-event-stream.d.ts +1 -1
  374. package/dist/types/tests/test-event-stream.d.ts.map +1 -1
  375. package/dist/types/tests/test-stores.d.ts +5 -4
  376. package/dist/types/tests/test-stores.d.ts.map +1 -1
  377. package/dist/types/tests/test-suite.d.ts +1 -2
  378. package/dist/types/tests/test-suite.d.ts.map +1 -1
  379. package/dist/types/tests/utils/test-data-generator.d.ts +20 -1
  380. package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
  381. package/dist/types/tests/utils/test-validation-state-reader.d.ts +15 -0
  382. package/dist/types/tests/utils/test-validation-state-reader.d.ts.map +1 -0
  383. package/package.json +2 -2
  384. package/src/core/core-protocol.ts +3 -3
  385. package/src/core/dwn-constant.ts +7 -1
  386. package/src/core/dwn-error.ts +12 -4
  387. package/src/core/grant-authorization.ts +11 -20
  388. package/src/core/message-reply.ts +6 -5
  389. package/src/core/messages-grant-authorization.ts +37 -70
  390. package/src/core/protocol-authorization-action.ts +29 -38
  391. package/src/core/protocol-authorization-validation.ts +39 -96
  392. package/src/core/protocol-authorization.ts +56 -202
  393. package/src/core/protocols-grant-authorization.ts +9 -9
  394. package/src/core/recording-validation-state-reader.ts +130 -0
  395. package/src/core/records-grant-authorization.ts +16 -16
  396. package/src/core/replication-apply.ts +172 -32
  397. package/src/core/resumable-task-manager.ts +10 -8
  398. package/src/core/validation-state-reader.ts +350 -0
  399. package/src/dwn.ts +285 -192
  400. package/src/enums/dwn-interface-method.ts +0 -1
  401. package/src/event-stream/durable-event-log.ts +509 -0
  402. package/src/event-stream/event-emitter-wake-publisher.ts +34 -0
  403. package/src/handlers/messages-query.ts +203 -0
  404. package/src/handlers/messages-read.ts +9 -10
  405. package/src/handlers/messages-subscribe.ts +12 -13
  406. package/src/handlers/protocols-configure.ts +37 -58
  407. package/src/handlers/protocols-query.ts +1 -1
  408. package/src/handlers/records-count.ts +24 -17
  409. package/src/handlers/records-delete.ts +29 -27
  410. package/src/handlers/records-query.ts +38 -17
  411. package/src/handlers/records-read.ts +63 -50
  412. package/src/handlers/records-subscribe.ts +132 -19
  413. package/src/handlers/records-write.ts +77 -168
  414. package/src/index.ts +14 -17
  415. package/src/interfaces/messages-query.ts +70 -0
  416. package/src/interfaces/protocols-configure.ts +12 -4
  417. package/src/interfaces/protocols-query.ts +4 -5
  418. package/src/interfaces/records-count.ts +9 -4
  419. package/src/interfaces/records-delete.ts +25 -5
  420. package/src/interfaces/records-query.ts +9 -4
  421. package/src/interfaces/records-read.ts +4 -4
  422. package/src/interfaces/records-subscribe.ts +9 -4
  423. package/src/interfaces/records-write.ts +41 -13
  424. package/src/protocols/permissions.ts +32 -52
  425. package/src/store/index-level.ts +30 -9
  426. package/src/store/level-wrapper.ts +9 -1
  427. package/src/store/message-store-level.ts +757 -47
  428. package/src/store/storage-controller.ts +74 -63
  429. package/src/types/message-store.ts +45 -2
  430. package/src/types/message-types.ts +3 -1
  431. package/src/types/messages-types.ts +26 -45
  432. package/src/types/method-handler.ts +3 -3
  433. package/src/types/permission-types.ts +1 -1
  434. package/src/types/subscriptions.ts +53 -42
  435. package/src/types/validation-state-reader.ts +127 -0
  436. package/src/utils/messages.ts +25 -1
  437. package/src/utils/record-limit-occupancy.ts +377 -0
  438. package/src/utils/records.ts +69 -13
  439. package/src/utils/replication.ts +122 -0
  440. package/dist/esm/src/core/record-chain.js +0 -64
  441. package/dist/esm/src/core/record-chain.js.map +0 -1
  442. package/dist/esm/src/event-stream/event-emitter-event-log.js +0 -334
  443. package/dist/esm/src/event-stream/event-emitter-event-log.js.map +0 -1
  444. package/dist/esm/src/handlers/messages-sync.js +0 -278
  445. package/dist/esm/src/handlers/messages-sync.js.map +0 -1
  446. package/dist/esm/src/interfaces/messages-sync.js.map +0 -1
  447. package/dist/esm/src/smt/smt-store-level.js +0 -103
  448. package/dist/esm/src/smt/smt-store-level.js.map +0 -1
  449. package/dist/esm/src/smt/smt-store-memory.js +0 -41
  450. package/dist/esm/src/smt/smt-store-memory.js.map +0 -1
  451. package/dist/esm/src/smt/smt-utils.js +0 -129
  452. package/dist/esm/src/smt/smt-utils.js.map +0 -1
  453. package/dist/esm/src/smt/sparse-merkle-tree.js +0 -577
  454. package/dist/esm/src/smt/sparse-merkle-tree.js.map +0 -1
  455. package/dist/esm/src/state-index/state-index-level.js +0 -191
  456. package/dist/esm/src/state-index/state-index-level.js.map +0 -1
  457. package/dist/esm/src/types/smt-types.js +0 -5
  458. package/dist/esm/src/types/smt-types.js.map +0 -1
  459. package/dist/esm/src/types/state-index.js +0 -2
  460. package/dist/esm/src/types/state-index.js.map +0 -1
  461. package/dist/esm/tests/event-emitter-event-log.spec.js +0 -499
  462. package/dist/esm/tests/event-emitter-event-log.spec.js.map +0 -1
  463. package/dist/esm/tests/handlers/messages-sync.spec.js +0 -1088
  464. package/dist/esm/tests/handlers/messages-sync.spec.js.map +0 -1
  465. package/dist/esm/tests/smt/smt-store-level.spec.js +0 -132
  466. package/dist/esm/tests/smt/smt-store-level.spec.js.map +0 -1
  467. package/dist/esm/tests/smt/sparse-merkle-tree.spec.js +0 -732
  468. package/dist/esm/tests/smt/sparse-merkle-tree.spec.js.map +0 -1
  469. package/dist/esm/tests/state-index/state-index-level.spec.js +0 -245
  470. package/dist/esm/tests/state-index/state-index-level.spec.js.map +0 -1
  471. package/dist/types/src/core/record-chain.d.ts +0 -24
  472. package/dist/types/src/core/record-chain.d.ts.map +0 -1
  473. package/dist/types/src/event-stream/event-emitter-event-log.d.ts +0 -80
  474. package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +0 -1
  475. package/dist/types/src/handlers/messages-sync.d.ts +0 -39
  476. package/dist/types/src/handlers/messages-sync.d.ts.map +0 -1
  477. package/dist/types/src/interfaces/messages-sync.d.ts +0 -20
  478. package/dist/types/src/interfaces/messages-sync.d.ts.map +0 -1
  479. package/dist/types/src/smt/smt-store-level.d.ts +0 -32
  480. package/dist/types/src/smt/smt-store-level.d.ts.map +0 -1
  481. package/dist/types/src/smt/smt-store-memory.d.ts +0 -22
  482. package/dist/types/src/smt/smt-store-memory.d.ts.map +0 -1
  483. package/dist/types/src/smt/smt-utils.d.ts +0 -58
  484. package/dist/types/src/smt/smt-utils.d.ts.map +0 -1
  485. package/dist/types/src/smt/sparse-merkle-tree.d.ts +0 -124
  486. package/dist/types/src/smt/sparse-merkle-tree.d.ts.map +0 -1
  487. package/dist/types/src/state-index/state-index-level.d.ts +0 -83
  488. package/dist/types/src/state-index/state-index-level.d.ts.map +0 -1
  489. package/dist/types/src/types/smt-types.d.ts +0 -81
  490. package/dist/types/src/types/smt-types.d.ts.map +0 -1
  491. package/dist/types/src/types/state-index.d.ts +0 -90
  492. package/dist/types/src/types/state-index.d.ts.map +0 -1
  493. package/dist/types/tests/event-emitter-event-log.spec.d.ts +0 -2
  494. package/dist/types/tests/event-emitter-event-log.spec.d.ts.map +0 -1
  495. package/dist/types/tests/handlers/messages-sync.spec.d.ts +0 -2
  496. package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +0 -1
  497. package/dist/types/tests/smt/smt-store-level.spec.d.ts +0 -2
  498. package/dist/types/tests/smt/smt-store-level.spec.d.ts.map +0 -1
  499. package/dist/types/tests/smt/sparse-merkle-tree.spec.d.ts +0 -2
  500. package/dist/types/tests/smt/sparse-merkle-tree.spec.d.ts.map +0 -1
  501. package/dist/types/tests/state-index/state-index-level.spec.d.ts +0 -2
  502. package/dist/types/tests/state-index/state-index-level.spec.d.ts.map +0 -1
  503. package/src/core/record-chain.ts +0 -99
  504. package/src/event-stream/event-emitter-event-log.ts +0 -430
  505. package/src/handlers/messages-sync.ts +0 -403
  506. package/src/interfaces/messages-sync.ts +0 -69
  507. package/src/smt/smt-store-level.ts +0 -143
  508. package/src/smt/smt-store-memory.ts +0 -53
  509. package/src/smt/smt-utils.ts +0 -149
  510. package/src/smt/sparse-merkle-tree.ts +0 -698
  511. package/src/state-index/state-index-level.ts +0 -239
  512. package/src/types/smt-types.ts +0 -95
  513. package/src/types/state-index.ts +0 -100
@@ -1,11 +1,10 @@
1
1
  import type { AuthorizationModel } from '../types/message-types.js';
2
2
  import type { MessageSigner } from '../types/signer.js';
3
- import type { MessageStore } from '../types/message-store.js';
3
+ import type { ValidationStateReader } from '../types/validation-state-reader.js';
4
4
  import type { ProtocolsQueryDescriptor, ProtocolsQueryFilter, ProtocolsQueryMessage } from '../types/protocols-types.js';
5
5
 
6
6
  import { AbstractMessage } from '../core/abstract-message.js';
7
7
  import { Message } from '../core/message.js';
8
- import { PermissionsProtocol } from '../protocols/permissions.js';
9
8
  import { ProtocolsGrantAuthorization } from '../core/protocols-grant-authorization.js';
10
9
  import { removeUndefinedProperties } from '@enbox/common';
11
10
  import { Time } from '../utils/time.js';
@@ -77,19 +76,19 @@ export class ProtocolsQuery extends AbstractMessage<ProtocolsQueryMessage> {
77
76
  };
78
77
  }
79
78
 
80
- public async authorize(tenant: string, messageStore: MessageStore): Promise<void> {
79
+ public async authorize(tenant: string, validationStateReader: ValidationStateReader): Promise<void> {
81
80
  // if author is the same as the target tenant, we can directly grant access
82
81
  if (this.author === tenant) {
83
82
  return;
84
83
  } else if (this.author !== undefined && Message.getPermissionGrantId(this.signaturePayload!) !== undefined) {
85
84
  const permissionGrantId = Message.getPermissionGrantId(this.signaturePayload!)!;
86
- const permissionGrant = await PermissionsProtocol.fetchGrant(tenant, messageStore, permissionGrantId);
85
+ const permissionGrant = await validationStateReader.fetchGrant(tenant, permissionGrantId);
87
86
  await ProtocolsGrantAuthorization.authorizeQuery({
88
87
  expectedGrantor : tenant,
89
88
  expectedGrantee : this.author,
90
89
  incomingMessage : this.message,
91
90
  permissionGrant,
92
- messageStore
91
+ validationStateReader
93
92
  });
94
93
  } else {
95
94
  throw new DwnError(
@@ -1,5 +1,5 @@
1
1
  import type { MessageSigner } from '../types/signer.js';
2
- import type { MessageStore } from '../types/message-store.js';
2
+ import type { ValidationStateReader } from '../types/validation-state-reader.js';
3
3
  import type { DataEncodedRecordsWriteMessage, RecordsCountDescriptor, RecordsCountMessage, RecordsFilter } from '../types/records-types.js';
4
4
 
5
5
  import { AbstractMessage } from '../core/abstract-message.js';
@@ -38,6 +38,11 @@ export class RecordsCount extends AbstractMessage<RecordsCountMessage> {
38
38
  }
39
39
 
40
40
  await Records.validateDelegatedGrantReferentialIntegrity(message, signaturePayload);
41
+ Records.validateNestedProtocolPathQueryScope(
42
+ message.descriptor.filter,
43
+ DwnErrorCode.RecordsCountNestedProtocolPathContextIdInvalid,
44
+ 'RecordsCount'
45
+ );
41
46
 
42
47
  if (signaturePayload?.protocolRole !== undefined) {
43
48
  if (message.descriptor.filter.protocolPath === undefined) {
@@ -98,16 +103,16 @@ export class RecordsCount extends AbstractMessage<RecordsCountMessage> {
98
103
 
99
104
  /**
100
105
  * Authorizes the delegate who signed the message.
101
- * @param messageStore Used to check if the grant has been revoked.
106
+ * @param validationStateReader Used to check if the grant has been revoked.
102
107
  */
103
- public async authorizeDelegate(messageStore: MessageStore): Promise<void> {
108
+ public async authorizeDelegate(validationStateReader: ValidationStateReader): Promise<void> {
104
109
  const delegatedGrant = PermissionGrant.parse(this.message.authorization!.authorDelegatedGrant!);
105
110
  await RecordsGrantAuthorization.authorizeQueryOrSubscribe({
106
111
  incomingMessage : this.message,
107
112
  expectedGrantor : this.author!,
108
113
  expectedGrantee : this.signer!,
109
114
  permissionGrant : delegatedGrant,
110
- messageStore
115
+ validationStateReader
111
116
  });
112
117
  }
113
118
  }
@@ -1,6 +1,6 @@
1
1
  import type { KeyValues } from '../types/query-types.js';
2
2
  import type { MessageSigner } from '../types/signer.js';
3
- import type { MessageStore } from '../types//message-store.js';
3
+ import type { ValidationStateReader } from '../types/validation-state-reader.js';
4
4
  import type { DataEncodedRecordsWriteMessage, RecordsDeleteDescriptor, RecordsDeleteMessage, RecordsWriteMessage } from '../types/records-types.js';
5
5
 
6
6
  import { AbstractMessage } from '../core/abstract-message.js';
@@ -87,9 +87,18 @@ export class RecordsDelete extends AbstractMessage<RecordsDeleteMessage> {
87
87
 
88
88
  /**
89
89
  * Indexed properties needed for MessageStore indexing.
90
+ *
91
+ * Immutable record facts (`protocol`, `protocolPath`, `recipient`, `schema`, `parentId`,
92
+ * `dateCreated`, `contextId`) come from the initial `RecordsWrite`. Mutable query-visibility
93
+ * facts (flattened `tag.*`, `published`, and `datePublished`) come from the newest retained
94
+ * `RecordsWrite` that existed immediately before this delete, because tombstone visibility must
95
+ * reflect the record state being deleted: without them, tombstones of tagged records never match
96
+ * tag filters (e.g. the permission shadow filters on `tag.protocol`) and tombstones of published
97
+ * records never match `published: true` or `datePublished` queries and subscriptions.
90
98
  */
91
99
  public constructIndexes(
92
100
  initialWrite: RecordsWriteMessage,
101
+ visibilitySourceWrite: RecordsWriteMessage,
93
102
  ): KeyValues {
94
103
  const message = this.message;
95
104
  const descriptor = { ...message.descriptor };
@@ -97,8 +106,13 @@ export class RecordsDelete extends AbstractMessage<RecordsDeleteMessage> {
97
106
  // we add the immutable properties from the initial RecordsWrite message in order to use them when querying relevant deletes.
98
107
  const { protocol, protocolPath, recipient, schema, parentId, dateCreated } = initialWrite.descriptor;
99
108
 
100
- const indexes: { [key:string]: string | boolean | undefined } = {
109
+ // Mutable visibility facts come from the newest retained RecordsWrite that held them before deletion.
110
+ const { tags, published, datePublished } = visibilitySourceWrite.descriptor;
111
+
112
+ const indexes: { [key:string]: string | number | boolean | string[] | number[] | undefined } = {
101
113
  isLatestBaseState : true,
114
+ published : !!published,
115
+ datePublished,
102
116
  protocol, protocolPath, recipient, schema, parentId, dateCreated,
103
117
  contextId : initialWrite.contextId,
104
118
  author : this.author!,
@@ -106,14 +120,20 @@ export class RecordsDelete extends AbstractMessage<RecordsDeleteMessage> {
106
120
  };
107
121
  removeUndefinedProperties(indexes);
108
122
 
123
+ // tags are flattened into `tag.<property>` keys to avoid name clashes with first-class index
124
+ // keys, matching the flattening the RecordsWrite indexing path performs.
125
+ if (tags !== undefined) {
126
+ return { ...indexes, ...Records.buildTagIndexes({ ...tags }) } as KeyValues;
127
+ }
128
+
109
129
  return indexes as KeyValues;
110
130
  }
111
131
 
112
132
  /*
113
133
  * Authorizes the delegate who signed the message.
114
- * @param messageStore Used to check if the grant has been revoked.
134
+ * @param validationStateReader Used to check if the grant has been revoked.
115
135
  */
116
- public async authorizeDelegate(recordsWriteToDelete: RecordsWriteMessage, messageStore: MessageStore): Promise<void> {
136
+ public async authorizeDelegate(recordsWriteToDelete: RecordsWriteMessage, validationStateReader: ValidationStateReader): Promise<void> {
117
137
  const delegatedGrant = PermissionGrant.parse(this.message.authorization.authorDelegatedGrant!);
118
138
  await RecordsGrantAuthorization.authorizeDelete({
119
139
  recordsDeleteMessage : this.message,
@@ -121,7 +141,7 @@ export class RecordsDelete extends AbstractMessage<RecordsDeleteMessage> {
121
141
  expectedGrantor : this.author!,
122
142
  expectedGrantee : this.signer!,
123
143
  permissionGrant : delegatedGrant,
124
- messageStore
144
+ validationStateReader
125
145
  });
126
146
  }
127
147
  }
@@ -1,6 +1,6 @@
1
1
  import type { MessageSigner } from '../types/signer.js';
2
- import type { MessageStore } from '../types//message-store.js';
3
2
  import type { Pagination } from '../types/message-types.js';
3
+ import type { ValidationStateReader } from '../types/validation-state-reader.js';
4
4
  import type { DataEncodedRecordsWriteMessage, RecordsFilter, RecordsQueryDescriptor, RecordsQueryMessage } from '../types/records-types.js';
5
5
 
6
6
  import { AbstractMessage } from '../core/abstract-message.js';
@@ -52,6 +52,11 @@ export class RecordsQuery extends AbstractMessage<RecordsQueryMessage> {
52
52
  }
53
53
 
54
54
  await Records.validateDelegatedGrantReferentialIntegrity(message, signaturePayload);
55
+ Records.validateNestedProtocolPathQueryScope(
56
+ message.descriptor.filter,
57
+ DwnErrorCode.RecordsQueryNestedProtocolPathContextIdInvalid,
58
+ 'RecordsQuery'
59
+ );
55
60
 
56
61
  if (signaturePayload?.protocolRole !== undefined) {
57
62
  if (message.descriptor.filter.protocolPath === undefined) {
@@ -123,16 +128,16 @@ export class RecordsQuery extends AbstractMessage<RecordsQueryMessage> {
123
128
 
124
129
  /**
125
130
  * Authorizes the delegate who signed this message.
126
- * @param messageStore Used to check if the grant has been revoked.
131
+ * @param validationStateReader Used to check if the grant has been revoked.
127
132
  */
128
- public async authorizeDelegate(messageStore: MessageStore): Promise<void> {
133
+ public async authorizeDelegate(validationStateReader: ValidationStateReader): Promise<void> {
129
134
  const delegatedGrant = PermissionGrant.parse(this.message.authorization!.authorDelegatedGrant!);
130
135
  await RecordsGrantAuthorization.authorizeQueryOrSubscribe({
131
136
  incomingMessage : this.message,
132
137
  expectedGrantee : this.signer!,
133
138
  expectedGrantor : this.author!,
134
139
  permissionGrant : delegatedGrant,
135
- messageStore
140
+ validationStateReader
136
141
  });
137
142
  }
138
143
  }
@@ -1,5 +1,5 @@
1
1
  import type { MessageSigner } from '../types/signer.js';
2
- import type { MessageStore } from '../types//message-store.js';
2
+ import type { ValidationStateReader } from '../types/validation-state-reader.js';
3
3
  import type { DataEncodedRecordsWriteMessage, RecordsFilter , RecordsReadDescriptor, RecordsReadMessage, RecordsWriteMessage } from '../types/records-types.js';
4
4
 
5
5
  import { AbstractMessage } from '../core/abstract-message.js';
@@ -110,9 +110,9 @@ export class RecordsRead extends AbstractMessage<RecordsReadMessage> {
110
110
 
111
111
  /**
112
112
  * Authorizes the delegate who signed this message.
113
- * @param messageStore Used to check if the grant has been revoked.
113
+ * @param validationStateReader Used to check if the grant has been revoked.
114
114
  */
115
- public async authorizeDelegate(matchedRecordsWrite: RecordsWriteMessage, messageStore: MessageStore): Promise<void> {
115
+ public async authorizeDelegate(matchedRecordsWrite: RecordsWriteMessage, validationStateReader: ValidationStateReader): Promise<void> {
116
116
  const delegatedGrant = PermissionGrant.parse(this.message.authorization!.authorDelegatedGrant!);
117
117
  await RecordsGrantAuthorization.authorizeRead({
118
118
  recordsReadMessage : this.message,
@@ -120,7 +120,7 @@ export class RecordsRead extends AbstractMessage<RecordsReadMessage> {
120
120
  expectedGrantor : this.author!,
121
121
  expectedGrantee : this.signer!,
122
122
  permissionGrant : delegatedGrant,
123
- messageStore
123
+ validationStateReader
124
124
  });
125
125
  }
126
126
  }
@@ -1,7 +1,7 @@
1
1
  import type { MessageSigner } from '../types/signer.js';
2
- import type { MessageStore } from '../types/message-store.js';
3
2
  import type { Pagination } from '../types/message-types.js';
4
3
  import type { ProgressToken } from '../types/subscriptions.js';
4
+ import type { ValidationStateReader } from '../types/validation-state-reader.js';
5
5
  import type { DataEncodedRecordsWriteMessage, DateSort, RecordsFilter, RecordsSubscribeDescriptor, RecordsSubscribeMessage } from '../types/records-types.js';
6
6
 
7
7
  import { AbstractMessage } from '../core/abstract-message.js';
@@ -48,6 +48,11 @@ export class RecordsSubscribe extends AbstractMessage<RecordsSubscribeMessage> {
48
48
  }
49
49
 
50
50
  await Records.validateDelegatedGrantReferentialIntegrity(message, signaturePayload);
51
+ Records.validateNestedProtocolPathQueryScope(
52
+ message.descriptor.filter,
53
+ DwnErrorCode.RecordsSubscribeNestedProtocolPathContextIdInvalid,
54
+ 'RecordsSubscribe'
55
+ );
51
56
 
52
57
  if (signaturePayload?.protocolRole !== undefined) {
53
58
  if (message.descriptor.filter.protocolPath === undefined) {
@@ -109,16 +114,16 @@ export class RecordsSubscribe extends AbstractMessage<RecordsSubscribeMessage> {
109
114
 
110
115
  /**
111
116
  * Authorizes the delegate who signed the message.
112
- * @param messageStore Used to check if the grant has been revoked.
117
+ * @param validationStateReader Used to check if the grant has been revoked.
113
118
  */
114
- public async authorizeDelegate(messageStore: MessageStore): Promise<void> {
119
+ public async authorizeDelegate(validationStateReader: ValidationStateReader): Promise<void> {
115
120
  const delegatedGrant = PermissionGrant.parse(this.message.authorization!.authorDelegatedGrant!);
116
121
  await RecordsGrantAuthorization.authorizeQueryOrSubscribe({
117
122
  incomingMessage : this.message,
118
123
  expectedGrantor : this.author!,
119
124
  expectedGrantee : this.signer!,
120
125
  permissionGrant : delegatedGrant,
121
- messageStore
126
+ validationStateReader
122
127
  });
123
128
  }
124
129
  }
@@ -4,6 +4,7 @@ import type { MessageInterface } from '../types/message-interface.js';
4
4
  import type { MessageSigner } from '../types/signer.js';
5
5
  import type { MessageStore } from '../types/message-store.js';
6
6
  import type { PublicKeyJwk } from '../types/jose-types.js';
7
+ import type { ValidationStateReader } from '../types/validation-state-reader.js';
7
8
  import type {
8
9
  DataEncodedRecordsWriteMessage,
9
10
  InternalRecordsWriteMessage,
@@ -460,6 +461,35 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
460
461
  return recordsWrite;
461
462
  }
462
463
 
464
+ /**
465
+ * Validates the expected `dataCid` and `dataSize` in the descriptor against the actual data.
466
+ *
467
+ * @throws {DwnError} with `DwnErrorCode.RecordsWriteDataCidMismatch`
468
+ * if the actual data CID does not match `dataCid` in the descriptor.
469
+ * @throws {DwnError} with `DwnErrorCode.RecordsWriteDataSizeMismatch`
470
+ * if the actual byte size does not match `dataSize` in the descriptor.
471
+ */
472
+ public static validateDataIntegrity(
473
+ expectedDataCid: string,
474
+ expectedDataSize: number,
475
+ actualDataCid: string,
476
+ actualDataSize: number
477
+ ): void {
478
+ if (expectedDataCid !== actualDataCid) {
479
+ throw new DwnError(
480
+ DwnErrorCode.RecordsWriteDataCidMismatch,
481
+ `actual data CID ${actualDataCid} does not match dataCid in descriptor: ${expectedDataCid}`
482
+ );
483
+ }
484
+
485
+ if (expectedDataSize !== actualDataSize) {
486
+ throw new DwnError(
487
+ DwnErrorCode.RecordsWriteDataSizeMismatch,
488
+ `actual data size ${actualDataSize} bytes does not match dataSize in descriptor: ${expectedDataSize}`
489
+ );
490
+ }
491
+ }
492
+
463
493
  /**
464
494
  * Called by `JSON.stringify(...)` automatically.
465
495
  */
@@ -472,9 +502,7 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
472
502
  *
473
503
  * @param options.append - When `true`, appends new `recipients` entries to the existing
474
504
  * `encryption` property instead of replacing it. Requires `this._message.encryption` to
475
- * already exist (i.e., the record must already be encrypted). This is used for the reactive
476
- * root-record upgrade: adding a ProtocolContext recipient entry alongside an existing
477
- * ProtocolPath entry so both the owner and context key holders can decrypt.
505
+ * already exist (i.e., the record must already be encrypted).
478
506
  */
479
507
  public async encryptSymmetricEncryptionKey(
480
508
  encryptionInput: EncryptionInput,
@@ -693,10 +721,10 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
693
721
 
694
722
  // If `encryption` is given in message, make sure the correct `encryptionCid`
695
723
  // is in the payload of the message signature — UNLESS the message has an
696
- // ownerSignature. When the DWN owner appends recipients to an
697
- // externally-authored record (reactive root-record upgrade), the author's
698
- // encryptionCid becomes stale. The owner's signature vouches for the
699
- // updated encryption property, so the mismatch is expected and safe.
724
+ // ownerSignature. When the DWN owner appends recipients to an externally-authored
725
+ // record before normal admission, the author's encryptionCid becomes stale. The
726
+ // owner's signature vouches for the updated encryption property, so the mismatch
727
+ // is expected and safe.
700
728
  const hasOwnerSignature = this.message.authorization?.ownerSignature !== undefined;
701
729
  if (signaturePayload.encryptionCid !== undefined && !hasOwnerSignature) {
702
730
  const expectedEncryptionCid = await Cid.computeCid(this.message.encryption);
@@ -788,31 +816,31 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
788
816
 
789
817
  /**
790
818
  * Authorizes the author-delegate who signed this message.
791
- * @param messageStore Used to check if the grant has been revoked.
819
+ * @param validationStateReader Used to check if the grant has been revoked.
792
820
  */
793
- public async authorizeAuthorDelegate(messageStore: MessageStore): Promise<void> {
821
+ public async authorizeAuthorDelegate(validationStateReader: ValidationStateReader): Promise<void> {
794
822
  const delegatedGrant = PermissionGrant.parse(this.message.authorization.authorDelegatedGrant!);
795
823
  await RecordsGrantAuthorization.authorizeWrite({
796
824
  recordsWriteMessage : this.message,
797
825
  expectedGrantor : this.author!,
798
826
  expectedGrantee : this.signer!,
799
827
  permissionGrant : delegatedGrant,
800
- messageStore
828
+ validationStateReader
801
829
  });
802
830
  }
803
831
 
804
832
  /**
805
833
  * Authorizes the owner-delegate who signed this message.
806
- * @param messageStore Used to check if the grant has been revoked.
834
+ * @param validationStateReader Used to check if the grant has been revoked.
807
835
  */
808
- public async authorizeOwnerDelegate(messageStore: MessageStore): Promise<void> {
836
+ public async authorizeOwnerDelegate(validationStateReader: ValidationStateReader): Promise<void> {
809
837
  const delegatedGrant = PermissionGrant.parse(this.message.authorization.ownerDelegatedGrant!);
810
838
  await RecordsGrantAuthorization.authorizeWrite({
811
839
  recordsWriteMessage : this.message,
812
840
  expectedGrantor : this.owner!,
813
841
  expectedGrantee : this.ownerSignatureSigner!,
814
842
  permissionGrant : delegatedGrant,
815
- messageStore
843
+ validationStateReader
816
844
  });
817
845
  }
818
846
 
@@ -1,14 +1,14 @@
1
1
  import type { Filter } from '../types/query-types.js';
2
- import type { GenericMessage } from '../types/message-types.js';
3
2
  import type { MessagesFilter } from '../types/messages-types.js';
4
3
  import type { MessageSigner } from '../types/signer.js';
5
- import type { MessageStore } from '../types/message-store.js';
6
4
  import type { ProtocolDefinition } from '../types/protocols-types.js';
5
+ import type { ValidationStateReader } from '../types/validation-state-reader.js';
7
6
  import type { CoreProtocol, CoreProtocolStores } from '../core/core-protocol.js';
8
7
  import type { DataEncodedRecordsWriteMessage, RecordsWriteMessage } from '../types/records-types.js';
9
8
  import type { PermissionConditions, PermissionGrantData, PermissionRequestData, PermissionRevocationData, PermissionScope, RecordsPermissionScope } from '../types/permission-types.js';
10
9
 
11
10
  import { DwnConstant } from '../core/dwn-constant.js';
11
+ import { DwnMethodName } from '../enums/dwn-interface-method.js';
12
12
  import { Encoder } from '../utils/encoder.js';
13
13
  import { FilterUtility } from '../utils/filter.js';
14
14
  import { Message } from '../core/message.js';
@@ -20,7 +20,6 @@ import { RecordsWrite } from '../interfaces/records-write.js';
20
20
  import { Time } from '../utils/time.js';
21
21
  import { validateJsonSchema } from '../schema-validator.js';
22
22
  import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
23
- import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
24
23
  import { normalizeProtocolUrl, validateProtocolUrlNormalized } from '../utils/url.js';
25
24
 
26
25
  /**
@@ -113,6 +112,17 @@ export class PermissionsProtocol implements CoreProtocol {
113
112
  */
114
113
  public static readonly revocationPath = 'grant/revocation';
115
114
 
115
+ /**
116
+ * Canonical store predicate for the latest revocation of a permission grant.
117
+ */
118
+ public static grantRevocationFilter(grantId: string): Filter {
119
+ return {
120
+ isLatestBaseState : true,
121
+ parentId : grantId,
122
+ protocolPath : PermissionsProtocol.revocationPath,
123
+ };
124
+ }
125
+
116
126
  /**
117
127
  * The definition of the Permissions protocol.
118
128
  */
@@ -131,8 +141,15 @@ export class PermissionsProtocol implements CoreProtocol {
131
141
  }
132
142
  },
133
143
  structure: {
144
+ // All permission record paths are `$immutable`: requests, grants, and revocations are
145
+ // write-once by design (a grant is never amended — it is revoked and re-issued).
146
+ // Immutability locks each record's initial-write facts (notably the `protocol` tag),
147
+ // which replication fingerprint domains and protocol-scoped shadow filters depend on —
148
+ // a tag-mutated permission record would otherwise drift between the shadow-filter
149
+ // stream (current tags) and its fingerprint domain (initial tags).
134
150
  request: {
135
- $size: {
151
+ $immutable : true,
152
+ $size : {
136
153
  max: 10000
137
154
  },
138
155
  $actions: [
@@ -143,7 +160,8 @@ export class PermissionsProtocol implements CoreProtocol {
143
160
  ]
144
161
  },
145
162
  grant: {
146
- $size: {
163
+ $immutable : true,
164
+ $size : {
147
165
  max: 10000
148
166
  },
149
167
  $actions: [
@@ -154,7 +172,8 @@ export class PermissionsProtocol implements CoreProtocol {
154
172
  }
155
173
  ],
156
174
  revocation: {
157
- $size: {
175
+ $immutable : true,
176
+ $size : {
158
177
  max: 10000
159
178
  },
160
179
  $actions: [
@@ -194,7 +213,7 @@ export class PermissionsProtocol implements CoreProtocol {
194
213
  public async preProcessWrite(
195
214
  tenant: string,
196
215
  message: RecordsWriteMessage,
197
- messageStore: MessageStore,
216
+ validationStateReader: ValidationStateReader,
198
217
  ): Promise<void> {
199
218
  if (message.descriptor.protocolPath !== PermissionsProtocol.revocationPath) {
200
219
  return;
@@ -202,7 +221,7 @@ export class PermissionsProtocol implements CoreProtocol {
202
221
 
203
222
  // fetch the parent grant to compare the scoped protocol against the revocation tag
204
223
  const permissionGrantId = message.descriptor.parentId!;
205
- const grant = await PermissionsProtocol.fetchGrant(tenant, messageStore, permissionGrantId);
224
+ const grant = await validationStateReader.fetchGrant(tenant, permissionGrantId);
206
225
 
207
226
  const revokeTagProtocol = message.descriptor.tags?.protocol;
208
227
  const grantProtocol = 'protocol' in grant.scope ? grant.scope.protocol : undefined;
@@ -221,8 +240,7 @@ export class PermissionsProtocol implements CoreProtocol {
221
240
  *
222
241
  * Deletion order is deliberate to avoid orphaned data in case of crash:
223
242
  * 1. data store (large blobs first)
224
- * 2. state index (SMT entries)
225
- * 3. message store
243
+ * 2. message store
226
244
  */
227
245
  public async postProcessWrite(
228
246
  tenant: string,
@@ -255,11 +273,9 @@ export class PermissionsProtocol implements CoreProtocol {
255
273
  }
256
274
  }
257
275
 
258
- // 2. Compute CIDs and delete from state index before message store to avoid orphaned state entries.
259
276
  const messageCids = await Promise.all(grantAuthorizedMessages.map((message): Promise<string> => Message.getCid(message)));
260
- await stores.stateIndex.delete(tenant, messageCids);
261
277
 
262
- // 3. Finally delete all messages from the message store.
278
+ // 2. Finally delete all messages from the message store.
263
279
  await Promise.all(messageCids.map((cid): Promise<void> => stores.messageStore.delete(tenant, cid)));
264
280
  }
265
281
 
@@ -530,51 +546,15 @@ export class PermissionsProtocol implements CoreProtocol {
530
546
 
531
547
 
532
548
 
533
- /**
534
- * Fetches PermissionGrant with the specified `recordID`.
535
- * @returns the PermissionGrant matching the `recordId` specified.
536
- * @throws {Error} if PermissionGrant does not exist
537
- */
538
- public static async fetchGrant(
539
- tenant: string,
540
- messageStore: MessageStore,
541
- permissionGrantId: string,
542
- ): Promise<PermissionGrant> {
543
-
544
- const grantQuery = {
545
- recordId : permissionGrantId,
546
- isLatestBaseState : true
547
- };
548
- const { messages } = await messageStore.query(tenant, [grantQuery]);
549
- const possibleGrantMessage: GenericMessage | undefined = messages[0];
550
-
551
- const dwnInterface = possibleGrantMessage?.descriptor.interface;
552
- const dwnMethod = possibleGrantMessage?.descriptor.method;
553
-
554
- if (dwnInterface !== DwnInterfaceName.Records ||
555
- dwnMethod !== DwnMethodName.Write ||
556
- (possibleGrantMessage as RecordsWriteMessage).descriptor.protocolPath !== PermissionsProtocol.grantPath) {
557
- throw new DwnError(
558
- DwnErrorCode.GrantAuthorizationGrantMissing,
559
- `Could not find permission grant with record ID ${permissionGrantId}.`
560
- );
561
- }
562
-
563
- const permissionGrantMessage = possibleGrantMessage as DataEncodedRecordsWriteMessage;
564
- const permissionGrant = PermissionGrant.parse(permissionGrantMessage);
565
-
566
- return permissionGrant;
567
- }
568
-
569
549
  /**
570
550
  * Gets the scope from the given permission record.
571
551
  * If the record is a revocation, the scope is fetched from the grant that is being revoked.
572
552
  *
573
- * @param messageStore The message store to fetch the grant for a revocation.
553
+ * @param validationStateReader Used to fetch the grant for a revocation.
574
554
  */
575
555
  public static async getScopeFromPermissionRecord(
576
556
  tenant: string,
577
- messageStore:MessageStore,
557
+ validationStateReader: ValidationStateReader,
578
558
  incomingMessage: DataEncodedRecordsWriteMessage,
579
559
  ): Promise<PermissionScope> {
580
560
  if (incomingMessage.descriptor.protocol !== PermissionsProtocol.uri) {
@@ -585,7 +565,7 @@ export class PermissionsProtocol implements CoreProtocol {
585
565
  }
586
566
 
587
567
  if (incomingMessage.descriptor.protocolPath === PermissionsProtocol.revocationPath) {
588
- const grant = await PermissionsProtocol.fetchGrant(tenant, messageStore, incomingMessage.descriptor.parentId!);
568
+ const grant = await validationStateReader.fetchGrant(tenant, incomingMessage.descriptor.parentId!);
589
569
  return grant.scope;
590
570
  } else if (incomingMessage.descriptor.protocolPath === PermissionsProtocol.grantPath) {
591
571
  const grant = PermissionGrant.parse(incomingMessage);
@@ -55,7 +55,7 @@ export class IndexLevel {
55
55
  config: IndexLevelConfig;
56
56
  private readonly _compoundIndexes: CompoundIndexDefinition[];
57
57
 
58
- constructor(config: IndexLevelConfig) {
58
+ constructor(config: IndexLevelConfig, db?: LevelWrapper<string>) {
59
59
  this.config = {
60
60
  createLevelDatabase,
61
61
  ...config,
@@ -63,7 +63,7 @@ export class IndexLevel {
63
63
 
64
64
  this._compoundIndexes = config.compoundIndexes ?? [];
65
65
 
66
- this.db = new LevelWrapper<string>({
66
+ this.db = db ?? new LevelWrapper<string>({
67
67
  location : this.config.location,
68
68
  createLevelDatabase : this.config.createLevelDatabase,
69
69
  keyEncoding : 'utf8'
@@ -99,7 +99,19 @@ export class IndexLevel {
99
99
  indexes: KeyValues,
100
100
  options?: IndexLevelOptions
101
101
  ): Promise<void> {
102
+ const indexOps = await this.createPutOperations(tenant, messageCid, indexes);
103
+ const tenantPartition = await this.db.partition(tenant);
104
+ await tenantPartition.batch(indexOps, options);
105
+ }
102
106
 
107
+ /**
108
+ * Creates the batch operations for indexing an item without executing them.
109
+ */
110
+ async createPutOperations(
111
+ tenant: string,
112
+ messageCid: string,
113
+ indexes: KeyValues,
114
+ ): Promise<LevelWrapperBatchOperation<string>[]> {
103
115
  // ensure we have something valid to index
104
116
  if (isEmptyObject(indexes)) {
105
117
  throw new DwnError(DwnErrorCode.IndexMissingIndexableProperty, 'Index must include at least one valid indexable property');
@@ -140,21 +152,32 @@ export class IndexLevel {
140
152
  );
141
153
  opCreationPromises.push(partitionOperationPromise);
142
154
 
143
- const indexOps = await Promise.all(opCreationPromises);
144
- const tenantPartition = await this.db.partition(tenant);
145
- await tenantPartition.batch(indexOps, options);
155
+ return Promise.all(opCreationPromises);
146
156
  }
147
157
 
148
158
  /**
149
159
  * Deletes all of the index data associated with the item.
150
160
  */
151
161
  async delete(tenant: string, messageCid: string, options?: IndexLevelOptions): Promise<void> {
162
+ const indexOps = await this.createDeleteOperations(tenant, messageCid);
163
+ if (indexOps.length === 0) {
164
+ return;
165
+ }
166
+
167
+ const tenantPartition = await this.db.partition(tenant);
168
+ await tenantPartition.batch(indexOps, options);
169
+ }
170
+
171
+ /**
172
+ * Creates the batch operations for removing an item's index data without executing them.
173
+ */
174
+ async createDeleteOperations(tenant: string, messageCid: string): Promise<LevelWrapperBatchOperation<string>[]> {
152
175
  const opCreationPromises: Promise<LevelWrapperBatchOperation<string>>[] = [];
153
176
 
154
177
  const indexes = await this.getIndexes(tenant, messageCid);
155
178
  if (indexes === undefined) {
156
179
  // invalid messageCid
157
- return;
180
+ return [];
158
181
  }
159
182
 
160
183
  // delete the reverse lookup
@@ -185,9 +208,7 @@ export class IndexLevel {
185
208
  }
186
209
  }
187
210
 
188
- const indexOps = await Promise.all(opCreationPromises);
189
- const tenantPartition = await this.db.partition(tenant);
190
- await tenantPartition.batch(indexOps, options);
211
+ return Promise.all(opCreationPromises);
191
212
  }
192
213
 
193
214
  /**
@@ -215,6 +215,14 @@ export class LevelWrapper<V> {
215
215
  }) };
216
216
  }
217
217
 
218
+ /**
219
+ * Wraps the given operation as targeting this wrapper's own partition, so it
220
+ * can be executed in a batch on an ancestor database.
221
+ */
222
+ createOperation(operation: LevelWrapperBatchOperation<V>): LevelWrapperBatchOperation<V> {
223
+ return { ...operation, sublevel: this.db as any };
224
+ }
225
+
218
226
  private async compactUnderlyingStorage(options?: LevelWrapperOptions): Promise<void> {
219
227
  options?.signal?.throwIfAborted();
220
228
 
@@ -269,4 +277,4 @@ export class LevelWrapper<V> {
269
277
  export type LevelWrapperConfig<V> = CreateLevelDatabaseOptions<V> & {
270
278
  location: string,
271
279
  createLevelDatabase?: typeof createLevelDatabase,
272
- };
280
+ };