@enbox/dwn-sdk-js 0.0.7 → 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 (351) 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 +761 -909
  4. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  5. package/dist/esm/src/core/constants.js +11 -0
  6. package/dist/esm/src/core/constants.js.map +1 -0
  7. package/dist/esm/src/core/core-protocol.js +44 -0
  8. package/dist/esm/src/core/core-protocol.js.map +1 -0
  9. package/dist/esm/src/core/dwn-error.js +9 -12
  10. package/dist/esm/src/core/dwn-error.js.map +1 -1
  11. package/dist/esm/src/core/grant-authorization.js +16 -3
  12. package/dist/esm/src/core/grant-authorization.js.map +1 -1
  13. package/dist/esm/src/core/protocol-authorization-validation.js +67 -0
  14. package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
  15. package/dist/esm/src/core/protocol-authorization.js +51 -30
  16. package/dist/esm/src/core/protocol-authorization.js.map +1 -1
  17. package/dist/esm/src/core/records-grant-authorization.js +6 -8
  18. package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
  19. package/dist/esm/src/dwn.js +42 -18
  20. package/dist/esm/src/dwn.js.map +1 -1
  21. package/dist/esm/src/event-stream/event-emitter-event-log.js +204 -0
  22. package/dist/esm/src/event-stream/event-emitter-event-log.js.map +1 -0
  23. package/dist/esm/src/handlers/messages-read.js +7 -11
  24. package/dist/esm/src/handlers/messages-read.js.map +1 -1
  25. package/dist/esm/src/handlers/messages-subscribe.js +22 -24
  26. package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
  27. package/dist/esm/src/handlers/messages-sync.js +11 -15
  28. package/dist/esm/src/handlers/messages-sync.js.map +1 -1
  29. package/dist/esm/src/handlers/protocols-configure.js +37 -27
  30. package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
  31. package/dist/esm/src/handlers/protocols-query.js +7 -11
  32. package/dist/esm/src/handlers/protocols-query.js.map +1 -1
  33. package/dist/esm/src/handlers/records-count.js +10 -12
  34. package/dist/esm/src/handlers/records-count.js.map +1 -1
  35. package/dist/esm/src/handlers/records-delete.js +10 -18
  36. package/dist/esm/src/handlers/records-delete.js.map +1 -1
  37. package/dist/esm/src/handlers/records-query.js +11 -15
  38. package/dist/esm/src/handlers/records-query.js.map +1 -1
  39. package/dist/esm/src/handlers/records-read.js +31 -26
  40. package/dist/esm/src/handlers/records-read.js.map +1 -1
  41. package/dist/esm/src/handlers/records-subscribe.js +39 -26
  42. package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
  43. package/dist/esm/src/handlers/records-write.js +47 -105
  44. package/dist/esm/src/handlers/records-write.js.map +1 -1
  45. package/dist/esm/src/index.js +5 -2
  46. package/dist/esm/src/index.js.map +1 -1
  47. package/dist/esm/src/interfaces/messages-subscribe.js +1 -0
  48. package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
  49. package/dist/esm/src/interfaces/protocols-configure.js +25 -3
  50. package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
  51. package/dist/esm/src/interfaces/records-count.js +1 -1
  52. package/dist/esm/src/interfaces/records-count.js.map +1 -1
  53. package/dist/esm/src/interfaces/records-delete.js +1 -1
  54. package/dist/esm/src/interfaces/records-delete.js.map +1 -1
  55. package/dist/esm/src/interfaces/records-query.js +1 -1
  56. package/dist/esm/src/interfaces/records-query.js.map +1 -1
  57. package/dist/esm/src/interfaces/records-read.js +1 -1
  58. package/dist/esm/src/interfaces/records-read.js.map +1 -1
  59. package/dist/esm/src/interfaces/records-subscribe.js +2 -1
  60. package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
  61. package/dist/esm/src/interfaces/records-write-signing.js +1 -12
  62. package/dist/esm/src/interfaces/records-write-signing.js.map +1 -1
  63. package/dist/esm/src/interfaces/records-write.js +22 -41
  64. package/dist/esm/src/interfaces/records-write.js.map +1 -1
  65. package/dist/esm/src/protocols/permission-grant.js +1 -1
  66. package/dist/esm/src/protocols/permission-grant.js.map +1 -1
  67. package/dist/esm/src/protocols/permission-request.js +1 -1
  68. package/dist/esm/src/protocols/permission-request.js.map +1 -1
  69. package/dist/esm/src/protocols/permissions.js +113 -5
  70. package/dist/esm/src/protocols/permissions.js.map +1 -1
  71. package/dist/esm/src/state-index/state-index-level.js +5 -7
  72. package/dist/esm/src/state-index/state-index-level.js.map +1 -1
  73. package/dist/esm/src/store/data-store-level.js +110 -33
  74. package/dist/esm/src/store/data-store-level.js.map +1 -1
  75. package/dist/esm/src/store/index-level.js +42 -32
  76. package/dist/esm/src/store/index-level.js.map +1 -1
  77. package/dist/esm/src/store/storage-controller.js +6 -6
  78. package/dist/esm/src/store/storage-controller.js.map +1 -1
  79. package/dist/esm/src/types/permission-types.js.map +1 -1
  80. package/dist/esm/src/types/protocols-types.js +10 -0
  81. package/dist/esm/src/types/protocols-types.js.map +1 -1
  82. package/dist/esm/src/types/records-types.js.map +1 -1
  83. package/dist/esm/src/utils/hd-key.js +0 -8
  84. package/dist/esm/src/utils/hd-key.js.map +1 -1
  85. package/dist/esm/src/utils/messages.js +16 -34
  86. package/dist/esm/src/utils/messages.js.map +1 -1
  87. package/dist/esm/src/utils/records.js +5 -43
  88. package/dist/esm/src/utils/records.js.map +1 -1
  89. package/dist/esm/tests/core/protocol-authorization.spec.js +2 -1
  90. package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
  91. package/dist/esm/tests/dwn.spec.js +32 -43
  92. package/dist/esm/tests/dwn.spec.js.map +1 -1
  93. package/dist/esm/tests/event-emitter-event-log.spec.js +305 -0
  94. package/dist/esm/tests/event-emitter-event-log.spec.js.map +1 -0
  95. package/dist/esm/tests/features/author-delegated-grant.spec.js +14 -7
  96. package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
  97. package/dist/esm/tests/features/owner-delegated-grant.spec.js +9 -5
  98. package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
  99. package/dist/esm/tests/features/owner-signature.spec.js +14 -7
  100. package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
  101. package/dist/esm/tests/features/permissions.spec.js +12 -12
  102. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  103. package/dist/esm/tests/features/protocol-composition.spec.js +636 -5
  104. package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
  105. package/dist/esm/tests/features/protocol-create-action.spec.js +4 -4
  106. package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
  107. package/dist/esm/tests/features/protocol-delete-action.spec.js +7 -7
  108. package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
  109. package/dist/esm/tests/features/protocol-update-action.spec.js +4 -4
  110. package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
  111. package/dist/esm/tests/features/records-immutable.spec.js +315 -0
  112. package/dist/esm/tests/features/records-immutable.spec.js.map +1 -0
  113. package/dist/esm/tests/features/records-prune.spec.js +4 -4
  114. package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
  115. package/dist/esm/tests/features/records-record-limit.spec.js +542 -0
  116. package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -0
  117. package/dist/esm/tests/features/records-tags.spec.js +16 -4
  118. package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
  119. package/dist/esm/tests/features/resumable-tasks.spec.js +7 -8
  120. package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
  121. package/dist/esm/tests/handlers/messages-read.spec.js +11 -5
  122. package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
  123. package/dist/esm/tests/handlers/messages-subscribe.spec.js +169 -22
  124. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  125. package/dist/esm/tests/handlers/messages-sync.spec.js +103 -21
  126. package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
  127. package/dist/esm/tests/handlers/protocols-configure.spec.js +5 -5
  128. package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
  129. package/dist/esm/tests/handlers/protocols-query.spec.js +5 -5
  130. package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
  131. package/dist/esm/tests/handlers/records-count.spec.js +9 -4
  132. package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
  133. package/dist/esm/tests/handlers/records-delete.spec.js +24 -25
  134. package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
  135. package/dist/esm/tests/handlers/records-query.spec.js +68 -9
  136. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  137. package/dist/esm/tests/handlers/records-read.spec.js +24 -138
  138. package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
  139. package/dist/esm/tests/handlers/records-subscribe.spec.js +175 -35
  140. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  141. package/dist/esm/tests/handlers/records-write.spec.js +173 -72
  142. package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
  143. package/dist/esm/tests/interfaces/records-write.spec.js +52 -68
  144. package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
  145. package/dist/esm/tests/protocols/permission-grant.spec.js +6 -6
  146. package/dist/esm/tests/protocols/permission-grant.spec.js.map +1 -1
  147. package/dist/esm/tests/protocols/permission-request.spec.js +4 -4
  148. package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
  149. package/dist/esm/tests/protocols/permissions.spec.js +4 -4
  150. package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
  151. package/dist/esm/tests/scenarios/aggregator.spec.js +4 -4
  152. package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
  153. package/dist/esm/tests/scenarios/deleted-record.spec.js +350 -5
  154. package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
  155. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +4 -4
  156. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
  157. package/dist/esm/tests/scenarios/nested-roles.spec.js +4 -4
  158. package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
  159. package/dist/esm/tests/scenarios/subscriptions.spec.js +93 -40
  160. package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
  161. package/dist/esm/tests/store/data-store-level.spec.js +102 -41
  162. package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
  163. package/dist/esm/tests/test-event-stream.js +12 -13
  164. package/dist/esm/tests/test-event-stream.js.map +1 -1
  165. package/dist/esm/tests/test-suite.js +6 -4
  166. package/dist/esm/tests/test-suite.js.map +1 -1
  167. package/dist/esm/tests/utils/messages.spec.js +12 -5
  168. package/dist/esm/tests/utils/messages.spec.js.map +1 -1
  169. package/dist/esm/tests/utils/records.spec.js +8 -12
  170. package/dist/esm/tests/utils/records.spec.js.map +1 -1
  171. package/dist/esm/tests/utils/test-data-generator.js +35 -2
  172. package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
  173. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +37 -8
  174. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
  175. package/dist/types/generated/precompiled-validators.d.ts +49 -40
  176. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  177. package/dist/types/src/core/constants.d.ts +11 -0
  178. package/dist/types/src/core/constants.d.ts.map +1 -0
  179. package/dist/types/src/core/core-protocol.d.ts +89 -0
  180. package/dist/types/src/core/core-protocol.d.ts.map +1 -0
  181. package/dist/types/src/core/dwn-error.d.ts +9 -12
  182. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  183. package/dist/types/src/core/grant-authorization.d.ts +6 -2
  184. package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
  185. package/dist/types/src/core/protocol-authorization-validation.d.ts +21 -0
  186. package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
  187. package/dist/types/src/core/protocol-authorization.d.ts +19 -11
  188. package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
  189. package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
  190. package/dist/types/src/dwn.d.ts +19 -7
  191. package/dist/types/src/dwn.d.ts.map +1 -1
  192. package/dist/types/src/event-stream/event-emitter-event-log.d.ts +50 -0
  193. package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +1 -0
  194. package/dist/types/src/handlers/messages-read.d.ts +3 -8
  195. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  196. package/dist/types/src/handlers/messages-subscribe.d.ts +6 -10
  197. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  198. package/dist/types/src/handlers/messages-sync.d.ts +3 -8
  199. package/dist/types/src/handlers/messages-sync.d.ts.map +1 -1
  200. package/dist/types/src/handlers/protocols-configure.d.ts +3 -10
  201. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  202. package/dist/types/src/handlers/protocols-query.d.ts +3 -8
  203. package/dist/types/src/handlers/protocols-query.d.ts.map +1 -1
  204. package/dist/types/src/handlers/records-count.d.ts +3 -6
  205. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  206. package/dist/types/src/handlers/records-delete.d.ts +3 -8
  207. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  208. package/dist/types/src/handlers/records-query.d.ts +3 -8
  209. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  210. package/dist/types/src/handlers/records-read.d.ts +3 -8
  211. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  212. package/dist/types/src/handlers/records-subscribe.d.ts +8 -10
  213. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  214. package/dist/types/src/handlers/records-write.d.ts +4 -25
  215. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  216. package/dist/types/src/index.d.ts +8 -4
  217. package/dist/types/src/index.d.ts.map +1 -1
  218. package/dist/types/src/interfaces/messages-subscribe.d.ts +5 -0
  219. package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
  220. package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
  221. package/dist/types/src/interfaces/records-subscribe.d.ts +5 -0
  222. package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
  223. package/dist/types/src/interfaces/records-write-signing.d.ts +3 -4
  224. package/dist/types/src/interfaces/records-write-signing.d.ts.map +1 -1
  225. package/dist/types/src/interfaces/records-write.d.ts +5 -11
  226. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  227. package/dist/types/src/protocols/permission-grant.d.ts +1 -1
  228. package/dist/types/src/protocols/permission-grant.d.ts.map +1 -1
  229. package/dist/types/src/protocols/permission-request.d.ts +1 -1
  230. package/dist/types/src/protocols/permission-request.d.ts.map +1 -1
  231. package/dist/types/src/protocols/permissions.d.ts +40 -3
  232. package/dist/types/src/protocols/permissions.d.ts.map +1 -1
  233. package/dist/types/src/state-index/state-index-level.d.ts.map +1 -1
  234. package/dist/types/src/store/data-store-level.d.ts +20 -4
  235. package/dist/types/src/store/data-store-level.d.ts.map +1 -1
  236. package/dist/types/src/store/index-level.d.ts +4 -0
  237. package/dist/types/src/store/index-level.d.ts.map +1 -1
  238. package/dist/types/src/store/storage-controller.d.ts +4 -4
  239. package/dist/types/src/store/storage-controller.d.ts.map +1 -1
  240. package/dist/types/src/types/message-types.d.ts +3 -3
  241. package/dist/types/src/types/message-types.d.ts.map +1 -1
  242. package/dist/types/src/types/messages-types.d.ts +12 -3
  243. package/dist/types/src/types/messages-types.d.ts.map +1 -1
  244. package/dist/types/src/types/method-handler.d.ts +24 -3
  245. package/dist/types/src/types/method-handler.d.ts.map +1 -1
  246. package/dist/types/src/types/permission-types.d.ts +7 -0
  247. package/dist/types/src/types/permission-types.d.ts.map +1 -1
  248. package/dist/types/src/types/protocols-types.d.ts +41 -1
  249. package/dist/types/src/types/protocols-types.d.ts.map +1 -1
  250. package/dist/types/src/types/records-types.d.ts +16 -6
  251. package/dist/types/src/types/records-types.d.ts.map +1 -1
  252. package/dist/types/src/types/subscriptions.d.ts +151 -13
  253. package/dist/types/src/types/subscriptions.d.ts.map +1 -1
  254. package/dist/types/src/utils/hd-key.d.ts +1 -9
  255. package/dist/types/src/utils/hd-key.d.ts.map +1 -1
  256. package/dist/types/src/utils/messages.d.ts +7 -5
  257. package/dist/types/src/utils/messages.d.ts.map +1 -1
  258. package/dist/types/src/utils/records.d.ts +1 -11
  259. package/dist/types/src/utils/records.d.ts.map +1 -1
  260. package/dist/types/tests/dwn.spec.d.ts.map +1 -1
  261. package/dist/types/tests/event-emitter-event-log.spec.d.ts +2 -0
  262. package/dist/types/tests/event-emitter-event-log.spec.d.ts.map +1 -0
  263. package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -1
  264. package/dist/types/tests/features/owner-delegated-grant.spec.d.ts.map +1 -1
  265. package/dist/types/tests/features/owner-signature.spec.d.ts.map +1 -1
  266. package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -1
  267. package/dist/types/tests/features/records-immutable.spec.d.ts +2 -0
  268. package/dist/types/tests/features/records-immutable.spec.d.ts.map +1 -0
  269. package/dist/types/tests/features/records-record-limit.spec.d.ts +2 -0
  270. package/dist/types/tests/features/records-record-limit.spec.d.ts.map +1 -0
  271. package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -1
  272. package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -1
  273. package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
  274. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  275. package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -1
  276. package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
  277. package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
  278. package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
  279. package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
  280. package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
  281. package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
  282. package/dist/types/tests/scenarios/deleted-record.spec.d.ts.map +1 -1
  283. package/dist/types/tests/scenarios/subscriptions.spec.d.ts.map +1 -1
  284. package/dist/types/tests/test-event-stream.d.ts +11 -12
  285. package/dist/types/tests/test-event-stream.d.ts.map +1 -1
  286. package/dist/types/tests/test-suite.d.ts +2 -2
  287. package/dist/types/tests/test-suite.d.ts.map +1 -1
  288. package/dist/types/tests/utils/test-data-generator.d.ts +18 -0
  289. package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
  290. package/package.json +5 -4
  291. package/src/core/constants.ts +11 -0
  292. package/src/core/core-protocol.ts +129 -0
  293. package/src/core/dwn-error.ts +15 -12
  294. package/src/core/grant-authorization.ts +20 -3
  295. package/src/core/protocol-authorization-validation.ts +96 -0
  296. package/src/core/protocol-authorization.ts +67 -23
  297. package/src/core/records-grant-authorization.ts +6 -8
  298. package/src/dwn.ts +58 -73
  299. package/src/event-stream/event-emitter-event-log.ts +283 -0
  300. package/src/handlers/messages-read.ts +8 -9
  301. package/src/handlers/messages-subscribe.ts +24 -28
  302. package/src/handlers/messages-sync.ts +10 -16
  303. package/src/handlers/protocols-configure.ts +47 -32
  304. package/src/handlers/protocols-query.ts +6 -9
  305. package/src/handlers/records-count.ts +11 -10
  306. package/src/handlers/records-delete.ts +12 -21
  307. package/src/handlers/records-query.ts +12 -12
  308. package/src/handlers/records-read.ts +34 -22
  309. package/src/handlers/records-subscribe.ts +47 -26
  310. package/src/handlers/records-write.ts +47 -120
  311. package/src/index.ts +9 -5
  312. package/src/interfaces/messages-subscribe.ts +7 -1
  313. package/src/interfaces/protocols-configure.ts +40 -3
  314. package/src/interfaces/records-count.ts +1 -1
  315. package/src/interfaces/records-delete.ts +1 -1
  316. package/src/interfaces/records-query.ts +1 -1
  317. package/src/interfaces/records-read.ts +1 -1
  318. package/src/interfaces/records-subscribe.ts +8 -1
  319. package/src/interfaces/records-write-signing.ts +2 -22
  320. package/src/interfaces/records-write.ts +25 -48
  321. package/src/protocols/permission-grant.ts +1 -1
  322. package/src/protocols/permission-request.ts +1 -1
  323. package/src/protocols/permissions.ts +148 -6
  324. package/src/state-index/state-index-level.ts +5 -7
  325. package/src/store/data-store-level.ts +124 -34
  326. package/src/store/index-level.ts +44 -35
  327. package/src/store/storage-controller.ts +11 -11
  328. package/src/types/message-types.ts +3 -3
  329. package/src/types/messages-types.ts +12 -3
  330. package/src/types/method-handler.ts +26 -4
  331. package/src/types/mitt.d.ts +28 -0
  332. package/src/types/permission-types.ts +7 -0
  333. package/src/types/protocols-types.ts +46 -0
  334. package/src/types/records-types.ts +16 -6
  335. package/src/types/subscriptions.ts +178 -14
  336. package/src/utils/hd-key.ts +0 -9
  337. package/src/utils/messages.ts +17 -37
  338. package/src/utils/records.ts +7 -58
  339. package/dist/esm/src/event-stream/event-emitter-stream.js +0 -46
  340. package/dist/esm/src/event-stream/event-emitter-stream.js.map +0 -1
  341. package/dist/esm/tests/event-stream/event-emitter-stream.spec.js +0 -68
  342. package/dist/esm/tests/event-stream/event-emitter-stream.spec.js.map +0 -1
  343. package/dist/esm/tests/event-stream/event-stream.spec.js +0 -114
  344. package/dist/esm/tests/event-stream/event-stream.spec.js.map +0 -1
  345. package/dist/types/src/event-stream/event-emitter-stream.d.ts +0 -23
  346. package/dist/types/src/event-stream/event-emitter-stream.d.ts.map +0 -1
  347. package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts +0 -2
  348. package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts.map +0 -1
  349. package/dist/types/tests/event-stream/event-stream.spec.d.ts +0 -2
  350. package/dist/types/tests/event-stream/event-stream.spec.d.ts.map +0 -1
  351. package/src/event-stream/event-emitter-stream.ts +0 -69
@@ -6,13 +6,13 @@ import { Jws } from '../../src/utils/jws.js';
6
6
  import { Protocols } from '../../src/utils/protocols.js';
7
7
  import { Records } from '../../src/utils/records.js';
8
8
  import { TestDataGenerator } from '../utils/test-data-generator.js';
9
- import { TestEventStream } from '../test-event-stream.js';
9
+ import { TestEventLog } from '../test-event-stream.js';
10
10
  import { TestStores } from '../test-stores.js';
11
11
  import { TestStubGenerator } from '../utils/test-stub-generator.js';
12
12
  import { X25519 } from '@enbox/crypto';
13
13
  import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'bun:test';
14
14
  import { DidKey, UniversalResolver } from '@enbox/dids';
15
- import { DwnErrorCode, Message, ProtocolsConfigure, RecordsDelete, RecordsQuery, RecordsRead, Time } from '../../src/index.js';
15
+ import { DwnErrorCode, Message, ProtocolsConfigure, RecordsCount, RecordsDelete, RecordsQuery, RecordsRead, RecordsSubscribe, Time } from '../../src/index.js';
16
16
  import { HdKey, KeyDerivationScheme } from '../../src/utils/hd-key.js';
17
17
  /**
18
18
  * Tests for protocol composition using `uses` + `$ref`.
@@ -24,7 +24,7 @@ export function testProtocolComposition() {
24
24
  let dataStore;
25
25
  let resumableTaskStore;
26
26
  let stateIndex;
27
- let eventStream;
27
+ let eventLog;
28
28
  let dwn;
29
29
  beforeAll(async () => {
30
30
  didResolver = new UniversalResolver({ didResolvers: [DidKey] });
@@ -33,8 +33,8 @@ export function testProtocolComposition() {
33
33
  dataStore = stores.dataStore;
34
34
  resumableTaskStore = stores.resumableTaskStore;
35
35
  stateIndex = stores.stateIndex;
36
- eventStream = TestEventStream.get();
37
- dwn = await Dwn.create({ didResolver, messageStore, dataStore, stateIndex, eventStream, resumableTaskStore });
36
+ eventLog = TestEventLog.get();
37
+ dwn = await Dwn.create({ didResolver, messageStore, dataStore, stateIndex, eventLog, resumableTaskStore });
38
38
  });
39
39
  beforeEach(async () => {
40
40
  sinon.restore();
@@ -1246,6 +1246,637 @@ export function testProtocolComposition() {
1246
1246
  });
1247
1247
  });
1248
1248
  // =========================================================================
1249
+ // Multi-level composition rejection (#299)
1250
+ // =========================================================================
1251
+ describe('multi-level composition rejection', () => {
1252
+ it('should reject `$ref` that targets a node which is itself a `$ref` composition point', async () => {
1253
+ const alice = await TestDataGenerator.generateDidKeyPersona();
1254
+ // Protocol B uses Protocol A (threads)
1255
+ const protocolB = {
1256
+ protocol: 'https://protocol-b.example.com',
1257
+ published: true,
1258
+ uses: { threads: 'https://threads.example.com' },
1259
+ types: {
1260
+ annotation: { schema: 'https://protocol-b.example.com/schemas/annotation', dataFormats: ['application/json'] },
1261
+ },
1262
+ structure: {
1263
+ thread: {
1264
+ $ref: 'threads:thread',
1265
+ annotation: {
1266
+ $actions: [{ who: 'anyone', can: ['create', 'read'] }],
1267
+ },
1268
+ },
1269
+ },
1270
+ };
1271
+ // Protocol C uses Protocol B — attempts to $ref through B's $ref node
1272
+ const protocolC = {
1273
+ protocol: 'https://protocol-c.example.com',
1274
+ published: true,
1275
+ uses: { b: 'https://protocol-b.example.com' },
1276
+ types: {
1277
+ tag: { schema: 'https://protocol-c.example.com/schemas/tag', dataFormats: ['application/json'] },
1278
+ },
1279
+ structure: {
1280
+ thread: {
1281
+ $ref: 'b:thread', // 'thread' in protocol B IS a $ref node — multi-level, should be rejected
1282
+ tag: {
1283
+ $actions: [{ who: 'anyone', can: ['create', 'read'] }],
1284
+ },
1285
+ },
1286
+ },
1287
+ };
1288
+ // Install threads protocol (protocol A)
1289
+ const threadsConfigure = await ProtocolsConfigure.create({
1290
+ definition: threadsProtocol,
1291
+ signer: Jws.createSigner(alice),
1292
+ });
1293
+ await dwn.processMessage(alice.did, threadsConfigure.message);
1294
+ // Install protocol B (depends on threads)
1295
+ const bConfigure = await ProtocolsConfigure.create({
1296
+ definition: protocolB,
1297
+ signer: Jws.createSigner(alice),
1298
+ });
1299
+ const bReply = await dwn.processMessage(alice.did, bConfigure.message);
1300
+ expect(bReply.status.code).toBe(202);
1301
+ // Install protocol C (depends on B) — should be REJECTED
1302
+ const cConfigure = await ProtocolsConfigure.create({
1303
+ definition: protocolC,
1304
+ signer: Jws.createSigner(alice),
1305
+ });
1306
+ const cReply = await dwn.processMessage(alice.did, cConfigure.message);
1307
+ expect(cReply.status.code).toBe(400);
1308
+ expect(cReply.status.detail).toContain(DwnErrorCode.ProtocolsConfigureInvalidRefTargetThroughRef);
1309
+ });
1310
+ it('should reject `$ref` that targets a multi-segment path traversing through an intermediate `$ref` node', async () => {
1311
+ const alice = await TestDataGenerator.generateDidKeyPersona();
1312
+ // Protocol B uses threads — has $ref at 'thread' and local children under it
1313
+ const protocolB = {
1314
+ protocol: 'https://protocol-b.example.com',
1315
+ published: true,
1316
+ uses: { threads: 'https://threads.example.com' },
1317
+ types: {
1318
+ annotation: { schema: 'https://protocol-b.example.com/schemas/annotation', dataFormats: ['application/json'] },
1319
+ },
1320
+ structure: {
1321
+ thread: {
1322
+ $ref: 'threads:thread',
1323
+ annotation: {
1324
+ $actions: [{ who: 'anyone', can: ['create', 'read'] }],
1325
+ },
1326
+ },
1327
+ },
1328
+ };
1329
+ // Protocol C references a path that traverses through B's $ref node: 'thread/annotation'
1330
+ // 'thread' is a $ref node in protocol B, so this should be rejected even though 'annotation' is a real node
1331
+ const protocolC = {
1332
+ protocol: 'https://protocol-c.example.com',
1333
+ published: true,
1334
+ uses: { b: 'https://protocol-b.example.com' },
1335
+ types: {
1336
+ tag: { schema: 'https://protocol-c.example.com/schemas/tag', dataFormats: ['application/json'] },
1337
+ },
1338
+ structure: {
1339
+ annotation: {
1340
+ $ref: 'b:thread/annotation', // traverses through 'thread' which is a $ref node
1341
+ tag: {
1342
+ $actions: [{ who: 'anyone', can: ['create', 'read'] }],
1343
+ },
1344
+ },
1345
+ },
1346
+ };
1347
+ // Install threads protocol
1348
+ const threadsConfigure = await ProtocolsConfigure.create({
1349
+ definition: threadsProtocol,
1350
+ signer: Jws.createSigner(alice),
1351
+ });
1352
+ await dwn.processMessage(alice.did, threadsConfigure.message);
1353
+ // Install protocol B
1354
+ const bConfigure = await ProtocolsConfigure.create({
1355
+ definition: protocolB,
1356
+ signer: Jws.createSigner(alice),
1357
+ });
1358
+ const bReply = await dwn.processMessage(alice.did, bConfigure.message);
1359
+ expect(bReply.status.code).toBe(202);
1360
+ // Install protocol C — should be REJECTED because 'thread' (intermediate) is a $ref node
1361
+ const cConfigure = await ProtocolsConfigure.create({
1362
+ definition: protocolC,
1363
+ signer: Jws.createSigner(alice),
1364
+ });
1365
+ const cReply = await dwn.processMessage(alice.did, cConfigure.message);
1366
+ expect(cReply.status.code).toBe(400);
1367
+ expect(cReply.status.detail).toContain(DwnErrorCode.ProtocolsConfigureInvalidRefTargetThroughRef);
1368
+ });
1369
+ it('should accept `$ref` to a node that does NOT have a `$ref` directive', async () => {
1370
+ const alice = await TestDataGenerator.generateDidKeyPersona();
1371
+ // Protocol B has a normal (non-$ref) 'item' type with children
1372
+ const protocolB = {
1373
+ protocol: 'https://protocol-b.example.com',
1374
+ published: true,
1375
+ types: {
1376
+ item: { schema: 'https://protocol-b.example.com/schemas/item', dataFormats: ['application/json'] },
1377
+ sub: { schema: 'https://protocol-b.example.com/schemas/sub', dataFormats: ['application/json'] },
1378
+ },
1379
+ structure: {
1380
+ item: {
1381
+ $actions: [{ who: 'anyone', can: ['create', 'read'] }],
1382
+ sub: {
1383
+ $actions: [{ who: 'anyone', can: ['create', 'read'] }],
1384
+ },
1385
+ },
1386
+ },
1387
+ };
1388
+ // Protocol C references 'item' in B — this is single-level composition (no $ref in target), should succeed
1389
+ const protocolC = {
1390
+ protocol: 'https://protocol-c.example.com',
1391
+ published: true,
1392
+ uses: { b: 'https://protocol-b.example.com' },
1393
+ types: {
1394
+ extra: { schema: 'https://protocol-c.example.com/schemas/extra', dataFormats: ['application/json'] },
1395
+ },
1396
+ structure: {
1397
+ item: {
1398
+ $ref: 'b:item',
1399
+ extra: {
1400
+ $actions: [{ who: 'anyone', can: ['create', 'read'] }],
1401
+ },
1402
+ },
1403
+ },
1404
+ };
1405
+ // Install protocol B
1406
+ const bConfigure = await ProtocolsConfigure.create({
1407
+ definition: protocolB,
1408
+ signer: Jws.createSigner(alice),
1409
+ });
1410
+ const bReply = await dwn.processMessage(alice.did, bConfigure.message);
1411
+ expect(bReply.status.code).toBe(202);
1412
+ // Install protocol C — should SUCCEED
1413
+ const cConfigure = await ProtocolsConfigure.create({
1414
+ definition: protocolC,
1415
+ signer: Jws.createSigner(alice),
1416
+ });
1417
+ const cReply = await dwn.processMessage(alice.did, cConfigure.message);
1418
+ expect(cReply.status.code).toBe(202);
1419
+ });
1420
+ });
1421
+ // =========================================================================
1422
+ // RecordsSubscribe with cross-protocol role
1423
+ // =========================================================================
1424
+ describe('cross-protocol RecordsSubscribe', () => {
1425
+ it('should allow a cross-protocol role holder to subscribe to records in the composing protocol', async () => {
1426
+ const alice = await TestDataGenerator.generateDidKeyPersona();
1427
+ const bob = await TestDataGenerator.generateDidKeyPersona();
1428
+ // Install both protocols on Alice's DWN
1429
+ const threadsConfigure = await ProtocolsConfigure.create({
1430
+ definition: threadsProtocol,
1431
+ signer: Jws.createSigner(alice),
1432
+ });
1433
+ await dwn.processMessage(alice.did, threadsConfigure.message);
1434
+ const commentsConfigure = await ProtocolsConfigure.create({
1435
+ definition: commentsProtocol,
1436
+ signer: Jws.createSigner(alice),
1437
+ });
1438
+ await dwn.processMessage(alice.did, commentsConfigure.message);
1439
+ // Alice creates a thread
1440
+ const threadWrite = await TestDataGenerator.generateRecordsWrite({
1441
+ author: alice,
1442
+ protocol: threadsProtocol.protocol,
1443
+ protocolPath: 'thread',
1444
+ schema: 'https://threads.example.com/schemas/thread',
1445
+ dataFormat: 'application/json',
1446
+ });
1447
+ await dwn.processMessage(alice.did, threadWrite.message, { dataStream: threadWrite.dataStream });
1448
+ const threadContextId = threadWrite.message.contextId;
1449
+ // Alice assigns Bob as a participant
1450
+ const participantWrite = await TestDataGenerator.generateRecordsWrite({
1451
+ author: alice,
1452
+ recipient: bob.did,
1453
+ protocol: threadsProtocol.protocol,
1454
+ protocolPath: 'thread/participant',
1455
+ schema: 'https://threads.example.com/schemas/participant',
1456
+ dataFormat: 'application/json',
1457
+ parentContextId: threadContextId,
1458
+ });
1459
+ await dwn.processMessage(alice.did, participantWrite.message, { dataStream: participantWrite.dataStream });
1460
+ // Bob subscribes to comments using the cross-protocol role
1461
+ const bobSubscribe = await RecordsSubscribe.create({
1462
+ signer: Jws.createSigner(bob),
1463
+ protocolRole: 'threads:thread/participant',
1464
+ filter: {
1465
+ protocol: commentsProtocol.protocol,
1466
+ protocolPath: 'thread/comment',
1467
+ contextId: threadContextId,
1468
+ },
1469
+ });
1470
+ const subReply = await dwn.processMessage(alice.did, bobSubscribe.message, { subscriptionHandler: () => { } });
1471
+ expect(subReply.status.code).toBe(200);
1472
+ expect(subReply.subscription).toBeDefined();
1473
+ // Clean up subscription
1474
+ await subReply.subscription.close();
1475
+ });
1476
+ });
1477
+ // =========================================================================
1478
+ // RecordsCount with cross-protocol role
1479
+ // =========================================================================
1480
+ describe('cross-protocol RecordsCount', () => {
1481
+ it('should allow a cross-protocol role holder to count records in the composing protocol', async () => {
1482
+ const alice = await TestDataGenerator.generateDidKeyPersona();
1483
+ const bob = await TestDataGenerator.generateDidKeyPersona();
1484
+ // Install both protocols on Alice's DWN
1485
+ const threadsConfigure = await ProtocolsConfigure.create({
1486
+ definition: threadsProtocol,
1487
+ signer: Jws.createSigner(alice),
1488
+ });
1489
+ await dwn.processMessage(alice.did, threadsConfigure.message);
1490
+ const commentsConfigure = await ProtocolsConfigure.create({
1491
+ definition: commentsProtocol,
1492
+ signer: Jws.createSigner(alice),
1493
+ });
1494
+ await dwn.processMessage(alice.did, commentsConfigure.message);
1495
+ // Alice creates a thread
1496
+ const threadWrite = await TestDataGenerator.generateRecordsWrite({
1497
+ author: alice,
1498
+ protocol: threadsProtocol.protocol,
1499
+ protocolPath: 'thread',
1500
+ schema: 'https://threads.example.com/schemas/thread',
1501
+ dataFormat: 'application/json',
1502
+ });
1503
+ await dwn.processMessage(alice.did, threadWrite.message, { dataStream: threadWrite.dataStream });
1504
+ const threadContextId = threadWrite.message.contextId;
1505
+ // Alice assigns Bob as a participant
1506
+ const participantWrite = await TestDataGenerator.generateRecordsWrite({
1507
+ author: alice,
1508
+ recipient: bob.did,
1509
+ protocol: threadsProtocol.protocol,
1510
+ protocolPath: 'thread/participant',
1511
+ schema: 'https://threads.example.com/schemas/participant',
1512
+ dataFormat: 'application/json',
1513
+ parentContextId: threadContextId,
1514
+ });
1515
+ await dwn.processMessage(alice.did, participantWrite.message, { dataStream: participantWrite.dataStream });
1516
+ // Alice creates 3 comments
1517
+ for (let i = 0; i < 3; i++) {
1518
+ const commentWrite = await TestDataGenerator.generateRecordsWrite({
1519
+ author: alice,
1520
+ protocol: commentsProtocol.protocol,
1521
+ protocolPath: 'thread/comment',
1522
+ schema: 'https://comments.example.com/schemas/comment',
1523
+ dataFormat: 'application/json',
1524
+ parentContextId: threadContextId,
1525
+ });
1526
+ await dwn.processMessage(alice.did, commentWrite.message, { dataStream: commentWrite.dataStream });
1527
+ }
1528
+ // Bob counts comments using the cross-protocol role
1529
+ const bobCount = await RecordsCount.create({
1530
+ signer: Jws.createSigner(bob),
1531
+ protocolRole: 'threads:thread/participant',
1532
+ filter: {
1533
+ protocol: commentsProtocol.protocol,
1534
+ protocolPath: 'thread/comment',
1535
+ contextId: threadContextId,
1536
+ },
1537
+ });
1538
+ const countReply = await dwn.processMessage(alice.did, bobCount.message);
1539
+ expect(countReply.status.code).toBe(200);
1540
+ expect(countReply.count).toBe(3);
1541
+ });
1542
+ });
1543
+ // =========================================================================
1544
+ // Cross-protocol co-update via role
1545
+ // =========================================================================
1546
+ describe('cross-protocol co-update via role', () => {
1547
+ it('should allow a cross-protocol role holder to co-update records in the composing protocol', async () => {
1548
+ const alice = await TestDataGenerator.generateDidKeyPersona();
1549
+ const bob = await TestDataGenerator.generateDidKeyPersona();
1550
+ // A variant of the comments protocol where participants can also co-update
1551
+ const commentsCoUpdateProtocol = {
1552
+ protocol: 'https://comments-coupdate.example.com',
1553
+ published: true,
1554
+ uses: { threads: 'https://threads.example.com' },
1555
+ types: {
1556
+ comment: { schema: 'https://comments-coupdate.example.com/schemas/comment', dataFormats: ['application/json'] },
1557
+ },
1558
+ structure: {
1559
+ thread: {
1560
+ $ref: 'threads:thread',
1561
+ comment: {
1562
+ $actions: [
1563
+ { who: 'anyone', can: ['create', 'read'] },
1564
+ { role: 'threads:thread/participant', can: ['co-update'] },
1565
+ ],
1566
+ },
1567
+ },
1568
+ },
1569
+ };
1570
+ // Install both protocols on Alice's DWN
1571
+ const threadsConfigure = await ProtocolsConfigure.create({
1572
+ definition: threadsProtocol,
1573
+ signer: Jws.createSigner(alice),
1574
+ });
1575
+ await dwn.processMessage(alice.did, threadsConfigure.message);
1576
+ const commentsConfigure = await ProtocolsConfigure.create({
1577
+ definition: commentsCoUpdateProtocol,
1578
+ signer: Jws.createSigner(alice),
1579
+ });
1580
+ const commentsReply = await dwn.processMessage(alice.did, commentsConfigure.message);
1581
+ expect(commentsReply.status.code).toBe(202);
1582
+ // Alice creates a thread
1583
+ const threadWrite = await TestDataGenerator.generateRecordsWrite({
1584
+ author: alice,
1585
+ protocol: threadsProtocol.protocol,
1586
+ protocolPath: 'thread',
1587
+ schema: 'https://threads.example.com/schemas/thread',
1588
+ dataFormat: 'application/json',
1589
+ });
1590
+ await dwn.processMessage(alice.did, threadWrite.message, { dataStream: threadWrite.dataStream });
1591
+ const threadContextId = threadWrite.message.contextId;
1592
+ // Alice assigns Bob as a participant
1593
+ const participantWrite = await TestDataGenerator.generateRecordsWrite({
1594
+ author: alice,
1595
+ recipient: bob.did,
1596
+ protocol: threadsProtocol.protocol,
1597
+ protocolPath: 'thread/participant',
1598
+ schema: 'https://threads.example.com/schemas/participant',
1599
+ dataFormat: 'application/json',
1600
+ parentContextId: threadContextId,
1601
+ });
1602
+ await dwn.processMessage(alice.did, participantWrite.message, { dataStream: participantWrite.dataStream });
1603
+ // Alice creates a comment (via 'anyone' can 'create')
1604
+ const commentWrite = await TestDataGenerator.generateRecordsWrite({
1605
+ author: alice,
1606
+ protocol: commentsCoUpdateProtocol.protocol,
1607
+ protocolPath: 'thread/comment',
1608
+ schema: 'https://comments-coupdate.example.com/schemas/comment',
1609
+ dataFormat: 'application/json',
1610
+ parentContextId: threadContextId,
1611
+ });
1612
+ await dwn.processMessage(alice.did, commentWrite.message, { dataStream: commentWrite.dataStream });
1613
+ // Bob (participant) co-updates Alice's comment using the cross-protocol role
1614
+ const bobUpdate = await TestDataGenerator.generateFromRecordsWrite({
1615
+ author: bob,
1616
+ existingWrite: commentWrite.recordsWrite,
1617
+ protocolRole: 'threads:thread/participant',
1618
+ });
1619
+ const updateReply = await dwn.processMessage(alice.did, bobUpdate.message, { dataStream: bobUpdate.dataStream });
1620
+ expect(updateReply.status.code).toBe(202);
1621
+ });
1622
+ });
1623
+ // =========================================================================
1624
+ // Query isolation — subscribing to referenced protocol does NOT yield composing protocol events
1625
+ // =========================================================================
1626
+ describe('query isolation between protocols', () => {
1627
+ it('should not return composing protocol records when querying the referenced protocol', async () => {
1628
+ const alice = await TestDataGenerator.generateDidKeyPersona();
1629
+ // Install both protocols
1630
+ const threadsConfigure = await ProtocolsConfigure.create({
1631
+ definition: threadsProtocol,
1632
+ signer: Jws.createSigner(alice),
1633
+ });
1634
+ await dwn.processMessage(alice.did, threadsConfigure.message);
1635
+ const commentsConfigure = await ProtocolsConfigure.create({
1636
+ definition: commentsProtocol,
1637
+ signer: Jws.createSigner(alice),
1638
+ });
1639
+ await dwn.processMessage(alice.did, commentsConfigure.message);
1640
+ // Alice creates a thread in the threads protocol
1641
+ const threadWrite = await TestDataGenerator.generateRecordsWrite({
1642
+ author: alice,
1643
+ protocol: threadsProtocol.protocol,
1644
+ protocolPath: 'thread',
1645
+ schema: 'https://threads.example.com/schemas/thread',
1646
+ dataFormat: 'application/json',
1647
+ });
1648
+ await dwn.processMessage(alice.did, threadWrite.message, { dataStream: threadWrite.dataStream });
1649
+ const threadContextId = threadWrite.message.contextId;
1650
+ // Alice creates comments in the composing protocol
1651
+ const commentWrite = await TestDataGenerator.generateRecordsWrite({
1652
+ author: alice,
1653
+ protocol: commentsProtocol.protocol,
1654
+ protocolPath: 'thread/comment',
1655
+ schema: 'https://comments.example.com/schemas/comment',
1656
+ dataFormat: 'application/json',
1657
+ parentContextId: threadContextId,
1658
+ });
1659
+ await dwn.processMessage(alice.did, commentWrite.message, { dataStream: commentWrite.dataStream });
1660
+ // Query the THREADS protocol for all records — should NOT include the comment
1661
+ const threadsQuery = await RecordsQuery.create({
1662
+ signer: Jws.createSigner(alice),
1663
+ filter: {
1664
+ protocol: threadsProtocol.protocol,
1665
+ },
1666
+ });
1667
+ const threadsQueryReply = await dwn.processMessage(alice.did, threadsQuery.message);
1668
+ expect(threadsQueryReply.status.code).toBe(200);
1669
+ // Only the thread record itself should be returned
1670
+ const threadsRecordIds = threadsQueryReply.entries.map((e) => e.recordId);
1671
+ expect(threadsRecordIds).toContain(threadWrite.message.recordId);
1672
+ expect(threadsRecordIds).not.toContain(commentWrite.message.recordId);
1673
+ // Query the COMMENTS protocol — should include the comment
1674
+ const commentsQuery = await RecordsQuery.create({
1675
+ signer: Jws.createSigner(alice),
1676
+ filter: {
1677
+ protocol: commentsProtocol.protocol,
1678
+ },
1679
+ });
1680
+ const commentsQueryReply = await dwn.processMessage(alice.did, commentsQuery.message);
1681
+ expect(commentsQueryReply.status.code).toBe(200);
1682
+ const commentsRecordIds = commentsQueryReply.entries.map((e) => e.recordId);
1683
+ expect(commentsRecordIds).toContain(commentWrite.message.recordId);
1684
+ expect(commentsRecordIds).not.toContain(threadWrite.message.recordId);
1685
+ });
1686
+ });
1687
+ // =========================================================================
1688
+ // Multiple composing protocols on the same $ref target
1689
+ // =========================================================================
1690
+ describe('multiple composing protocols on the same $ref target', () => {
1691
+ it('should allow two different composing protocols to independently reference the same type in a base protocol', async () => {
1692
+ const alice = await TestDataGenerator.generateDidKeyPersona();
1693
+ // commentsProtocol already references threads:thread
1694
+ // Create a second composing protocol that also references threads:thread
1695
+ const ratingsProtocol = {
1696
+ protocol: 'https://ratings.example.com',
1697
+ published: true,
1698
+ uses: { threads: 'https://threads.example.com' },
1699
+ types: {
1700
+ rating: { schema: 'https://ratings.example.com/schemas/rating', dataFormats: ['application/json'] },
1701
+ },
1702
+ structure: {
1703
+ thread: {
1704
+ $ref: 'threads:thread',
1705
+ rating: {
1706
+ $actions: [
1707
+ { who: 'anyone', can: ['create', 'read'] },
1708
+ ],
1709
+ },
1710
+ },
1711
+ },
1712
+ };
1713
+ // Install threads (base), comments, and ratings
1714
+ const threadsConfigure = await ProtocolsConfigure.create({
1715
+ definition: threadsProtocol,
1716
+ signer: Jws.createSigner(alice),
1717
+ });
1718
+ await dwn.processMessage(alice.did, threadsConfigure.message);
1719
+ const commentsConfigure = await ProtocolsConfigure.create({
1720
+ definition: commentsProtocol,
1721
+ signer: Jws.createSigner(alice),
1722
+ });
1723
+ const commentsReply = await dwn.processMessage(alice.did, commentsConfigure.message);
1724
+ expect(commentsReply.status.code).toBe(202);
1725
+ const ratingsConfigure = await ProtocolsConfigure.create({
1726
+ definition: ratingsProtocol,
1727
+ signer: Jws.createSigner(alice),
1728
+ });
1729
+ const ratingsReply = await dwn.processMessage(alice.did, ratingsConfigure.message);
1730
+ expect(ratingsReply.status.code).toBe(202);
1731
+ // Create a thread
1732
+ const threadWrite = await TestDataGenerator.generateRecordsWrite({
1733
+ author: alice,
1734
+ protocol: threadsProtocol.protocol,
1735
+ protocolPath: 'thread',
1736
+ schema: 'https://threads.example.com/schemas/thread',
1737
+ dataFormat: 'application/json',
1738
+ });
1739
+ await dwn.processMessage(alice.did, threadWrite.message, { dataStream: threadWrite.dataStream });
1740
+ const threadContextId = threadWrite.message.contextId;
1741
+ // Create a comment under the thread via comments protocol
1742
+ const commentWrite = await TestDataGenerator.generateRecordsWrite({
1743
+ author: alice,
1744
+ protocol: commentsProtocol.protocol,
1745
+ protocolPath: 'thread/comment',
1746
+ schema: 'https://comments.example.com/schemas/comment',
1747
+ dataFormat: 'application/json',
1748
+ parentContextId: threadContextId,
1749
+ });
1750
+ const commentReply = await dwn.processMessage(alice.did, commentWrite.message, { dataStream: commentWrite.dataStream });
1751
+ expect(commentReply.status.code).toBe(202);
1752
+ // Create a rating under the same thread via ratings protocol
1753
+ const ratingWrite = await TestDataGenerator.generateRecordsWrite({
1754
+ author: alice,
1755
+ protocol: ratingsProtocol.protocol,
1756
+ protocolPath: 'thread/rating',
1757
+ schema: 'https://ratings.example.com/schemas/rating',
1758
+ dataFormat: 'application/json',
1759
+ parentContextId: threadContextId,
1760
+ });
1761
+ const ratingReply = await dwn.processMessage(alice.did, ratingWrite.message, { dataStream: ratingWrite.dataStream });
1762
+ expect(ratingReply.status.code).toBe(202);
1763
+ // Each protocol's records are isolated — querying comments returns only comments
1764
+ const commentsQuery = await RecordsQuery.create({
1765
+ signer: Jws.createSigner(alice),
1766
+ filter: { protocol: commentsProtocol.protocol },
1767
+ });
1768
+ const commentsQueryReply = await dwn.processMessage(alice.did, commentsQuery.message);
1769
+ expect(commentsQueryReply.entries.length).toBe(1);
1770
+ expect(commentsQueryReply.entries[0].recordId).toBe(commentWrite.message.recordId);
1771
+ // Querying ratings returns only ratings
1772
+ const ratingsQuery = await RecordsQuery.create({
1773
+ signer: Jws.createSigner(alice),
1774
+ filter: { protocol: ratingsProtocol.protocol },
1775
+ });
1776
+ const ratingsQueryReply = await dwn.processMessage(alice.did, ratingsQuery.message);
1777
+ expect(ratingsQueryReply.entries.length).toBe(1);
1778
+ expect(ratingsQueryReply.entries[0].recordId).toBe(ratingWrite.message.recordId);
1779
+ });
1780
+ });
1781
+ // =========================================================================
1782
+ // Composing protocol definition upgrade (adding children under $ref in V2)
1783
+ // =========================================================================
1784
+ describe('composing protocol definition upgrade', () => {
1785
+ it('should allow upgrading a composing protocol to add new child types under a `$ref` node', async () => {
1786
+ const alice = await TestDataGenerator.generateDidKeyPersona();
1787
+ // Install threads protocol
1788
+ const threadsConfigure = await ProtocolsConfigure.create({
1789
+ definition: threadsProtocol,
1790
+ signer: Jws.createSigner(alice),
1791
+ });
1792
+ await dwn.processMessage(alice.did, threadsConfigure.message);
1793
+ // Comments V1 — only has 'comment' under 'thread'
1794
+ const commentsV1 = {
1795
+ protocol: 'https://comments-upgrade.example.com',
1796
+ published: true,
1797
+ uses: { threads: 'https://threads.example.com' },
1798
+ types: {
1799
+ comment: { schema: 'https://comments-upgrade.example.com/schemas/comment', dataFormats: ['application/json'] },
1800
+ },
1801
+ structure: {
1802
+ thread: {
1803
+ $ref: 'threads:thread',
1804
+ comment: {
1805
+ $actions: [{ who: 'anyone', can: ['create', 'read'] }],
1806
+ },
1807
+ },
1808
+ },
1809
+ };
1810
+ const v1Configure = await ProtocolsConfigure.create({
1811
+ definition: commentsV1,
1812
+ signer: Jws.createSigner(alice),
1813
+ });
1814
+ const v1Reply = await dwn.processMessage(alice.did, v1Configure.message);
1815
+ expect(v1Reply.status.code).toBe(202);
1816
+ // Create a thread and a V1 comment
1817
+ const threadWrite = await TestDataGenerator.generateRecordsWrite({
1818
+ author: alice,
1819
+ protocol: threadsProtocol.protocol,
1820
+ protocolPath: 'thread',
1821
+ schema: 'https://threads.example.com/schemas/thread',
1822
+ dataFormat: 'application/json',
1823
+ });
1824
+ await dwn.processMessage(alice.did, threadWrite.message, { dataStream: threadWrite.dataStream });
1825
+ const threadContextId = threadWrite.message.contextId;
1826
+ const commentWrite = await TestDataGenerator.generateRecordsWrite({
1827
+ author: alice,
1828
+ protocol: commentsV1.protocol,
1829
+ protocolPath: 'thread/comment',
1830
+ schema: 'https://comments-upgrade.example.com/schemas/comment',
1831
+ dataFormat: 'application/json',
1832
+ parentContextId: threadContextId,
1833
+ });
1834
+ const commentReply = await dwn.processMessage(alice.did, commentWrite.message, { dataStream: commentWrite.dataStream });
1835
+ expect(commentReply.status.code).toBe(202);
1836
+ // Wait to ensure V2 gets a later timestamp
1837
+ await Time.minimalSleep();
1838
+ // Comments V2 — adds 'reaction' type under 'thread/comment'
1839
+ const commentsV2 = {
1840
+ protocol: 'https://comments-upgrade.example.com',
1841
+ published: true,
1842
+ uses: { threads: 'https://threads.example.com' },
1843
+ types: {
1844
+ comment: { schema: 'https://comments-upgrade.example.com/schemas/comment', dataFormats: ['application/json'] },
1845
+ reaction: { schema: 'https://comments-upgrade.example.com/schemas/reaction', dataFormats: ['application/json'] },
1846
+ },
1847
+ structure: {
1848
+ thread: {
1849
+ $ref: 'threads:thread',
1850
+ comment: {
1851
+ $actions: [{ who: 'anyone', can: ['create', 'read'] }],
1852
+ reaction: {
1853
+ $actions: [{ who: 'anyone', can: ['create', 'read'] }],
1854
+ },
1855
+ },
1856
+ },
1857
+ },
1858
+ };
1859
+ const v2Configure = await ProtocolsConfigure.create({
1860
+ definition: commentsV2,
1861
+ signer: Jws.createSigner(alice),
1862
+ });
1863
+ const v2Reply = await dwn.processMessage(alice.did, v2Configure.message);
1864
+ expect(v2Reply.status.code).toBe(202);
1865
+ // Now create a reaction under the comment using V2's structure
1866
+ const commentContextId = commentWrite.message.contextId;
1867
+ const reactionWrite = await TestDataGenerator.generateRecordsWrite({
1868
+ author: alice,
1869
+ protocol: commentsV2.protocol,
1870
+ protocolPath: 'thread/comment/reaction',
1871
+ schema: 'https://comments-upgrade.example.com/schemas/reaction',
1872
+ dataFormat: 'application/json',
1873
+ parentContextId: commentContextId,
1874
+ });
1875
+ const reactionReply = await dwn.processMessage(alice.did, reactionWrite.message, { dataStream: reactionWrite.dataStream });
1876
+ expect(reactionReply.status.code).toBe(202);
1877
+ });
1878
+ });
1879
+ // =========================================================================
1249
1880
  // Temporal correctness — governing timestamp for cross-protocol lookups
1250
1881
  // =========================================================================
1251
1882
  describe('temporal correctness — governing timestamp', () => {