@enbox/dwn-sdk-js 0.0.6 → 0.0.8

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 (527) hide show
  1. package/dist/browser.mjs +8 -8
  2. package/dist/browser.mjs.map +4 -4
  3. package/dist/esm/generated/precompiled-validators.js +762 -911
  4. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  5. package/dist/esm/src/core/abstract-message.js +4 -0
  6. package/dist/esm/src/core/abstract-message.js.map +1 -1
  7. package/dist/esm/src/core/auth.js +22 -33
  8. package/dist/esm/src/core/auth.js.map +1 -1
  9. package/dist/esm/src/core/constants.js +11 -0
  10. package/dist/esm/src/core/constants.js.map +1 -0
  11. package/dist/esm/src/core/core-protocol.js +44 -0
  12. package/dist/esm/src/core/core-protocol.js.map +1 -0
  13. package/dist/esm/src/core/dwn-constant.js +7 -7
  14. package/dist/esm/src/core/dwn-constant.js.map +1 -1
  15. package/dist/esm/src/core/dwn-error.js +10 -12
  16. package/dist/esm/src/core/dwn-error.js.map +1 -1
  17. package/dist/esm/src/core/grant-authorization.js +50 -52
  18. package/dist/esm/src/core/grant-authorization.js.map +1 -1
  19. package/dist/esm/src/core/message.js +85 -116
  20. package/dist/esm/src/core/message.js.map +1 -1
  21. package/dist/esm/src/core/messages-grant-authorization.js +63 -78
  22. package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
  23. package/dist/esm/src/core/protocol-authorization-action.js +266 -0
  24. package/dist/esm/src/core/protocol-authorization-action.js.map +1 -0
  25. package/dist/esm/src/core/protocol-authorization-validation.js +321 -0
  26. package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -0
  27. package/dist/esm/src/core/protocol-authorization.js +144 -741
  28. package/dist/esm/src/core/protocol-authorization.js.map +1 -1
  29. package/dist/esm/src/core/protocols-grant-authorization.js +24 -38
  30. package/dist/esm/src/core/protocols-grant-authorization.js.map +1 -1
  31. package/dist/esm/src/core/record-chain.js +64 -0
  32. package/dist/esm/src/core/record-chain.js.map +1 -0
  33. package/dist/esm/src/core/records-grant-authorization.js +53 -72
  34. package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
  35. package/dist/esm/src/core/resumable-task-manager.js +50 -65
  36. package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
  37. package/dist/esm/src/core/tenant-gate.js +2 -13
  38. package/dist/esm/src/core/tenant-gate.js.map +1 -1
  39. package/dist/esm/src/dwn.js +108 -101
  40. package/dist/esm/src/dwn.js.map +1 -1
  41. package/dist/esm/src/event-stream/event-emitter-event-log.js +204 -0
  42. package/dist/esm/src/event-stream/event-emitter-event-log.js.map +1 -0
  43. package/dist/esm/src/handlers/messages-read.js +67 -81
  44. package/dist/esm/src/handlers/messages-read.js.map +1 -1
  45. package/dist/esm/src/handlers/messages-subscribe.js +51 -63
  46. package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
  47. package/dist/esm/src/handlers/messages-sync.js +75 -89
  48. package/dist/esm/src/handlers/messages-sync.js.map +1 -1
  49. package/dist/esm/src/handlers/protocols-configure.js +153 -163
  50. package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
  51. package/dist/esm/src/handlers/protocols-query.js +52 -55
  52. package/dist/esm/src/handlers/protocols-query.js.map +1 -1
  53. package/dist/esm/src/handlers/records-count.js +97 -85
  54. package/dist/esm/src/handlers/records-count.js.map +1 -1
  55. package/dist/esm/src/handlers/records-delete.js +75 -93
  56. package/dist/esm/src/handlers/records-delete.js.map +1 -1
  57. package/dist/esm/src/handlers/records-query.js +116 -105
  58. package/dist/esm/src/handlers/records-query.js.map +1 -1
  59. package/dist/esm/src/handlers/records-read.js +130 -132
  60. package/dist/esm/src/handlers/records-read.js.map +1 -1
  61. package/dist/esm/src/handlers/records-subscribe.js +164 -104
  62. package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
  63. package/dist/esm/src/handlers/records-write.js +213 -280
  64. package/dist/esm/src/handlers/records-write.js.map +1 -1
  65. package/dist/esm/src/index.js +5 -2
  66. package/dist/esm/src/index.js.map +1 -1
  67. package/dist/esm/src/interfaces/messages-read.js +24 -32
  68. package/dist/esm/src/interfaces/messages-read.js.map +1 -1
  69. package/dist/esm/src/interfaces/messages-subscribe.js +28 -41
  70. package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
  71. package/dist/esm/src/interfaces/messages-sync.js +26 -40
  72. package/dist/esm/src/interfaces/messages-sync.js.map +1 -1
  73. package/dist/esm/src/interfaces/protocols-configure.js +87 -65
  74. package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
  75. package/dist/esm/src/interfaces/protocols-query.js +55 -68
  76. package/dist/esm/src/interfaces/protocols-query.js.map +1 -1
  77. package/dist/esm/src/interfaces/records-count.js +50 -66
  78. package/dist/esm/src/interfaces/records-count.js.map +1 -1
  79. package/dist/esm/src/interfaces/records-delete.js +45 -55
  80. package/dist/esm/src/interfaces/records-delete.js.map +1 -1
  81. package/dist/esm/src/interfaces/records-query.js +60 -76
  82. package/dist/esm/src/interfaces/records-query.js.map +1 -1
  83. package/dist/esm/src/interfaces/records-read.js +51 -67
  84. package/dist/esm/src/interfaces/records-read.js.map +1 -1
  85. package/dist/esm/src/interfaces/records-subscribe.js +53 -68
  86. package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
  87. package/dist/esm/src/interfaces/records-write-query.js +102 -0
  88. package/dist/esm/src/interfaces/records-write-query.js.map +1 -0
  89. package/dist/esm/src/interfaces/records-write-signing.js +81 -0
  90. package/dist/esm/src/interfaces/records-write-signing.js.map +1 -0
  91. package/dist/esm/src/interfaces/records-write.js +396 -610
  92. package/dist/esm/src/interfaces/records-write.js.map +1 -1
  93. package/dist/esm/src/jose/algorithms/signing/ed25519.js +10 -19
  94. package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -1
  95. package/dist/esm/src/jose/jws/general/builder.js +23 -35
  96. package/dist/esm/src/jose/jws/general/builder.js.map +1 -1
  97. package/dist/esm/src/jose/jws/general/verifier.js +56 -69
  98. package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
  99. package/dist/esm/src/protocols/permission-grant.js +43 -14
  100. package/dist/esm/src/protocols/permission-grant.js.map +1 -1
  101. package/dist/esm/src/protocols/permission-request.js +28 -14
  102. package/dist/esm/src/protocols/permission-request.js.map +1 -1
  103. package/dist/esm/src/protocols/permissions.js +325 -227
  104. package/dist/esm/src/protocols/permissions.js.map +1 -1
  105. package/dist/esm/src/smt/smt-store-level.js +42 -64
  106. package/dist/esm/src/smt/smt-store-level.js.map +1 -1
  107. package/dist/esm/src/smt/smt-store-memory.js +19 -45
  108. package/dist/esm/src/smt/smt-store-memory.js.map +1 -1
  109. package/dist/esm/src/smt/smt-utils.js +28 -45
  110. package/dist/esm/src/smt/smt-utils.js.map +1 -1
  111. package/dist/esm/src/smt/sparse-merkle-tree.js +426 -471
  112. package/dist/esm/src/smt/sparse-merkle-tree.js.map +1 -1
  113. package/dist/esm/src/state-index/state-index-level.js +113 -150
  114. package/dist/esm/src/state-index/state-index-level.js.map +1 -1
  115. package/dist/esm/src/store/blockstore-level.js +54 -156
  116. package/dist/esm/src/store/blockstore-level.js.map +1 -1
  117. package/dist/esm/src/store/blockstore-mock.js +48 -153
  118. package/dist/esm/src/store/blockstore-mock.js.map +1 -1
  119. package/dist/esm/src/store/data-store-level.js +137 -100
  120. package/dist/esm/src/store/data-store-level.js.map +1 -1
  121. package/dist/esm/src/store/index-level-compound.js +246 -0
  122. package/dist/esm/src/store/index-level-compound.js.map +1 -0
  123. package/dist/esm/src/store/index-level.js +307 -715
  124. package/dist/esm/src/store/index-level.js.map +1 -1
  125. package/dist/esm/src/store/level-wrapper.js +143 -244
  126. package/dist/esm/src/store/level-wrapper.js.map +1 -1
  127. package/dist/esm/src/store/message-store-level.js +71 -94
  128. package/dist/esm/src/store/message-store-level.js.map +1 -1
  129. package/dist/esm/src/store/resumable-task-store-level.js +62 -101
  130. package/dist/esm/src/store/resumable-task-store-level.js.map +1 -1
  131. package/dist/esm/src/store/storage-controller.js +131 -146
  132. package/dist/esm/src/store/storage-controller.js.map +1 -1
  133. package/dist/esm/src/types/permission-types.js.map +1 -1
  134. package/dist/esm/src/types/protocols-types.js +10 -0
  135. package/dist/esm/src/types/protocols-types.js.map +1 -1
  136. package/dist/esm/src/types/records-types.js.map +1 -1
  137. package/dist/esm/src/utils/abort.js +8 -19
  138. package/dist/esm/src/utils/abort.js.map +1 -1
  139. package/dist/esm/src/utils/array.js +15 -49
  140. package/dist/esm/src/utils/array.js.map +1 -1
  141. package/dist/esm/src/utils/cid.js +29 -77
  142. package/dist/esm/src/utils/cid.js.map +1 -1
  143. package/dist/esm/src/utils/data-stream.js +37 -65
  144. package/dist/esm/src/utils/data-stream.js.map +1 -1
  145. package/dist/esm/src/utils/encryption.js +136 -162
  146. package/dist/esm/src/utils/encryption.js.map +1 -1
  147. package/dist/esm/src/utils/filter.js +1 -12
  148. package/dist/esm/src/utils/filter.js.map +1 -1
  149. package/dist/esm/src/utils/hd-key.js +45 -71
  150. package/dist/esm/src/utils/hd-key.js.map +1 -1
  151. package/dist/esm/src/utils/jws.js +9 -20
  152. package/dist/esm/src/utils/jws.js.map +1 -1
  153. package/dist/esm/src/utils/memory-cache.js +12 -23
  154. package/dist/esm/src/utils/memory-cache.js.map +1 -1
  155. package/dist/esm/src/utils/messages.js +21 -33
  156. package/dist/esm/src/utils/messages.js.map +1 -1
  157. package/dist/esm/src/utils/private-key-signer.js +9 -17
  158. package/dist/esm/src/utils/private-key-signer.js.map +1 -1
  159. package/dist/esm/src/utils/protocols.js +62 -70
  160. package/dist/esm/src/utils/protocols.js.map +1 -1
  161. package/dist/esm/src/utils/records.js +103 -166
  162. package/dist/esm/src/utils/records.js.map +1 -1
  163. package/dist/esm/src/utils/secp256k1.js +60 -96
  164. package/dist/esm/src/utils/secp256k1.js.map +1 -1
  165. package/dist/esm/src/utils/secp256r1.js +54 -71
  166. package/dist/esm/src/utils/secp256r1.js.map +1 -1
  167. package/dist/esm/src/utils/time.js +5 -18
  168. package/dist/esm/src/utils/time.js.map +1 -1
  169. package/dist/esm/src/utils/url.js +3 -3
  170. package/dist/esm/src/utils/url.js.map +1 -1
  171. package/dist/esm/tests/core/auth.spec.js +3 -12
  172. package/dist/esm/tests/core/auth.spec.js.map +1 -1
  173. package/dist/esm/tests/core/message.spec.js +50 -59
  174. package/dist/esm/tests/core/message.spec.js.map +1 -1
  175. package/dist/esm/tests/core/protocol-authorization.spec.js +10 -18
  176. package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
  177. package/dist/esm/tests/dwn.spec.js +65 -89
  178. package/dist/esm/tests/dwn.spec.js.map +1 -1
  179. package/dist/esm/tests/event-emitter-event-log.spec.js +305 -0
  180. package/dist/esm/tests/event-emitter-event-log.spec.js.map +1 -0
  181. package/dist/esm/tests/features/author-delegated-grant.spec.js +337 -347
  182. package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
  183. package/dist/esm/tests/features/owner-delegated-grant.spec.js +160 -172
  184. package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
  185. package/dist/esm/tests/features/owner-signature.spec.js +78 -82
  186. package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
  187. package/dist/esm/tests/features/permissions.spec.js +449 -184
  188. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  189. package/dist/esm/tests/features/protocol-composition.spec.js +981 -360
  190. package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
  191. package/dist/esm/tests/features/protocol-create-action.spec.js +45 -54
  192. package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
  193. package/dist/esm/tests/features/protocol-delete-action.spec.js +99 -108
  194. package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
  195. package/dist/esm/tests/features/protocol-update-action.spec.js +108 -117
  196. package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
  197. package/dist/esm/tests/features/records-immutable.spec.js +315 -0
  198. package/dist/esm/tests/features/records-immutable.spec.js.map +1 -0
  199. package/dist/esm/tests/features/records-prune.spec.js +178 -194
  200. package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
  201. package/dist/esm/tests/features/records-record-limit.spec.js +542 -0
  202. package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -0
  203. package/dist/esm/tests/features/records-tags.spec.js +456 -463
  204. package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
  205. package/dist/esm/tests/features/resumable-tasks.spec.js +88 -98
  206. package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
  207. package/dist/esm/tests/handlers/messages-read.spec.js +215 -210
  208. package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
  209. package/dist/esm/tests/handlers/messages-subscribe.spec.js +309 -171
  210. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  211. package/dist/esm/tests/handlers/messages-sync.spec.js +272 -199
  212. package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
  213. package/dist/esm/tests/handlers/protocols-configure.spec.js +247 -241
  214. package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
  215. package/dist/esm/tests/handlers/protocols-query.spec.js +159 -172
  216. package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
  217. package/dist/esm/tests/handlers/records-count.spec.js +101 -105
  218. package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
  219. package/dist/esm/tests/handlers/records-delete.spec.js +266 -279
  220. package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
  221. package/dist/esm/tests/handlers/records-query.spec.js +984 -996
  222. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  223. package/dist/esm/tests/handlers/records-read.spec.js +542 -671
  224. package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
  225. package/dist/esm/tests/handlers/records-subscribe.spec.js +433 -302
  226. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  227. package/dist/esm/tests/handlers/records-write.spec.js +1216 -1140
  228. package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
  229. package/dist/esm/tests/interfaces/messages-get.spec.js +39 -48
  230. package/dist/esm/tests/interfaces/messages-get.spec.js.map +1 -1
  231. package/dist/esm/tests/interfaces/messages-subscribe.spec.js +4 -13
  232. package/dist/esm/tests/interfaces/messages-subscribe.spec.js.map +1 -1
  233. package/dist/esm/tests/interfaces/protocols-configure.spec.js +212 -88
  234. package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
  235. package/dist/esm/tests/interfaces/protocols-query.spec.js +8 -17
  236. package/dist/esm/tests/interfaces/protocols-query.spec.js.map +1 -1
  237. package/dist/esm/tests/interfaces/records-delete.spec.js +8 -17
  238. package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -1
  239. package/dist/esm/tests/interfaces/records-query.spec.js +20 -29
  240. package/dist/esm/tests/interfaces/records-query.spec.js.map +1 -1
  241. package/dist/esm/tests/interfaces/records-read.spec.js +42 -51
  242. package/dist/esm/tests/interfaces/records-read.spec.js.map +1 -1
  243. package/dist/esm/tests/interfaces/records-subscribe.spec.js +16 -25
  244. package/dist/esm/tests/interfaces/records-subscribe.spec.js.map +1 -1
  245. package/dist/esm/tests/interfaces/records-write.spec.js +190 -219
  246. package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
  247. package/dist/esm/tests/jose/jws/general.spec.js +36 -45
  248. package/dist/esm/tests/jose/jws/general.spec.js.map +1 -1
  249. package/dist/esm/tests/protocols/permission-grant.spec.js +44 -50
  250. package/dist/esm/tests/protocols/permission-grant.spec.js.map +1 -1
  251. package/dist/esm/tests/protocols/permission-request.spec.js +23 -32
  252. package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
  253. package/dist/esm/tests/protocols/permissions.spec.js +49 -55
  254. package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
  255. package/dist/esm/tests/scenarios/aggregator.spec.js +127 -138
  256. package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
  257. package/dist/esm/tests/scenarios/deleted-record.spec.js +372 -36
  258. package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
  259. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +55 -64
  260. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
  261. package/dist/esm/tests/scenarios/nested-roles.spec.js +66 -76
  262. package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
  263. package/dist/esm/tests/scenarios/subscriptions.spec.js +451 -354
  264. package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
  265. package/dist/esm/tests/smt/smt-store-level.spec.js +76 -87
  266. package/dist/esm/tests/smt/smt-store-level.spec.js.map +1 -1
  267. package/dist/esm/tests/smt/sparse-merkle-tree.spec.js +344 -353
  268. package/dist/esm/tests/smt/sparse-merkle-tree.spec.js.map +1 -1
  269. package/dist/esm/tests/state-index/state-index-level.spec.js +117 -126
  270. package/dist/esm/tests/state-index/state-index-level.spec.js.map +1 -1
  271. package/dist/esm/tests/store/blockstore-level.spec.js +44 -99
  272. package/dist/esm/tests/store/blockstore-level.spec.js.map +1 -1
  273. package/dist/esm/tests/store/blockstore-mock.spec.js +40 -120
  274. package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
  275. package/dist/esm/tests/store/data-store-level.spec.js +160 -108
  276. package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
  277. package/dist/esm/tests/store/index-level.spec.js +404 -414
  278. package/dist/esm/tests/store/index-level.spec.js.map +1 -1
  279. package/dist/esm/tests/store/message-store-level.spec.js +13 -22
  280. package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
  281. package/dist/esm/tests/store/message-store.spec.js +229 -238
  282. package/dist/esm/tests/store/message-store.spec.js.map +1 -1
  283. package/dist/esm/tests/test-event-stream.js +12 -13
  284. package/dist/esm/tests/test-event-stream.js.map +1 -1
  285. package/dist/esm/tests/test-stores.js +16 -13
  286. package/dist/esm/tests/test-stores.js.map +1 -1
  287. package/dist/esm/tests/test-suite.js +8 -15
  288. package/dist/esm/tests/test-suite.js.map +1 -1
  289. package/dist/esm/tests/utils/cid.spec.js +24 -33
  290. package/dist/esm/tests/utils/cid.spec.js.map +1 -1
  291. package/dist/esm/tests/utils/data-stream.spec.js +48 -57
  292. package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
  293. package/dist/esm/tests/utils/encryption-callbacks.spec.js +45 -54
  294. package/dist/esm/tests/utils/encryption-callbacks.spec.js.map +1 -1
  295. package/dist/esm/tests/utils/encryption.spec.js +229 -82
  296. package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
  297. package/dist/esm/tests/utils/filters.spec.js +46 -55
  298. package/dist/esm/tests/utils/filters.spec.js.map +1 -1
  299. package/dist/esm/tests/utils/hd-key.spec.js +10 -19
  300. package/dist/esm/tests/utils/hd-key.spec.js.map +1 -1
  301. package/dist/esm/tests/utils/jws.spec.js +3 -12
  302. package/dist/esm/tests/utils/jws.spec.js.map +1 -1
  303. package/dist/esm/tests/utils/memory-cache.spec.js +9 -18
  304. package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -1
  305. package/dist/esm/tests/utils/messages.spec.js +18 -20
  306. package/dist/esm/tests/utils/messages.spec.js.map +1 -1
  307. package/dist/esm/tests/utils/poller.js +22 -33
  308. package/dist/esm/tests/utils/poller.js.map +1 -1
  309. package/dist/esm/tests/utils/private-key-signer.spec.js +15 -24
  310. package/dist/esm/tests/utils/private-key-signer.spec.js.map +1 -1
  311. package/dist/esm/tests/utils/records.spec.js +14 -27
  312. package/dist/esm/tests/utils/records.spec.js.map +1 -1
  313. package/dist/esm/tests/utils/secp256k1.spec.js +16 -25
  314. package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -1
  315. package/dist/esm/tests/utils/secp256r1.spec.js +18 -27
  316. package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
  317. package/dist/esm/tests/utils/test-data-generator.js +446 -467
  318. package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
  319. package/dist/esm/tests/validation/json-schemas/definitions.spec.js +2 -11
  320. package/dist/esm/tests/validation/json-schemas/definitions.spec.js.map +1 -1
  321. package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js +4 -13
  322. package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js.map +1 -1
  323. package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js +8 -17
  324. package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js.map +1 -1
  325. package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js +3 -12
  326. package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js.map +1 -1
  327. package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +4 -13
  328. package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -1
  329. package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js +2 -11
  330. package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js.map +1 -1
  331. package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js +2 -11
  332. package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js.map +1 -1
  333. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +44 -24
  334. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
  335. package/dist/types/generated/precompiled-validators.d.ts +49 -40
  336. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  337. package/dist/types/src/core/constants.d.ts +11 -0
  338. package/dist/types/src/core/constants.d.ts.map +1 -0
  339. package/dist/types/src/core/core-protocol.d.ts +89 -0
  340. package/dist/types/src/core/core-protocol.d.ts.map +1 -0
  341. package/dist/types/src/core/dwn-error.d.ts +9 -12
  342. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  343. package/dist/types/src/core/grant-authorization.d.ts +6 -2
  344. package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
  345. package/dist/types/src/core/protocol-authorization-action.d.ts +42 -0
  346. package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -0
  347. package/dist/types/src/core/protocol-authorization-validation.d.ts +81 -0
  348. package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -0
  349. package/dist/types/src/core/protocol-authorization.d.ts +24 -106
  350. package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
  351. package/dist/types/src/core/record-chain.d.ts +24 -0
  352. package/dist/types/src/core/record-chain.d.ts.map +1 -0
  353. package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
  354. package/dist/types/src/dwn.d.ts +19 -7
  355. package/dist/types/src/dwn.d.ts.map +1 -1
  356. package/dist/types/src/event-stream/event-emitter-event-log.d.ts +50 -0
  357. package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +1 -0
  358. package/dist/types/src/handlers/messages-read.d.ts +3 -8
  359. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  360. package/dist/types/src/handlers/messages-subscribe.d.ts +6 -10
  361. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  362. package/dist/types/src/handlers/messages-sync.d.ts +3 -8
  363. package/dist/types/src/handlers/messages-sync.d.ts.map +1 -1
  364. package/dist/types/src/handlers/protocols-configure.d.ts +3 -10
  365. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  366. package/dist/types/src/handlers/protocols-query.d.ts +3 -8
  367. package/dist/types/src/handlers/protocols-query.d.ts.map +1 -1
  368. package/dist/types/src/handlers/records-count.d.ts +3 -6
  369. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  370. package/dist/types/src/handlers/records-delete.d.ts +3 -8
  371. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  372. package/dist/types/src/handlers/records-query.d.ts +3 -8
  373. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  374. package/dist/types/src/handlers/records-read.d.ts +3 -8
  375. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  376. package/dist/types/src/handlers/records-subscribe.d.ts +8 -10
  377. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  378. package/dist/types/src/handlers/records-write.d.ts +4 -24
  379. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  380. package/dist/types/src/index.d.ts +8 -4
  381. package/dist/types/src/index.d.ts.map +1 -1
  382. package/dist/types/src/interfaces/messages-subscribe.d.ts +5 -0
  383. package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
  384. package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
  385. package/dist/types/src/interfaces/records-subscribe.d.ts +5 -0
  386. package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
  387. package/dist/types/src/interfaces/records-write-query.d.ts +33 -0
  388. package/dist/types/src/interfaces/records-write-query.d.ts.map +1 -0
  389. package/dist/types/src/interfaces/records-write-signing.d.ts +34 -0
  390. package/dist/types/src/interfaces/records-write-signing.d.ts.map +1 -0
  391. package/dist/types/src/interfaces/records-write.d.ts +13 -53
  392. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  393. package/dist/types/src/protocols/permission-grant.d.ts +1 -1
  394. package/dist/types/src/protocols/permission-grant.d.ts.map +1 -1
  395. package/dist/types/src/protocols/permission-request.d.ts +1 -1
  396. package/dist/types/src/protocols/permission-request.d.ts.map +1 -1
  397. package/dist/types/src/protocols/permissions.d.ts +40 -3
  398. package/dist/types/src/protocols/permissions.d.ts.map +1 -1
  399. package/dist/types/src/state-index/state-index-level.d.ts.map +1 -1
  400. package/dist/types/src/store/data-store-level.d.ts +20 -4
  401. package/dist/types/src/store/data-store-level.d.ts.map +1 -1
  402. package/dist/types/src/store/index-level-compound.d.ts +70 -0
  403. package/dist/types/src/store/index-level-compound.d.ts.map +1 -0
  404. package/dist/types/src/store/index-level.d.ts +4 -58
  405. package/dist/types/src/store/index-level.d.ts.map +1 -1
  406. package/dist/types/src/store/storage-controller.d.ts +4 -4
  407. package/dist/types/src/store/storage-controller.d.ts.map +1 -1
  408. package/dist/types/src/types/message-types.d.ts +3 -3
  409. package/dist/types/src/types/message-types.d.ts.map +1 -1
  410. package/dist/types/src/types/messages-types.d.ts +12 -3
  411. package/dist/types/src/types/messages-types.d.ts.map +1 -1
  412. package/dist/types/src/types/method-handler.d.ts +24 -3
  413. package/dist/types/src/types/method-handler.d.ts.map +1 -1
  414. package/dist/types/src/types/permission-types.d.ts +7 -0
  415. package/dist/types/src/types/permission-types.d.ts.map +1 -1
  416. package/dist/types/src/types/protocols-types.d.ts +41 -1
  417. package/dist/types/src/types/protocols-types.d.ts.map +1 -1
  418. package/dist/types/src/types/records-types.d.ts +16 -6
  419. package/dist/types/src/types/records-types.d.ts.map +1 -1
  420. package/dist/types/src/types/subscriptions.d.ts +151 -13
  421. package/dist/types/src/types/subscriptions.d.ts.map +1 -1
  422. package/dist/types/src/utils/hd-key.d.ts +1 -9
  423. package/dist/types/src/utils/hd-key.d.ts.map +1 -1
  424. package/dist/types/src/utils/messages.d.ts +7 -5
  425. package/dist/types/src/utils/messages.d.ts.map +1 -1
  426. package/dist/types/src/utils/protocols.d.ts +5 -0
  427. package/dist/types/src/utils/protocols.d.ts.map +1 -1
  428. package/dist/types/src/utils/records.d.ts +1 -11
  429. package/dist/types/src/utils/records.d.ts.map +1 -1
  430. package/dist/types/tests/dwn.spec.d.ts.map +1 -1
  431. package/dist/types/tests/event-emitter-event-log.spec.d.ts +2 -0
  432. package/dist/types/tests/event-emitter-event-log.spec.d.ts.map +1 -0
  433. package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -1
  434. package/dist/types/tests/features/owner-delegated-grant.spec.d.ts.map +1 -1
  435. package/dist/types/tests/features/owner-signature.spec.d.ts.map +1 -1
  436. package/dist/types/tests/features/permissions.spec.d.ts.map +1 -1
  437. package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -1
  438. package/dist/types/tests/features/records-immutable.spec.d.ts +2 -0
  439. package/dist/types/tests/features/records-immutable.spec.d.ts.map +1 -0
  440. package/dist/types/tests/features/records-record-limit.spec.d.ts +2 -0
  441. package/dist/types/tests/features/records-record-limit.spec.d.ts.map +1 -0
  442. package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -1
  443. package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -1
  444. package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
  445. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  446. package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -1
  447. package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
  448. package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
  449. package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
  450. package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
  451. package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
  452. package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
  453. package/dist/types/tests/scenarios/deleted-record.spec.d.ts.map +1 -1
  454. package/dist/types/tests/scenarios/subscriptions.spec.d.ts.map +1 -1
  455. package/dist/types/tests/test-event-stream.d.ts +11 -12
  456. package/dist/types/tests/test-event-stream.d.ts.map +1 -1
  457. package/dist/types/tests/test-suite.d.ts +2 -2
  458. package/dist/types/tests/test-suite.d.ts.map +1 -1
  459. package/dist/types/tests/utils/test-data-generator.d.ts +18 -0
  460. package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
  461. package/package.json +5 -4
  462. package/src/core/constants.ts +11 -0
  463. package/src/core/core-protocol.ts +129 -0
  464. package/src/core/dwn-error.ts +15 -12
  465. package/src/core/grant-authorization.ts +20 -3
  466. package/src/core/protocol-authorization-action.ts +377 -0
  467. package/src/core/protocol-authorization-validation.ts +487 -0
  468. package/src/core/protocol-authorization.ts +111 -856
  469. package/src/core/record-chain.ts +99 -0
  470. package/src/core/records-grant-authorization.ts +6 -8
  471. package/src/dwn.ts +58 -73
  472. package/src/event-stream/event-emitter-event-log.ts +283 -0
  473. package/src/handlers/messages-read.ts +8 -9
  474. package/src/handlers/messages-subscribe.ts +24 -28
  475. package/src/handlers/messages-sync.ts +10 -16
  476. package/src/handlers/protocols-configure.ts +47 -32
  477. package/src/handlers/protocols-query.ts +6 -9
  478. package/src/handlers/records-count.ts +11 -10
  479. package/src/handlers/records-delete.ts +12 -21
  480. package/src/handlers/records-query.ts +12 -12
  481. package/src/handlers/records-read.ts +34 -22
  482. package/src/handlers/records-subscribe.ts +47 -26
  483. package/src/handlers/records-write.ts +47 -104
  484. package/src/index.ts +9 -5
  485. package/src/interfaces/messages-subscribe.ts +7 -1
  486. package/src/interfaces/protocols-configure.ts +73 -8
  487. package/src/interfaces/records-count.ts +1 -1
  488. package/src/interfaces/records-delete.ts +1 -1
  489. package/src/interfaces/records-query.ts +1 -1
  490. package/src/interfaces/records-read.ts +1 -1
  491. package/src/interfaces/records-subscribe.ts +8 -1
  492. package/src/interfaces/records-write-query.ts +139 -0
  493. package/src/interfaces/records-write-signing.ts +123 -0
  494. package/src/interfaces/records-write.ts +66 -261
  495. package/src/protocols/permission-grant.ts +1 -1
  496. package/src/protocols/permission-request.ts +1 -1
  497. package/src/protocols/permissions.ts +148 -6
  498. package/src/state-index/state-index-level.ts +5 -7
  499. package/src/store/data-store-level.ts +124 -34
  500. package/src/store/index-level-compound.ts +324 -0
  501. package/src/store/index-level.ts +68 -341
  502. package/src/store/storage-controller.ts +11 -11
  503. package/src/types/message-types.ts +3 -3
  504. package/src/types/messages-types.ts +12 -3
  505. package/src/types/method-handler.ts +26 -4
  506. package/src/types/mitt.d.ts +28 -0
  507. package/src/types/permission-types.ts +7 -0
  508. package/src/types/protocols-types.ts +46 -0
  509. package/src/types/records-types.ts +16 -6
  510. package/src/types/subscriptions.ts +178 -14
  511. package/src/utils/hd-key.ts +0 -9
  512. package/src/utils/messages.ts +17 -37
  513. package/src/utils/protocols.ts +8 -0
  514. package/src/utils/records.ts +8 -59
  515. package/dist/esm/src/event-stream/event-emitter-stream.js +0 -60
  516. package/dist/esm/src/event-stream/event-emitter-stream.js.map +0 -1
  517. package/dist/esm/tests/event-stream/event-emitter-stream.spec.js +0 -77
  518. package/dist/esm/tests/event-stream/event-emitter-stream.spec.js.map +0 -1
  519. package/dist/esm/tests/event-stream/event-stream.spec.js +0 -123
  520. package/dist/esm/tests/event-stream/event-stream.spec.js.map +0 -1
  521. package/dist/types/src/event-stream/event-emitter-stream.d.ts +0 -23
  522. package/dist/types/src/event-stream/event-emitter-stream.d.ts.map +0 -1
  523. package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts +0 -2
  524. package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts.map +0 -1
  525. package/dist/types/tests/event-stream/event-stream.spec.d.ts +0 -2
  526. package/dist/types/tests/event-stream/event-stream.spec.d.ts.map +0 -1
  527. package/src/event-stream/event-emitter-stream.ts +0 -69
@@ -4,6 +4,13 @@ import type { LevelWrapperBatchOperation, LevelWrapperIteratorOptions, } from '.
4
4
  import { isEmptyObject } from '../utils/object.js';
5
5
  import { lexicographicalCompare } from '../utils/string.js';
6
6
  import { SortDirection } from '../types/query-types.js';
7
+ import {
8
+ countWithCompoundIndex,
9
+ createCompoundIndexDeleteOperation,
10
+ createCompoundIndexPutOperation,
11
+ queryWithCompoundIndex,
12
+ selectCompoundIndex,
13
+ } from './index-level-compound.js';
7
14
  import { createLevelDatabase, LevelWrapper } from './level-wrapper.js';
8
15
  import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
9
16
  import { FilterSelector, FilterUtility } from '../utils/filter.js';
@@ -36,9 +43,6 @@ export type CompoundIndexDefinition = {
36
43
 
37
44
  const INDEX_SUBLEVEL_NAME = 'index';
38
45
 
39
- /** Separator between compound key segments (higher than \x00 so prefix scans work correctly). */
40
- const COMPOUND_SEGMENT_SEPARATOR = '\x01';
41
-
42
46
  export interface IndexLevelOptions {
43
47
  signal?: AbortSignal;
44
48
  }
@@ -121,7 +125,9 @@ export class IndexLevel {
121
125
 
122
126
  // create compound index entries for any registered compound indexes whose properties are all present in the indexes.
123
127
  for (const compoundIndex of this._compoundIndexes) {
124
- const compoundOp = this.createCompoundIndexPutOperation(tenant, item, compoundIndex);
128
+ const compoundOp = createCompoundIndexPutOperation(
129
+ this.db, tenant, item, compoundIndex, IndexLevel.encodeValue, IndexLevel.delimiter
130
+ );
125
131
  if (compoundOp !== undefined) {
126
132
  opCreationPromises.push(compoundOp);
127
133
  }
@@ -171,7 +177,9 @@ export class IndexLevel {
171
177
 
172
178
  // delete compound index entries
173
179
  for (const compoundIndex of this._compoundIndexes) {
174
- const compoundOp = this.createCompoundIndexDeleteOperation(tenant, messageCid, indexes, compoundIndex);
180
+ const compoundOp = createCompoundIndexDeleteOperation(
181
+ this.db, tenant, messageCid, indexes, compoundIndex, IndexLevel.encodeValue, IndexLevel.delimiter
182
+ );
175
183
  if (compoundOp !== undefined) {
176
184
  opCreationPromises.push(compoundOp);
177
185
  }
@@ -289,9 +297,13 @@ export class IndexLevel {
289
297
 
290
298
  // Strategy 1: try compound index for single-filter queries
291
299
  if (filters.length === 1 && !isEmptyObject(filters[0])) {
292
- const compoundResult = this.selectCompoundIndex(filters[0], queryOptions);
300
+ const compoundResult = selectCompoundIndex(filters[0], queryOptions, this._compoundIndexes);
293
301
  if (compoundResult !== undefined) {
294
- return this.queryWithCompoundIndex(tenant, filters[0], queryOptions, compoundResult, options);
302
+ return queryWithCompoundIndex(
303
+ this.db, tenant, filters[0], queryOptions, compoundResult,
304
+ IndexLevel.encodeValue, IndexLevel.delimiter,
305
+ this.queryWithIteratorPaging.bind(this), options
306
+ );
295
307
  }
296
308
  }
297
309
 
@@ -315,9 +327,12 @@ export class IndexLevel {
315
327
 
316
328
  // try compound index for single-filter queries
317
329
  if (filters.length === 1 && !isEmptyObject(filters[0])) {
318
- const compoundResult = this.selectCompoundIndex(filters[0], { ...queryOptions });
330
+ const compoundResult = selectCompoundIndex(filters[0], { ...queryOptions }, this._compoundIndexes);
319
331
  if (compoundResult !== undefined) {
320
- return this.countWithCompoundIndex(tenant, filters[0], compoundResult, options);
332
+ return countWithCompoundIndex(
333
+ this.db, tenant, filters[0], compoundResult,
334
+ IndexLevel.encodeValue, this.query.bind(this), options
335
+ );
321
336
  }
322
337
  }
323
338
 
@@ -462,9 +477,18 @@ export class IndexLevel {
462
477
  }
463
478
 
464
479
  try {
465
- await Promise.all(filters.map(filter => {
466
- return this.executeSingleFilterQuery(tenant, filter, sortProperty, matches, options );
467
- }));
480
+ // Execute filters sequentially rather than with Promise.all.
481
+ // Firefox's IndexedDB implementation has two related async issues that cause flaky failures:
482
+ // 1. Concurrent cursors/transactions can silently miss recently-committed data
483
+ // 2. A read transaction opened immediately after a write transaction's oncomplete event
484
+ // can fail to see the written data (write-read race)
485
+ // Serializing eliminates both races. Performance impact is negligible: only 3 call sites
486
+ // (non-owner RecordsQuery/Subscribe/Count) ever pass multiple filters, and each filter
487
+ // reduces to a single bounded LevelDB range scan completing in single-digit ms.
488
+ // See: https://github.com/enboxorg/enbox/issues/264
489
+ for (const filter of filters) {
490
+ await this.executeSingleFilterQuery(tenant, filter, sortProperty, matches, options);
491
+ }
468
492
  } catch (error) {
469
493
  if ((error as DwnError).code === DwnErrorCode.IndexInvalidSortPropertyInMemory) {
470
494
  // return empty results if the sort property is invalid.
@@ -486,6 +510,10 @@ export class IndexLevel {
486
510
 
487
511
  /**
488
512
  * Execute a filtered query against a single filter and return all results.
513
+ *
514
+ * Sub-queries (exact match, range, OneOf) are executed sequentially to avoid opening
515
+ * multiple concurrent IndexedDB cursors. Firefox's IDB implementation intermittently
516
+ * drops results when cursors overlap — see https://github.com/enboxorg/enbox/issues/264
489
517
  */
490
518
  private async executeSingleFilterQuery(
491
519
  tenant: string,
@@ -495,13 +523,30 @@ export class IndexLevel {
495
523
  levelOptions?: IndexLevelOptions
496
524
  ): Promise<void> {
497
525
 
498
- // Note: We have an array of Promises in order to support OR (anyOf) matches when given a list of accepted values for a property
499
- const filterPromises: Promise<IndexedItem[]>[] = [];
526
+ // Collects results from each sub-query sequentially to avoid concurrent IndexedDB cursor races in Firefox.
527
+ const processResults = (indexItems: IndexedItem[]): void => {
528
+ for (const indexedItem of indexItems) {
529
+ // short circuit: if a data is already included to the final matched key set (by a different `Filter`),
530
+ // no need to evaluate if the data satisfies this current filter being evaluated
531
+ // otherwise check that the item is a match.
532
+ if (matches.has(indexedItem.messageCid) || !FilterUtility.matchFilter(indexedItem.indexes, filter)) {
533
+ continue;
534
+ }
535
+
536
+ // ensure that each matched item has the sortProperty, otherwise fail the entire query.
537
+ if (indexedItem.indexes[sortProperty] === undefined) {
538
+ throw new DwnError(DwnErrorCode.IndexInvalidSortPropertyInMemory, `invalid sort property ${sortProperty}`);
539
+ }
540
+
541
+ matches.set(indexedItem.messageCid, indexedItem);
542
+ }
543
+ };
500
544
 
501
545
  // If the filter is empty, then we just iterate over one of the indexes that contains all the records and return all items.
502
546
  if (isEmptyObject(filter)) {
503
- const getAllItemsPromise = this.getAllItems(tenant, sortProperty);
504
- filterPromises.push(getAllItemsPromise);
547
+ const allItems = await this.getAllItems(tenant, sortProperty);
548
+ processResults(allItems);
549
+ return;
505
550
  }
506
551
 
507
552
  // else the filter is not empty
@@ -511,40 +556,19 @@ export class IndexLevel {
511
556
  // We will find the union of these many individual queries later.
512
557
  if (FilterUtility.isEqualFilter(propertyFilter)) {
513
558
  // propertyFilter is an EqualFilter, meaning it is a non-object primitive type
514
- const exactMatchesPromise = this.filterExactMatches(tenant, propertyName, propertyFilter, levelOptions);
515
- filterPromises.push(exactMatchesPromise);
559
+ const exactMatches = await this.filterExactMatches(tenant, propertyName, propertyFilter, levelOptions);
560
+ processResults(exactMatches);
516
561
  } else if (FilterUtility.isOneOfFilter(propertyFilter)) {
517
562
  // `propertyFilter` is a OneOfFilter
518
- // Support OR matches by querying for each values separately, then adding them to the promises array.
563
+ // Support OR matches by querying for each value separately and sequentially.
519
564
  for (const propertyValue of new Set(propertyFilter)) {
520
- const exactMatchesPromise = this.filterExactMatches(tenant, propertyName, propertyValue, levelOptions);
521
- filterPromises.push(exactMatchesPromise);
565
+ const exactMatches = await this.filterExactMatches(tenant, propertyName, propertyValue, levelOptions);
566
+ processResults(exactMatches);
522
567
  }
523
568
  } else if (FilterUtility.isRangeFilter(propertyFilter)) {
524
569
  // `propertyFilter` is a `RangeFilter`
525
- const rangeMatchesPromise = this.filterRangeMatches(tenant, propertyName, propertyFilter, levelOptions);
526
- filterPromises.push(rangeMatchesPromise);
527
- }
528
- }
529
-
530
- // acting as an OR match for the property, any of the promises returning a match will be treated as a property match
531
- for (const promise of filterPromises) {
532
- const indexItems = await promise;
533
- // reminder: the promise returns a list of IndexedItem satisfying a particular property match
534
- for (const indexedItem of indexItems) {
535
- // short circuit: if a data is already included to the final matched key set (by a different `Filter`),
536
- // no need to evaluate if the data satisfies this current filter being evaluated
537
- // otherwise check that the item is a match.
538
- if (matches.has(indexedItem.messageCid) || !FilterUtility.matchFilter(indexedItem.indexes, filter)) {
539
- continue;
540
- }
541
-
542
- // ensure that each matched item has the sortProperty, otherwise fail the entire query.
543
- if (indexedItem.indexes[sortProperty] === undefined) {
544
- throw new DwnError(DwnErrorCode.IndexInvalidSortPropertyInMemory, `invalid sort property ${sortProperty}`);
545
- }
546
-
547
- matches.set(indexedItem.messageCid, indexedItem);
570
+ const rangeMatches = await this.filterRangeMatches(tenant, propertyName, propertyFilter, levelOptions);
571
+ processResults(rangeMatches);
548
572
  }
549
573
  }
550
574
  }
@@ -749,303 +773,6 @@ export class IndexLevel {
749
773
  }
750
774
  }
751
775
 
752
- // =========================================================================
753
- // Compound index methods
754
- // =========================================================================
755
-
756
- /**
757
- * Gets the compound index partition for a given compound index definition.
758
- * Compound index sublevels use the naming convention `__compound:<name>__`.
759
- */
760
- private async getCompoundIndexPartition(tenant: string, compoundIndex: CompoundIndexDefinition): Promise<LevelWrapper<string>> {
761
- const partitionName = `__compound:${compoundIndex.name}__`;
762
- return (await this.db.partition(tenant)).partition(partitionName);
763
- }
764
-
765
- /**
766
- * Builds a compound index key from the given indexes and compound index definition.
767
- *
768
- * Key format: `<prop1>\x01<prop2>\x01...\x01<sortValue>\x00<messageCid>`
769
- *
770
- * @returns the compound key, or undefined if the indexes don't contain all required properties.
771
- */
772
- private static buildCompoundKey(messageCid: string, indexes: KeyValues, compoundIndex: CompoundIndexDefinition): string | undefined {
773
- const segments: string[] = [];
774
-
775
- for (const property of compoundIndex.properties) {
776
- const value = indexes[property];
777
- if (value === undefined || Array.isArray(value)) {
778
- return undefined; // compound indexes don't support array values or missing properties
779
- }
780
- segments.push(IndexLevel.encodeValue(value));
781
- }
782
-
783
- const sortValue = indexes[compoundIndex.sortProperty];
784
- if (sortValue === undefined || Array.isArray(sortValue)) {
785
- return undefined;
786
- }
787
-
788
- // join prefix segments with \x01, then append sort value and messageCid with the standard delimiters
789
- const prefixPart = segments.join(COMPOUND_SEGMENT_SEPARATOR);
790
- const sortPart = IndexLevel.encodeValue(sortValue);
791
- return prefixPart + COMPOUND_SEGMENT_SEPARATOR + sortPart + IndexLevel.delimiter + messageCid;
792
- }
793
-
794
- /**
795
- * Builds the prefix portion of a compound key from filter values (without the sort/messageCid suffix).
796
- * Used for range scans: all entries with this prefix match the filter.
797
- */
798
- private static buildCompoundPrefix(filter: Filter, compoundIndex: CompoundIndexDefinition): string | undefined {
799
- const segments: string[] = [];
800
-
801
- for (const property of compoundIndex.properties) {
802
- const filterValue = filter[property];
803
- if (filterValue === undefined || typeof filterValue === 'object') {
804
- return undefined; // compound prefix only works with equality filters
805
- }
806
- segments.push(IndexLevel.encodeValue(filterValue));
807
- }
808
-
809
- return segments.join(COMPOUND_SEGMENT_SEPARATOR) + COMPOUND_SEGMENT_SEPARATOR;
810
- }
811
-
812
- /**
813
- * Creates a put operation for a compound index entry.
814
- * Returns undefined if the indexes don't contain all required compound index properties.
815
- */
816
- private createCompoundIndexPutOperation(
817
- tenant: string,
818
- item: IndexedItem,
819
- compoundIndex: CompoundIndexDefinition
820
- ): Promise<LevelWrapperBatchOperation<string>> | undefined {
821
- const key = IndexLevel.buildCompoundKey(item.messageCid, item.indexes, compoundIndex);
822
- if (key === undefined) {
823
- return undefined;
824
- }
825
-
826
- return this.createOperationForPartition(tenant, `__compound:${compoundIndex.name}__`, {
827
- type : 'put',
828
- key,
829
- value : JSON.stringify(item),
830
- });
831
- }
832
-
833
- /**
834
- * Creates a delete operation for a compound index entry.
835
- * Returns undefined if the indexes don't contain all required compound index properties.
836
- */
837
- private createCompoundIndexDeleteOperation(
838
- tenant: string,
839
- messageCid: string,
840
- indexes: KeyValues,
841
- compoundIndex: CompoundIndexDefinition
842
- ): Promise<LevelWrapperBatchOperation<string>> | undefined {
843
- const key = IndexLevel.buildCompoundKey(messageCid, indexes, compoundIndex);
844
- if (key === undefined) {
845
- return undefined;
846
- }
847
-
848
- return this.createOperationForPartition(tenant, `__compound:${compoundIndex.name}__`, {
849
- type: 'del',
850
- key,
851
- });
852
- }
853
-
854
- /**
855
- * Generic helper to create a batch operation for any named partition under a tenant.
856
- */
857
- private async createOperationForPartition(
858
- tenant: string,
859
- partitionName: string,
860
- operation: LevelWrapperBatchOperation<string>
861
- ): Promise<LevelWrapperBatchOperation<string>> {
862
- const tenantPartition = await this.db.partition(tenant);
863
- return tenantPartition.createPartitionOperation(partitionName, operation);
864
- }
865
-
866
- /**
867
- * Selects the best compound index that covers the given filter and sort requirements.
868
- *
869
- * A compound index "covers" a query when:
870
- * 1. Every property in the compound index definition is present in the filter as an equality filter.
871
- * 2. The compound index's sort property matches the query's sort property.
872
- *
873
- * Among multiple matching compound indexes, the one with the most properties is preferred
874
- * (more specific = fewer false positives in the prefix scan).
875
- */
876
- private selectCompoundIndex(filter: Filter, queryOptions: QueryOptions): CompoundIndexDefinition | undefined {
877
- let bestMatch: CompoundIndexDefinition | undefined;
878
- let bestPropertyCount = 0;
879
-
880
- for (const compoundIndex of this._compoundIndexes) {
881
- // check that the sort property matches
882
- if (compoundIndex.sortProperty !== queryOptions.sortProperty) {
883
- continue;
884
- }
885
-
886
- // check that all compound properties are present in the filter as equality filters
887
- let allPropertiesMatch = true;
888
- for (const property of compoundIndex.properties) {
889
- const filterValue = filter[property];
890
- if (filterValue === undefined || typeof filterValue === 'object') {
891
- allPropertiesMatch = false;
892
- break;
893
- }
894
- }
895
-
896
- if (allPropertiesMatch && compoundIndex.properties.length > bestPropertyCount) {
897
- bestMatch = compoundIndex;
898
- bestPropertyCount = compoundIndex.properties.length;
899
- }
900
- }
901
-
902
- return bestMatch;
903
- }
904
-
905
- /**
906
- * Queries using a compound index. This is the most efficient query strategy: a single LevelDB
907
- * range scan that filters, sorts, and paginates all at once.
908
- *
909
- * The compound key encodes the filter properties as a prefix and the sort property as a suffix,
910
- * so iterating over keys with the filter prefix yields results in sort order.
911
- *
912
- * Any remaining filter properties not covered by the compound index are verified in memory.
913
- */
914
- private async queryWithCompoundIndex(
915
- tenant: string,
916
- filter: Filter,
917
- queryOptions: QueryOptions,
918
- compoundIndex: CompoundIndexDefinition,
919
- options?: IndexLevelOptions
920
- ): Promise<IndexedItem[]> {
921
- const { sortDirection = SortDirection.Ascending, cursor, limit } = queryOptions;
922
-
923
- const prefix = IndexLevel.buildCompoundPrefix(filter, compoundIndex);
924
- if (prefix === undefined) {
925
- // should not happen since selectCompoundIndex already validated, but guard against it
926
- return this.queryWithIteratorPaging(tenant, [filter], queryOptions, options);
927
- }
928
-
929
- const partition = await this.getCompoundIndexPartition(tenant, compoundIndex);
930
-
931
- // determine the iterator bounds from the prefix
932
- const iteratorOptions: LevelWrapperIteratorOptions<string> = {};
933
-
934
- if (cursor !== undefined) {
935
- // build the full compound key for the cursor position
936
- const cursorSortEncoded = IndexLevel.encodeValue(cursor.value);
937
- const cursorKey = prefix + cursorSortEncoded + IndexLevel.delimiter + cursor.messageCid;
938
-
939
- if (sortDirection === SortDirection.Ascending) {
940
- iteratorOptions.gt = cursorKey;
941
- // upper bound: everything with this prefix (prefix + \xff is past all valid compound keys with this prefix)
942
- iteratorOptions.lt = prefix + '\xff';
943
- } else {
944
- iteratorOptions.lt = cursorKey;
945
- iteratorOptions.gt = prefix;
946
- iteratorOptions.reverse = true;
947
- }
948
- } else {
949
- if (sortDirection === SortDirection.Ascending) {
950
- iteratorOptions.gt = prefix;
951
- iteratorOptions.lt = prefix + '\xff';
952
- } else {
953
- // for descending without cursor, start from the end of the prefix range
954
- iteratorOptions.gt = prefix;
955
- iteratorOptions.lt = prefix + '\xff';
956
- iteratorOptions.reverse = true;
957
- }
958
- }
959
-
960
- // determine which filter properties are NOT covered by the compound index
961
- // (need in-memory verification for these)
962
- // NOTE: the compound index equality properties are fully covered by the prefix scan,
963
- // but the sort property is only covered for ordering — any range filter on the sort
964
- // property must still be applied as a residual filter.
965
- const coveredEqualityProperties = new Set(compoundIndex.properties);
966
- const residualFilter: Filter = {};
967
- let hasResidualFilter = false;
968
- for (const property in filter) {
969
- if (!coveredEqualityProperties.has(property)) {
970
- residualFilter[property] = filter[property];
971
- hasResidualFilter = true;
972
- }
973
- }
974
-
975
- const matches: IndexedItem[] = [];
976
- for await (const [_key, value] of partition.iterator(iteratorOptions, options)) {
977
- if (limit !== undefined && matches.length === limit) {
978
- break;
979
- }
980
-
981
- const item = JSON.parse(value) as IndexedItem;
982
-
983
- // verify any residual filter properties in memory
984
- if (hasResidualFilter && !FilterUtility.matchFilter(item.indexes, residualFilter)) {
985
- continue;
986
- }
987
-
988
- matches.push(item);
989
- }
990
-
991
- return matches;
992
- }
993
-
994
- /**
995
- * Counts items matching a compound index prefix without loading full records.
996
- * Iterates only keys (not values) for maximum efficiency.
997
- */
998
- private async countWithCompoundIndex(
999
- tenant: string,
1000
- filter: Filter,
1001
- compoundIndex: CompoundIndexDefinition,
1002
- options?: IndexLevelOptions
1003
- ): Promise<number> {
1004
- const prefix = IndexLevel.buildCompoundPrefix(filter, compoundIndex);
1005
- if (prefix === undefined) {
1006
- // fallback
1007
- const results = await this.query(tenant, [filter], { sortProperty: compoundIndex.sortProperty }, options);
1008
- return results.length;
1009
- }
1010
-
1011
- const partition = await this.getCompoundIndexPartition(tenant, compoundIndex);
1012
-
1013
- // determine which filter properties are NOT covered by the compound index
1014
- // (same logic as queryWithCompoundIndex: sort property range filters are residual)
1015
- const coveredEqualityProperties = new Set(compoundIndex.properties);
1016
- let hasResidualFilter = false;
1017
- const residualFilter: Filter = {};
1018
- for (const property in filter) {
1019
- if (!coveredEqualityProperties.has(property)) {
1020
- residualFilter[property] = filter[property];
1021
- hasResidualFilter = true;
1022
- }
1023
- }
1024
-
1025
- const iteratorOptions: LevelWrapperIteratorOptions<string> = {
1026
- gt : prefix,
1027
- lt : prefix + '\xff',
1028
- };
1029
-
1030
- let count = 0;
1031
- if (hasResidualFilter) {
1032
- // must read values to check residual filter
1033
- for await (const [_key, value] of partition.iterator(iteratorOptions, options)) {
1034
- const item = JSON.parse(value) as IndexedItem;
1035
- if (FilterUtility.matchFilter(item.indexes, residualFilter)) {
1036
- count++;
1037
- }
1038
- }
1039
- } else {
1040
- // no residual filter — iterate keys via iterator without parsing values
1041
- for await (const [_key, _value] of partition.iterator(iteratorOptions, options)) {
1042
- count++;
1043
- }
1044
- }
1045
-
1046
- return count;
1047
- }
1048
-
1049
776
  // =========================================================================
1050
777
  // Query strategy selection
1051
778
  // =========================================================================
@@ -1,5 +1,5 @@
1
1
  import type { DataStore } from '../types/data-store.js';
2
- import type { EventStream } from '../types/subscriptions.js';
2
+ import type { EventLog } from '../types/subscriptions.js';
3
3
  import type { GenericMessage } from '../types/message-types.js';
4
4
  import type { MessageStore } from '../types/message-store.js';
5
5
  import type { StateIndex } from '../types/state-index.js';
@@ -26,18 +26,18 @@ export class StorageController {
26
26
  private messageStore: MessageStore;
27
27
  private dataStore: DataStore;
28
28
  private stateIndex: StateIndex;
29
- private eventStream?: EventStream;
29
+ private eventLog?: EventLog;
30
30
 
31
- public constructor({ messageStore, dataStore, stateIndex, eventStream }: {
32
- messageStore: MessageStore,
33
- dataStore: DataStore,
34
- stateIndex: StateIndex,
35
- eventStream?: EventStream}
31
+ public constructor({ messageStore, dataStore, stateIndex, eventLog }: {
32
+ messageStore : MessageStore,
33
+ dataStore : DataStore,
34
+ stateIndex : StateIndex,
35
+ eventLog? : EventLog}
36
36
  ) {
37
37
  this.messageStore = messageStore;
38
38
  this.dataStore = dataStore;
39
39
  this.stateIndex = stateIndex;
40
- this.eventStream = eventStream;
40
+ this.eventLog = eventLog;
41
41
  }
42
42
 
43
43
  public async performRecordsDelete({ tenant, message }: ResumableRecordsDeleteData): Promise<void> {
@@ -66,9 +66,9 @@ export class StorageController {
66
66
  await this.messageStore.put(tenant, message, indexes);
67
67
  await this.stateIndex.insert(tenant, messageCid, indexes);
68
68
 
69
- // only emit if the event stream is set
70
- if (this.eventStream !== undefined) {
71
- this.eventStream.emit(tenant, { message, initialWrite }, indexes);
69
+ // only emit if the event log is set
70
+ if (this.eventLog !== undefined) {
71
+ await this.eventLog.emit(tenant, { message, initialWrite }, indexes);
72
72
  }
73
73
 
74
74
  if (message.descriptor.prune) {
@@ -65,13 +65,13 @@ export type DelegatedGrantRecordsWriteMessage = {
65
65
  signature: GeneralJws;
66
66
  },
67
67
  recordId: string,
68
- contextId?: string;
68
+ contextId: string;
69
69
  // NOTE: This is a direct expansion and copy of `DataEncodedRecordsWriteMessage` to avoid circular references.
70
70
  descriptor: {
71
71
  interface: DwnInterfaceName.Records;
72
72
  method: DwnMethodName.Write;
73
- protocol?: string;
74
- protocolPath?: string;
73
+ protocol: string;
74
+ protocolPath: string;
75
75
  recipient?: string;
76
76
  schema?: string;
77
77
  parentId?: string;
@@ -1,5 +1,5 @@
1
- import type { MessageEvent } from './subscriptions.js';
2
1
  import type { RangeCriterion } from './query-types.js';
2
+ import type { SubscriptionListener } from './subscriptions.js';
3
3
  import type { AuthorizationModel, GenericMessage, GenericMessageReply, MessageSubscription } from './message-types.js';
4
4
  import type { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
5
5
 
@@ -59,10 +59,13 @@ export type MessagesSyncReply = GenericMessageReply & {
59
59
  entries? : string[]; // messageCid[] (for 'leaves' action)
60
60
  };
61
61
 
62
- export type MessageSubscriptionHandler = (event: MessageEvent) => void;
62
+ /**
63
+ * @deprecated Use {@link SubscriptionListener} directly. Retained as an alias for migration.
64
+ */
65
+ export type MessageSubscriptionHandler = SubscriptionListener;
63
66
 
64
67
  export type MessagesSubscribeMessageOptions = {
65
- subscriptionHandler: MessageSubscriptionHandler;
68
+ subscriptionHandler: SubscriptionListener;
66
69
  };
67
70
 
68
71
  export type MessagesSubscribeMessage = {
@@ -80,4 +83,10 @@ export type MessagesSubscribeDescriptor = {
80
83
  messageTimestamp: string;
81
84
  filters: MessagesFilter[];
82
85
  permissionGrantId?: string;
86
+ /**
87
+ * Opaque EventLog cursor string to resume from. When provided, the handler replays
88
+ * events from the EventLog starting after this cursor instead of returning no
89
+ * initial snapshot. An EOSE marker is sent after catch-up.
90
+ */
91
+ cursor?: string;
83
92
  };
@@ -1,5 +1,10 @@
1
- import type { MessageSubscriptionHandler } from './messages-types.js';
2
- import type { RecordSubscriptionHandler } from './records-types.js';
1
+ import type { CoreProtocolRegistry } from '../core/core-protocol.js';
2
+ import type { DataStore } from './data-store.js';
3
+ import type { DidResolver } from '@enbox/dids';
4
+ import type { MessageStore } from './message-store.js';
5
+ import type { ResumableTaskManager } from '../core/resumable-task-manager.js';
6
+ import type { StateIndex } from './state-index.js';
7
+ import type { EventLog, SubscriptionListener } from './subscriptions.js';
3
8
  import type { GenericMessage, GenericMessageReply } from './message-types.js';
4
9
 
5
10
  /**
@@ -13,6 +18,23 @@ export interface MethodHandler {
13
18
  tenant: string;
14
19
  message: GenericMessage;
15
20
  dataStream?: ReadableStream<Uint8Array>
16
- subscriptionHandler?: MessageSubscriptionHandler | RecordSubscriptionHandler;
21
+ subscriptionHandler?: SubscriptionListener;
17
22
  }): Promise<GenericMessageReply>;
18
- }
23
+ }
24
+
25
+ /**
26
+ * Shared dependency bag for all DWN method handlers.
27
+ *
28
+ * Every handler receives the same object; each handler accesses only the
29
+ * dependencies it needs. Adding a new dependency here is a single-line
30
+ * change — no handler constructor signatures need updating.
31
+ */
32
+ export type HandlerDependencies = {
33
+ didResolver: DidResolver;
34
+ messageStore: MessageStore;
35
+ dataStore?: DataStore;
36
+ stateIndex?: StateIndex;
37
+ resumableTaskManager?: ResumableTaskManager;
38
+ coreProtocols?: CoreProtocolRegistry;
39
+ eventLog?: EventLog;
40
+ };
@@ -0,0 +1,28 @@
1
+ // mitt v3 does not include `"type": "module"` in its package.json, so under
2
+ // TypeScript's `NodeNext` module resolution the `export default function` in
3
+ // mitt's own typings is treated as a CJS namespace rather than a callable.
4
+ // This ambient module declaration re-exports the factory as a proper ESM
5
+ // default so `import mitt from 'mitt'` type-checks correctly.
6
+ declare module 'mitt' {
7
+ type EventType = string | symbol;
8
+ type Handler<T = unknown> = (event: T) => void;
9
+ type EventHandlerList<T = unknown> = Array<Handler<T>>;
10
+ type WildCardEventHandlerList<T = Record<string, unknown>> = Array<
11
+ (type: keyof T, event: T[keyof T]) => void
12
+ >;
13
+ type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<
14
+ keyof Events | '*',
15
+ EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>
16
+ >;
17
+
18
+ interface Emitter<Events extends Record<EventType, unknown>> {
19
+ all: EventHandlerMap<Events>;
20
+ on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;
21
+ off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void;
22
+ emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;
23
+ }
24
+
25
+ export default function mitt<Events extends Record<EventType, unknown>>(
26
+ all?: EventHandlerMap<Events>
27
+ ): Emitter<Events>;
28
+ }
@@ -76,6 +76,13 @@ export type ProtocolPermissionScope = {
76
76
  protocol?: string;
77
77
  };
78
78
 
79
+ /**
80
+ * Permission scope for the Messages interface.
81
+ *
82
+ * A `Read` scope is a unified scope that authorizes `MessagesRead`, `MessagesSubscribe`, and `MessagesSync` operations.
83
+ * The `Subscribe` and `Sync` method values are retained for backward compatibility with existing grants but are
84
+ * functionally equivalent to `Read` — new grants SHOULD use `Read` exclusively.
85
+ */
79
86
  export type MessagesPermissionScope = {
80
87
  interface: DwnInterfaceName.Messages;
81
88
  method: DwnMethodName.Read | DwnMethodName.Subscribe | DwnMethodName.Sync;