@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
@@ -1,14 +1,21 @@
1
+ import type { Filter } from '../types/query-types.js';
1
2
  import type { GenericMessage } from '../types/message-types.js';
3
+ import type { MessagesFilter } from '../types/messages-types.js';
2
4
  import type { MessageSigner } from '../types/signer.js';
3
5
  import type { MessageStore } from '../types/message-store.js';
4
6
  import type { ProtocolDefinition } from '../types/protocols-types.js';
7
+ import type { CoreProtocol, CoreProtocolStores } from '../core/core-protocol.js';
5
8
  import type { DataEncodedRecordsWriteMessage, RecordsWriteMessage } from '../types/records-types.js';
6
9
  import type { PermissionConditions, PermissionGrantData, PermissionRequestData, PermissionRevocationData, PermissionScope, RecordsPermissionScope } from '../types/permission-types.js';
7
10
 
11
+ import { DwnConstant } from '../core/dwn-constant.js';
8
12
  import { Encoder } from '../utils/encoder.js';
13
+ import { FilterUtility } from '../utils/filter.js';
14
+ import { Message } from '../core/message.js';
9
15
  import { PermissionGrant } from './permission-grant.js';
10
16
  import { PermissionRequest } from './permission-request.js';
11
- import { RecordsWrite } from '../../src/interfaces/records-write.js';
17
+ import { Records } from '../utils/records.js';
18
+ import { RecordsWrite } from '../interfaces/records-write.js';
12
19
  import { Time } from '../utils/time.js';
13
20
  import { validateJsonSchema } from '../schema-validator.js';
14
21
  import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
@@ -79,12 +86,16 @@ export type PermissionRevocationCreateOptions = {
79
86
 
80
87
  /**
81
88
  * This is a first-class DWN protocol for managing permission grants of a given DWN.
89
+ *
90
+ * It implements the `CoreProtocol` interface so that its lifecycle hooks
91
+ * (validation, pre-processing, post-processing) are dispatched generically
92
+ * by the `CoreProtocolRegistry` rather than being hardcoded in handlers.
82
93
  */
83
- export class PermissionsProtocol {
94
+ export class PermissionsProtocol implements CoreProtocol {
84
95
  /**
85
96
  * The URI of the DWN Permissions protocol.
86
97
  */
87
- public static readonly uri = 'https://tbd.website/dwn/permissions';
98
+ public static readonly uri = 'https://identity.foundation/dwn/permissions';
88
99
 
89
100
  /**
90
101
  * The protocol path of the `request` record.
@@ -156,6 +167,137 @@ export class PermissionsProtocol {
156
167
  }
157
168
  };
158
169
 
170
+ // ---------- CoreProtocol instance accessors ----------
171
+
172
+ /** @inheritdoc */
173
+ public get uri(): string {
174
+ return PermissionsProtocol.uri;
175
+ }
176
+
177
+ /** @inheritdoc */
178
+ public get definition(): ProtocolDefinition {
179
+ return PermissionsProtocol.definition;
180
+ }
181
+
182
+ // ---------- CoreProtocol lifecycle hooks ----------
183
+
184
+ /** @inheritdoc */
185
+ public validateRecord(message: RecordsWriteMessage, dataBytes: Uint8Array): void {
186
+ PermissionsProtocol.validateSchema(message, dataBytes);
187
+ }
188
+
189
+ /**
190
+ * Pre-processing hook for permission revocation records.
191
+ * Validates that the revocation's `tags.protocol` matches the grant's scoped protocol.
192
+ */
193
+ public async preProcessWrite(
194
+ tenant: string,
195
+ message: RecordsWriteMessage,
196
+ messageStore: MessageStore,
197
+ ): Promise<void> {
198
+ if (message.descriptor.protocolPath !== PermissionsProtocol.revocationPath) {
199
+ return;
200
+ }
201
+
202
+ // fetch the parent grant to compare the scoped protocol against the revocation tag
203
+ const permissionGrantId = message.descriptor.parentId!;
204
+ const grant = await PermissionsProtocol.fetchGrant(tenant, messageStore, permissionGrantId);
205
+
206
+ const revokeTagProtocol = message.descriptor.tags?.protocol;
207
+ const grantProtocol = 'protocol' in grant.scope ? grant.scope.protocol : undefined;
208
+ if (grantProtocol !== revokeTagProtocol) {
209
+ throw new DwnError(
210
+ DwnErrorCode.PermissionsProtocolValidateRevocationProtocolTagMismatch,
211
+ `Revocation protocol ${revokeTagProtocol} does not match grant protocol ${grantProtocol}`
212
+ );
213
+ }
214
+ }
215
+
216
+ /**
217
+ * Post-processing hook for permission revocation records.
218
+ * When a grant is revoked, all messages authorized by that grant and created
219
+ * after the revocation timestamp are deleted from all stores.
220
+ *
221
+ * Deletion order is deliberate to avoid orphaned data in case of crash:
222
+ * 1. data store (large blobs first)
223
+ * 2. state index (SMT entries)
224
+ * 3. message store
225
+ */
226
+ public async postProcessWrite(
227
+ tenant: string,
228
+ recordsWrite: RecordsWrite,
229
+ stores: CoreProtocolStores,
230
+ ): Promise<void> {
231
+ if (recordsWrite.message.descriptor.protocolPath !== PermissionsProtocol.revocationPath) {
232
+ return;
233
+ }
234
+
235
+ const permissionGrantId = recordsWrite.message.descriptor.parentId!;
236
+ const grantAuthorizedMessagesQuery = {
237
+ permissionGrantId,
238
+ dateCreated: { gte: recordsWrite.message.descriptor.messageTimestamp },
239
+ };
240
+ const { messages: grantAuthorizedMessages } = await stores.messageStore.query(tenant, [grantAuthorizedMessagesQuery]);
241
+
242
+ if (grantAuthorizedMessages.length === 0) {
243
+ return;
244
+ }
245
+
246
+ // 1. Delete data from the data store first to avoid orphaned data blobs in case of crash.
247
+ // Only RecordsWrite messages with data larger than maxDataSizeAllowedToBeEncoded have data in the data store.
248
+ for (const message of grantAuthorizedMessages) {
249
+ if (message.descriptor.method === DwnMethodName.Write) {
250
+ const recordsWriteMessage = message as RecordsWriteMessage;
251
+ if (recordsWriteMessage.descriptor.dataSize > DwnConstant.maxDataSizeAllowedToBeEncoded) {
252
+ await stores.dataStore.delete(tenant, recordsWriteMessage.recordId, recordsWriteMessage.descriptor.dataCid);
253
+ }
254
+ }
255
+ }
256
+
257
+ // 2. Compute CIDs and delete from state index before message store to avoid orphaned state entries.
258
+ const messageCids = await Promise.all(grantAuthorizedMessages.map((message): Promise<string> => Message.getCid(message)));
259
+ await stores.stateIndex.delete(tenant, messageCids);
260
+
261
+ // 3. Finally delete all messages from the message store.
262
+ await Promise.all(messageCids.map((cid): Promise<void> => stores.messageStore.delete(tenant, cid)));
263
+ }
264
+
265
+ /** @inheritdoc */
266
+ public mapErrorToStatusCode(errorCode: string): number | undefined {
267
+ if (errorCode.startsWith('PermissionsProtocolValidate')) {
268
+ return 400;
269
+ }
270
+ return undefined;
271
+ }
272
+
273
+ /**
274
+ * Constructs an additional filter for protocol-scoped message queries so that
275
+ * permission records (grants, requests, revocations) tagged with the target
276
+ * protocol appear alongside that protocol's own records in sync/subscribe/read results.
277
+ */
278
+ public constructAdditionalMessageFilter(filter: MessagesFilter): Filter | undefined {
279
+ const { protocol, messageTimestamp } = filter;
280
+ if (protocol === undefined) {
281
+ return undefined;
282
+ }
283
+
284
+ const taggedFilter = {
285
+ protocol: PermissionsProtocol.uri,
286
+ ...Records.convertTagsFilter({ protocol }),
287
+ } as Filter;
288
+
289
+ if (messageTimestamp !== undefined) {
290
+ const messageTimestampFilter = FilterUtility.convertRangeCriterion(messageTimestamp);
291
+ if (messageTimestampFilter) {
292
+ taggedFilter.messageTimestamp = messageTimestampFilter;
293
+ }
294
+ }
295
+
296
+ return taggedFilter;
297
+ }
298
+
299
+ // ---------- Static utility methods ----------
300
+
159
301
  public static parseRequest(base64UrlEncodedRequest: string): PermissionRequestData {
160
302
  return Encoder.base64UrlToObject(base64UrlEncodedRequest);
161
303
  }
@@ -394,7 +536,7 @@ export class PermissionsProtocol {
394
536
  }
395
537
 
396
538
  const permissionGrantMessage = possibleGrantMessage as DataEncodedRecordsWriteMessage;
397
- const permissionGrant = await PermissionGrant.parse(permissionGrantMessage);
539
+ const permissionGrant = PermissionGrant.parse(permissionGrantMessage);
398
540
 
399
541
  return permissionGrant;
400
542
  }
@@ -421,11 +563,11 @@ export class PermissionsProtocol {
421
563
  const grant = await PermissionsProtocol.fetchGrant(tenant, messageStore, incomingMessage.descriptor.parentId!);
422
564
  return grant.scope;
423
565
  } else if (incomingMessage.descriptor.protocolPath === PermissionsProtocol.grantPath) {
424
- const grant = await PermissionGrant.parse(incomingMessage);
566
+ const grant = PermissionGrant.parse(incomingMessage);
425
567
  return grant.scope;
426
568
  } else {
427
569
  // if the record is not a grant or revocation, it must be a request
428
- const request = await PermissionRequest.parse(incomingMessage);
570
+ const request = PermissionRequest.parse(incomingMessage);
429
571
  return request.scope;
430
572
  }
431
573
  }
@@ -83,7 +83,8 @@ export class StateIndexLevel implements StateIndex {
83
83
  const globalSmt = await this.getGlobalTree(tenant);
84
84
  await globalSmt.insert(messageCid);
85
85
 
86
- // If the message is associated with a protocol, insert into the protocol-scoped tree
86
+ // Insert into the protocol-scoped tree if the message has a protocol (e.g. RecordsWrite).
87
+ // Non-record messages like ProtocolsConfigure do not have a protocol.
87
88
  const protocol = indexes.protocol as string | undefined;
88
89
  if (protocol !== undefined) {
89
90
  const protoSmt = await this.getProtocolTree(tenant, protocol);
@@ -104,7 +105,7 @@ export class StateIndexLevel implements StateIndex {
104
105
  // Delete from global tree
105
106
  await globalSmt.delete(messageCid);
106
107
 
107
- // Delete from protocol tree if applicable
108
+ // Delete from protocol tree if the message had a protocol
108
109
  if (indexes !== undefined) {
109
110
  const protocol = indexes.protocol as string | undefined;
110
111
  if (protocol !== undefined) {
@@ -204,11 +205,8 @@ export class StateIndexLevel implements StateIndex {
204
205
  */
205
206
  private async storeIndexes(tenant: string, messageCid: string, indexes: KeyValues): Promise<void> {
206
207
  const metaPartition = await this.getMetaPartition(tenant);
207
- // Only store the minimal set of indexes needed for deletion (protocol)
208
- const minimalIndexes: KeyValues = {};
209
- if (indexes.protocol !== undefined) {
210
- minimalIndexes.protocol = indexes.protocol;
211
- }
208
+ // Store the protocol index needed for deletion
209
+ const minimalIndexes: KeyValues = { protocol: indexes.protocol };
212
210
  await metaPartition.put(messageCid, JSON.stringify(minimalIndexes));
213
211
  }
214
212
 
@@ -1,4 +1,5 @@
1
1
  import type { ImportResult } from 'ipfs-unixfs-importer';
2
+ import type { LevelWrapper } from './level-wrapper.js';
2
3
  import type { DataStore, DataStoreGetResult, DataStorePutResult } from '../types/data-store.js';
3
4
 
4
5
  import { BlockstoreLevel } from './blockstore-level.js';
@@ -7,12 +8,20 @@ import { DataStream } from '../utils/data-stream.js';
7
8
  import { exporter } from 'ipfs-unixfs-exporter';
8
9
  import { importer } from 'ipfs-unixfs-importer';
9
10
 
11
+ const textEncoder = new TextEncoder();
12
+ const textDecoder = new TextDecoder();
13
+
10
14
  /**
11
15
  * A simple implementation of {@link DataStore} that works in both the browser and server-side.
12
16
  * Leverages LevelDB under the hood.
13
17
  *
14
- * It has the following structure (`+` represents an additional sublevel/partition):
15
- * 'data' + <tenant> + <recordId> + <dataCid> -> <data>
18
+ * It has the following sublevel structure (`+` represents an additional sublevel):
19
+ * 'refs' + <tenant> + <recordId> : key <dataCid> JSON { dataSize }
20
+ * 'blocks' + <dataCid> : key <blockCid> → block data (shared)
21
+ * 'refcounts' : key <dataCid> → JSON { count, dataSize }
22
+ *
23
+ * Identical data (same dataCid) is stored only once in the blocks sublevel.
24
+ * Multiple (tenant, recordId) pairs can reference the same blocks.
16
25
  */
17
26
  export class DataStoreLevel implements DataStore {
18
27
  config: DataStoreLevelConfig;
@@ -41,29 +50,74 @@ export class DataStoreLevel implements DataStore {
41
50
  }
42
51
 
43
52
  async put(tenant: string, recordId: string, dataCid: string, dataStream: ReadableStream<Uint8Array>): Promise<DataStorePutResult> {
44
- const blockstoreForData = await this.getBlockstoreForStoringData(tenant, recordId, dataCid);
53
+ // Check if this exact ref already exists (idempotent re-put).
54
+ const refsPartition = await this.getRefsPartition(tenant, recordId);
55
+ const existingRef = await refsPartition.get(dataCid);
56
+ if (existingRef) {
57
+ await dataStream.cancel();
58
+ const { dataSize } = JSON.parse(textDecoder.decode(existingRef)) as { dataSize: number };
59
+ return { dataSize };
60
+ }
45
61
 
46
- const asyncDataBlocks = importer([{ content: DataStream.asAsyncIterable(dataStream) }], blockstoreForData, { cidVersion: 1 });
62
+ // Check refcount if > 0, blocks already exist for this dataCid.
63
+ const refcountsPartition = await this.getRefcountsPartition();
64
+ const rawRefcount = await refcountsPartition.get(dataCid);
65
+ const refcountData = rawRefcount
66
+ ? JSON.parse(textDecoder.decode(rawRefcount)) as { count: number; dataSize: number }
67
+ : { count: 0, dataSize: 0 };
68
+
69
+ let dataSize: number;
70
+
71
+ if (refcountData.count > 0) {
72
+ // Blocks already exist — skip import.
73
+ await dataStream.cancel();
74
+ dataSize = refcountData.dataSize;
75
+ } else {
76
+ // First write — import blocks into the shared blocks partition.
77
+ const blocksPartition = await this.getBlocksPartition(dataCid);
78
+ const asyncDataBlocks = importer(
79
+ [{ content: DataStream.asAsyncIterable(dataStream) }],
80
+ blocksPartition,
81
+ { cidVersion: 1 }
82
+ );
83
+
84
+ // NOTE: the last block contains the root CID as well as info to derive the data size.
85
+ let dataDagRoot!: ImportResult;
86
+ for await (dataDagRoot of asyncDataBlocks) { ; }
87
+ dataSize = Number(dataDagRoot.unixfs?.fileSize() ?? dataDagRoot.size);
88
+ }
47
89
 
48
- // NOTE: the last block contains the root CID as well as info to derive the data size
49
- let dataDagRoot!: ImportResult;
50
- for await (dataDagRoot of asyncDataBlocks) { ; }
90
+ // Write ref entry.
91
+ await refsPartition.put(dataCid, textEncoder.encode(JSON.stringify({ dataSize })));
51
92
 
52
- return {
53
- dataSize: Number(dataDagRoot.unixfs?.fileSize() ?? dataDagRoot.size)
54
- };
93
+ // Increment refcount.
94
+ await refcountsPartition.put(dataCid, textEncoder.encode(JSON.stringify({
95
+ count: refcountData.count + 1,
96
+ dataSize,
97
+ })));
98
+
99
+ return { dataSize };
55
100
  }
56
101
 
57
102
  public async get(tenant: string, recordId: string, dataCid: string): Promise<DataStoreGetResult | undefined> {
58
- const blockstoreForData = await this.getBlockstoreForStoringData(tenant, recordId, dataCid);
103
+ // Check ref exists.
104
+ const refsPartition = await this.getRefsPartition(tenant, recordId);
105
+ const rawRef = await refsPartition.get(dataCid);
106
+ if (!rawRef) {
107
+ return undefined;
108
+ }
109
+
110
+ const { dataSize } = JSON.parse(textDecoder.decode(rawRef)) as { dataSize: number };
59
111
 
60
- const exists = await blockstoreForData.has(dataCid);
112
+ // Export from the shared blocks partition.
113
+ const blocksPartition = await this.getBlocksPartition(dataCid);
114
+ const exists = await blocksPartition.has(dataCid);
61
115
  if (!exists) {
62
116
  return undefined;
63
117
  }
64
118
 
65
- // data is chunked into dag-pb unixfs blocks. re-inflate the chunks.
66
- const dataDagRoot = await exporter(dataCid, blockstoreForData);
119
+ // Data is chunked into DAG-PB UnixFS blocks. Re-inflate the chunks.
120
+ const dataDagRoot = await exporter(dataCid, blocksPartition);
67
121
  const contentIterator = dataDagRoot.content();
68
122
 
69
123
  const dataStream = new ReadableStream<Uint8Array>({
@@ -77,21 +131,42 @@ export class DataStoreLevel implements DataStore {
77
131
  }
78
132
  });
79
133
 
80
- let dataSize = dataDagRoot.size;
134
+ return { dataSize, dataStream };
135
+ }
81
136
 
82
- if (dataDagRoot.type === 'file' || dataDagRoot.type === 'directory') {
83
- dataSize = dataDagRoot.unixfs.fileSize();
137
+ public async delete(tenant: string, recordId: string, dataCid: string): Promise<void> {
138
+ // Check ref exists.
139
+ const refsPartition = await this.getRefsPartition(tenant, recordId);
140
+ const rawRef = await refsPartition.get(dataCid);
141
+ if (!rawRef) {
142
+ return;
84
143
  }
85
144
 
86
- return {
87
- dataSize: Number(dataSize),
88
- dataStream,
89
- };
90
- }
145
+ // Remove ref.
146
+ await refsPartition.delete(dataCid);
91
147
 
92
- public async delete(tenant: string, recordId: string, dataCid: string): Promise<void> {
93
- const blockstoreForData = await this.getBlockstoreForStoringData(tenant, recordId, dataCid);
94
- await blockstoreForData.clear();
148
+ // Decrement refcount and GC blocks if this was the last ref.
149
+ const refcountsPartition = await this.getRefcountsPartition();
150
+ const rawRefcount = await refcountsPartition.get(dataCid);
151
+ if (!rawRefcount) {
152
+ return;
153
+ }
154
+
155
+ const refcountData = JSON.parse(textDecoder.decode(rawRefcount)) as { count: number; dataSize: number };
156
+ const newCount = refcountData.count - 1;
157
+
158
+ if (newCount <= 0) {
159
+ // Last reference removed — garbage-collect blocks and refcount entry.
160
+ const blocksPartition = await this.getBlocksPartition(dataCid);
161
+ await blocksPartition.clear();
162
+ await refcountsPartition.delete(dataCid);
163
+ } else {
164
+ // Other references remain — update the count.
165
+ await refcountsPartition.put(dataCid, textEncoder.encode(JSON.stringify({
166
+ count : newCount,
167
+ dataSize : refcountData.dataSize,
168
+ })));
169
+ }
95
170
  }
96
171
 
97
172
  /**
@@ -102,15 +177,30 @@ export class DataStoreLevel implements DataStore {
102
177
  }
103
178
 
104
179
  /**
105
- * Gets the blockstore used for storing data for the given `tenant -> `recordId` -> `dataCid`.
180
+ * Gets the refs sublevel for the given tenant and recordId.
181
+ * Caller uses `dataCid` as the key within the returned partition.
182
+ */
183
+ private async getRefsPartition(tenant: string, recordId: string): Promise<LevelWrapper<Uint8Array>> {
184
+ const refsRoot = await this.blockstore.db.partition('refs');
185
+ const tenantPartition = await refsRoot.partition(tenant);
186
+ return tenantPartition.partition(recordId);
187
+ }
188
+
189
+ /**
190
+ * Gets the shared blocks sublevel for the given dataCid.
191
+ * Used as a Blockstore for ipfs-unixfs-importer/exporter.
192
+ */
193
+ private async getBlocksPartition(dataCid: string): Promise<BlockstoreLevel> {
194
+ const blocksRoot = await this.blockstore.partition('blocks');
195
+ return blocksRoot.partition(dataCid);
196
+ }
197
+
198
+ /**
199
+ * Gets the refcounts sublevel.
200
+ * Key: `dataCid` → JSON `{ count, dataSize }`.
106
201
  */
107
- private async getBlockstoreForStoringData(tenant: string, recordId: string, dataCid: string): Promise<BlockstoreLevel> {
108
- const dataPartitionName = 'data';
109
- const blockstoreForData = await this.blockstore.partition(dataPartitionName);
110
- const blockstoreOfGivenTenant = await blockstoreForData.partition(tenant);
111
- const blockstoreOfGivenRecordId = await blockstoreOfGivenTenant.partition(recordId);
112
- const blockstoreOfGivenDataCidOfRecordId = await blockstoreOfGivenRecordId.partition(dataCid);
113
- return blockstoreOfGivenDataCidOfRecordId;
202
+ private async getRefcountsPartition(): Promise<LevelWrapper<Uint8Array>> {
203
+ return this.blockstore.db.partition('refcounts');
114
204
  }
115
205
 
116
206
  }
@@ -118,4 +208,4 @@ export class DataStoreLevel implements DataStore {
118
208
  export type DataStoreLevelConfig = {
119
209
  blockstoreLocation?: string,
120
210
  createLevelDatabase?: typeof createLevelDatabase,
121
- };
211
+ };