@enbox/dwn-sdk-js 0.3.3 → 0.3.5

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 (202) hide show
  1. package/dist/browser.mjs +8 -8
  2. package/dist/browser.mjs.map +3 -3
  3. package/dist/esm/generated/precompiled-validators.js +766 -1224
  4. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  5. package/dist/esm/src/core/abstract-message.js +3 -3
  6. package/dist/esm/src/core/abstract-message.js.map +1 -1
  7. package/dist/esm/src/core/grant-authorization.js +6 -2
  8. package/dist/esm/src/core/grant-authorization.js.map +1 -1
  9. package/dist/esm/src/core/message.js +3 -3
  10. package/dist/esm/src/core/message.js.map +1 -1
  11. package/dist/esm/src/core/protocol-authorization-action.js +3 -3
  12. package/dist/esm/src/core/protocol-authorization-action.js.map +1 -1
  13. package/dist/esm/src/core/protocol-authorization-validation.js +1 -1
  14. package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
  15. package/dist/esm/src/core/protocol-authorization.js +11 -11
  16. package/dist/esm/src/core/protocol-authorization.js.map +1 -1
  17. package/dist/esm/src/core/records-grant-authorization.js +1 -1
  18. package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
  19. package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
  20. package/dist/esm/src/dwn.js.map +1 -1
  21. package/dist/esm/src/event-stream/event-emitter-event-log.js +12 -12
  22. package/dist/esm/src/event-stream/event-emitter-event-log.js.map +1 -1
  23. package/dist/esm/src/handlers/messages-read.js +7 -7
  24. package/dist/esm/src/handlers/messages-read.js.map +1 -1
  25. package/dist/esm/src/handlers/messages-subscribe.js +1 -1
  26. package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
  27. package/dist/esm/src/handlers/messages-sync.js +18 -18
  28. package/dist/esm/src/handlers/messages-sync.js.map +1 -1
  29. package/dist/esm/src/handlers/protocols-configure.js +1 -1
  30. package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
  31. package/dist/esm/src/handlers/protocols-query.js.map +1 -1
  32. package/dist/esm/src/handlers/records-count.js.map +1 -1
  33. package/dist/esm/src/handlers/records-delete.js.map +1 -1
  34. package/dist/esm/src/handlers/records-query.js.map +1 -1
  35. package/dist/esm/src/handlers/records-read.js +6 -6
  36. package/dist/esm/src/handlers/records-read.js.map +1 -1
  37. package/dist/esm/src/handlers/records-subscribe.js +1 -1
  38. package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
  39. package/dist/esm/src/handlers/records-write.js +16 -16
  40. package/dist/esm/src/handlers/records-write.js.map +1 -1
  41. package/dist/esm/src/index.js +2 -2
  42. package/dist/esm/src/index.js.map +1 -1
  43. package/dist/esm/src/interfaces/protocols-configure.js +9 -9
  44. package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
  45. package/dist/esm/src/interfaces/records-delete.js.map +1 -1
  46. package/dist/esm/src/interfaces/records-write.js +8 -8
  47. package/dist/esm/src/interfaces/records-write.js.map +1 -1
  48. package/dist/esm/src/jose/jws/general/builder.js.map +1 -1
  49. package/dist/esm/src/jose/jws/general/verifier.js +30 -2
  50. package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
  51. package/dist/esm/src/protocols/permissions.js +1 -1
  52. package/dist/esm/src/protocols/permissions.js.map +1 -1
  53. package/dist/esm/src/smt/smt-store-level.js.map +1 -1
  54. package/dist/esm/src/smt/smt-store-memory.js.map +1 -1
  55. package/dist/esm/src/smt/sparse-merkle-tree.js +2 -2
  56. package/dist/esm/src/smt/sparse-merkle-tree.js.map +1 -1
  57. package/dist/esm/src/state-index/state-index-level.js.map +1 -1
  58. package/dist/esm/src/store/index-level-compound.js +10 -10
  59. package/dist/esm/src/store/index-level-compound.js.map +1 -1
  60. package/dist/esm/src/store/index-level.js +2 -2
  61. package/dist/esm/src/store/index-level.js.map +1 -1
  62. package/dist/esm/src/store/level-wrapper.js +1 -1
  63. package/dist/esm/src/store/level-wrapper.js.map +1 -1
  64. package/dist/esm/src/store/storage-controller.js +23 -10
  65. package/dist/esm/src/store/storage-controller.js.map +1 -1
  66. package/dist/esm/src/types/permission-types.js.map +1 -1
  67. package/dist/esm/src/utils/memory-cache.js.map +1 -1
  68. package/dist/esm/src/utils/messages.js +1 -1
  69. package/dist/esm/src/utils/messages.js.map +1 -1
  70. package/dist/esm/src/utils/object.js +1 -4
  71. package/dist/esm/src/utils/object.js.map +1 -1
  72. package/dist/esm/src/utils/private-key-signer.js.map +1 -1
  73. package/dist/esm/src/utils/records.js.map +1 -1
  74. package/dist/esm/tests/core/grant-authorization.spec.js +38 -0
  75. package/dist/esm/tests/core/grant-authorization.spec.js.map +1 -0
  76. package/dist/esm/tests/features/permissions.spec.js +1 -1
  77. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  78. package/dist/esm/tests/features/records-prune-cross-protocol.spec.js +422 -0
  79. package/dist/esm/tests/features/records-prune-cross-protocol.spec.js.map +1 -0
  80. package/dist/esm/tests/handlers/messages-subscribe.spec.js +3 -26
  81. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  82. package/dist/esm/tests/handlers/messages-sync.spec.js +3 -26
  83. package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
  84. package/dist/esm/tests/handlers/protocols-query.spec.js +4 -3
  85. package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
  86. package/dist/esm/tests/jose/jws/general.spec.js +115 -0
  87. package/dist/esm/tests/jose/jws/general.spec.js.map +1 -1
  88. package/dist/esm/tests/store/message-store.spec.js +15 -0
  89. package/dist/esm/tests/store/message-store.spec.js.map +1 -1
  90. package/dist/esm/tests/test-suite.js +2 -0
  91. package/dist/esm/tests/test-suite.js.map +1 -1
  92. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  93. package/dist/types/src/core/abstract-message.d.ts +4 -4
  94. package/dist/types/src/core/abstract-message.d.ts.map +1 -1
  95. package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
  96. package/dist/types/src/core/resumable-task-manager.d.ts +2 -2
  97. package/dist/types/src/core/resumable-task-manager.d.ts.map +1 -1
  98. package/dist/types/src/dwn.d.ts +12 -12
  99. package/dist/types/src/dwn.d.ts.map +1 -1
  100. package/dist/types/src/event-stream/event-emitter-event-log.d.ts +5 -5
  101. package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +1 -1
  102. package/dist/types/src/handlers/messages-read.d.ts +1 -1
  103. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  104. package/dist/types/src/handlers/messages-subscribe.d.ts +1 -1
  105. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  106. package/dist/types/src/handlers/messages-sync.d.ts +1 -1
  107. package/dist/types/src/handlers/messages-sync.d.ts.map +1 -1
  108. package/dist/types/src/handlers/protocols-configure.d.ts +1 -1
  109. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  110. package/dist/types/src/handlers/protocols-query.d.ts +1 -1
  111. package/dist/types/src/handlers/protocols-query.d.ts.map +1 -1
  112. package/dist/types/src/handlers/records-count.d.ts +1 -1
  113. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  114. package/dist/types/src/handlers/records-delete.d.ts +1 -1
  115. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  116. package/dist/types/src/handlers/records-query.d.ts +1 -1
  117. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  118. package/dist/types/src/handlers/records-read.d.ts +1 -1
  119. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  120. package/dist/types/src/handlers/records-subscribe.d.ts +1 -1
  121. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  122. package/dist/types/src/handlers/records-write.d.ts +1 -1
  123. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  124. package/dist/types/src/index.d.ts +5 -5
  125. package/dist/types/src/index.d.ts.map +1 -1
  126. package/dist/types/src/interfaces/records-write.d.ts +2 -2
  127. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  128. package/dist/types/src/jose/jws/general/builder.d.ts +1 -1
  129. package/dist/types/src/jose/jws/general/builder.d.ts.map +1 -1
  130. package/dist/types/src/jose/jws/general/verifier.d.ts +13 -0
  131. package/dist/types/src/jose/jws/general/verifier.d.ts.map +1 -1
  132. package/dist/types/src/smt/smt-store-level.d.ts +1 -1
  133. package/dist/types/src/smt/smt-store-level.d.ts.map +1 -1
  134. package/dist/types/src/smt/smt-store-memory.d.ts +1 -1
  135. package/dist/types/src/smt/smt-store-memory.d.ts.map +1 -1
  136. package/dist/types/src/smt/sparse-merkle-tree.d.ts +1 -1
  137. package/dist/types/src/smt/sparse-merkle-tree.d.ts.map +1 -1
  138. package/dist/types/src/state-index/state-index-level.d.ts +3 -3
  139. package/dist/types/src/state-index/state-index-level.d.ts.map +1 -1
  140. package/dist/types/src/store/index-level.d.ts +2 -2
  141. package/dist/types/src/store/index-level.d.ts.map +1 -1
  142. package/dist/types/src/store/storage-controller.d.ts +19 -5
  143. package/dist/types/src/store/storage-controller.d.ts.map +1 -1
  144. package/dist/types/src/types/permission-types.d.ts +3 -4
  145. package/dist/types/src/types/permission-types.d.ts.map +1 -1
  146. package/dist/types/src/utils/memory-cache.d.ts +2 -2
  147. package/dist/types/src/utils/memory-cache.d.ts.map +1 -1
  148. package/dist/types/src/utils/object.d.ts.map +1 -1
  149. package/dist/types/src/utils/private-key-signer.d.ts +2 -2
  150. package/dist/types/src/utils/private-key-signer.d.ts.map +1 -1
  151. package/dist/types/tests/core/grant-authorization.spec.d.ts +2 -0
  152. package/dist/types/tests/core/grant-authorization.spec.d.ts.map +1 -0
  153. package/dist/types/tests/features/records-prune-cross-protocol.spec.d.ts +29 -0
  154. package/dist/types/tests/features/records-prune-cross-protocol.spec.d.ts.map +1 -0
  155. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  156. package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -1
  157. package/dist/types/tests/handlers/protocols-query.spec.d.ts.map +1 -1
  158. package/dist/types/tests/store/message-store.spec.d.ts.map +1 -1
  159. package/dist/types/tests/test-suite.d.ts.map +1 -1
  160. package/package.json +1 -1
  161. package/src/core/abstract-message.ts +8 -8
  162. package/src/core/grant-authorization.ts +9 -2
  163. package/src/core/message.ts +3 -3
  164. package/src/core/protocol-authorization-action.ts +3 -3
  165. package/src/core/protocol-authorization-validation.ts +9 -9
  166. package/src/core/protocol-authorization.ts +24 -24
  167. package/src/core/records-grant-authorization.ts +1 -1
  168. package/src/core/resumable-task-manager.ts +2 -2
  169. package/src/dwn.ts +13 -13
  170. package/src/event-stream/event-emitter-event-log.ts +15 -15
  171. package/src/handlers/messages-read.ts +7 -7
  172. package/src/handlers/messages-subscribe.ts +2 -2
  173. package/src/handlers/messages-sync.ts +19 -19
  174. package/src/handlers/protocols-configure.ts +2 -2
  175. package/src/handlers/protocols-query.ts +1 -1
  176. package/src/handlers/records-count.ts +1 -1
  177. package/src/handlers/records-delete.ts +1 -1
  178. package/src/handlers/records-query.ts +1 -1
  179. package/src/handlers/records-read.ts +6 -6
  180. package/src/handlers/records-subscribe.ts +2 -2
  181. package/src/handlers/records-write.ts +18 -18
  182. package/src/index.ts +5 -5
  183. package/src/interfaces/protocols-configure.ts +12 -12
  184. package/src/interfaces/records-delete.ts +1 -1
  185. package/src/interfaces/records-write.ts +11 -11
  186. package/src/jose/jws/general/builder.ts +1 -1
  187. package/src/jose/jws/general/verifier.ts +44 -3
  188. package/src/protocols/permissions.ts +1 -1
  189. package/src/smt/smt-store-level.ts +1 -1
  190. package/src/smt/smt-store-memory.ts +1 -1
  191. package/src/smt/sparse-merkle-tree.ts +10 -10
  192. package/src/state-index/state-index-level.ts +3 -3
  193. package/src/store/index-level-compound.ts +11 -11
  194. package/src/store/index-level.ts +4 -4
  195. package/src/store/level-wrapper.ts +1 -1
  196. package/src/store/storage-controller.ts +31 -16
  197. package/src/types/permission-types.ts +3 -4
  198. package/src/utils/memory-cache.ts +2 -2
  199. package/src/utils/messages.ts +2 -2
  200. package/src/utils/object.ts +1 -5
  201. package/src/utils/private-key-signer.ts +2 -2
  202. package/src/utils/records.ts +1 -1
@@ -3,8 +3,8 @@ import type { Cache } from '../types/cache.js';
3
3
  * A cache using local memory.
4
4
  */
5
5
  export declare class MemoryCache implements Cache {
6
- private timeToLiveInSeconds;
7
- private cache;
6
+ private readonly timeToLiveInSeconds;
7
+ private readonly cache;
8
8
  /**
9
9
  * @param timeToLiveInSeconds time-to-live for every key-value pair set in the cache
10
10
  */
@@ -1 +1 @@
1
- {"version":3,"file":"memory-cache.d.ts","sourceRoot":"","sources":["../../../../src/utils/memory-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG/C;;GAEG;AACH,qBAAa,WAAY,YAAW,KAAK;IAMnB,OAAO,CAAC,mBAAmB;IAL/C,OAAO,CAAC,KAAK,CAAwB;IAErC;;OAEG;gBACyB,mBAAmB,EAAE,MAAM;IAOjD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC;CAGjD"}
1
+ {"version":3,"file":"memory-cache.d.ts","sourceRoot":"","sources":["../../../../src/utils/memory-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG/C;;GAEG;AACH,qBAAa,WAAY,YAAW,KAAK;IAMnB,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IALxD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwB;IAE9C;;OAEG;gBACkC,mBAAmB,EAAE,MAAM;IAO1D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC;CAGjD"}
@@ -1 +1 @@
1
- {"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../../../../src/utils/object.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAUnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAWrE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAQ5E"}
1
+ {"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../../../../src/utils/object.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAMnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAWrE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAQ5E"}
@@ -23,8 +23,8 @@ export type PrivateKeySignerOptions = {
23
23
  export declare class PrivateKeySigner implements MessageSigner {
24
24
  keyId: string;
25
25
  algorithm: string;
26
- private privateJwk;
27
- private signatureAlgorithm;
26
+ private readonly privateJwk;
27
+ private readonly signatureAlgorithm;
28
28
  constructor(options: PrivateKeySignerOptions);
29
29
  /**
30
30
  * Signs the given content and returns the signature as bytes.
@@ -1 +1 @@
1
- {"version":3,"file":"private-key-signer.d.ts","sourceRoot":"","sources":["../../../../src/utils/private-key-signer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAK5D;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;;OAEG;IACH,UAAU,EAAE,aAAa,CAAC;IAE1B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IAC7C,KAAK,SAAC;IACN,SAAS,SAAC;IACjB,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,kBAAkB,CAAC;gBAER,OAAO,EAAE,uBAAuB;IA8BnD;;OAEG;IACU,IAAI,CAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;CAI7D"}
1
+ {"version":3,"file":"private-key-signer.d.ts","sourceRoot":"","sources":["../../../../src/utils/private-key-signer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAK5D;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;;OAEG;IACH,UAAU,EAAE,aAAa,CAAC;IAE1B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IAC7C,KAAK,SAAC;IACN,SAAS,SAAC;IACjB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAC3C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;gBAEjB,OAAO,EAAE,uBAAuB;IA8BnD;;OAEG;IACU,IAAI,CAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;CAI7D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=grant-authorization.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grant-authorization.spec.d.ts","sourceRoot":"","sources":["../../../../tests/core/grant-authorization.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Regression tests for cross-protocol prune cascade — closes #298.
3
+ *
4
+ * Semantics (decision under #298):
5
+ * A `RecordsDelete` with `prune: true` cascades to every descendant of the
6
+ * pruned record, regardless of which protocol a descendant declares itself
7
+ * under. `parentContextId` is a structural link — pruning a parent removes
8
+ * the entire subtree it rooted. Cross-protocol composing children (records
9
+ * in a different protocol that reference the parent via `$ref` / `uses`)
10
+ * participate in the cascade on equal footing with same-protocol children.
11
+ *
12
+ * Rationale:
13
+ * - A DWN is tenant-owned storage. The tenant's prune authority extends
14
+ * across the whole subtree they rooted, so walking the `parentId` chain
15
+ * unconditionally is the correct semantic.
16
+ * - Preserving cross-protocol orphans creates a half-alive state — readable
17
+ * but not updatable, since `validateReferentialIntegrity` in the
18
+ * `RecordsWrite` handler rejects any write whose parent is missing —
19
+ * which is worse for callers than cascading.
20
+ * - Same-protocol descendants at arbitrary depth already cascade via
21
+ * `parentId` with no protocol filter; treating a cross-protocol hop
22
+ * specially was inconsistent.
23
+ *
24
+ * These tests install multiple protocols linked via `uses` + `$ref`, write
25
+ * records across protocol boundaries, and assert that the entire subtree —
26
+ * same protocol or cross protocol, at any depth — is fully purged on prune.
27
+ */
28
+ export declare function testRecordsPruneCrossProtocol(): void;
29
+ //# sourceMappingURL=records-prune-cross-protocol.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"records-prune-cross-protocol.spec.d.ts","sourceRoot":"","sources":["../../../../tests/features/records-prune-cross-protocol.spec.ts"],"names":[],"mappings":"AA8BA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,6BAA6B,IAAI,IAAI,CAyfpD"}
@@ -1 +1 @@
1
- {"version":3,"file":"messages-subscribe.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/messages-subscribe.spec.ts"],"names":[],"mappings":"AAsBA,wBAAgB,4BAA4B,IAAI,IAAI,CAi8BnD"}
1
+ {"version":3,"file":"messages-subscribe.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/messages-subscribe.spec.ts"],"names":[],"mappings":"AAsBA,wBAAgB,4BAA4B,IAAI,IAAI,CAu6BnD"}
@@ -1 +1 @@
1
- {"version":3,"file":"messages-sync.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/messages-sync.spec.ts"],"names":[],"mappings":"AAwBA,wBAAgB,uBAAuB,IAAI,IAAI,CAy1B9C"}
1
+ {"version":3,"file":"messages-sync.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/messages-sync.spec.ts"],"names":[],"mappings":"AAwBA,wBAAgB,uBAAuB,IAAI,IAAI,CA8zB9C"}
@@ -1 +1 @@
1
- {"version":3,"file":"protocols-query.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/protocols-query.spec.ts"],"names":[],"mappings":"AAwBA,wBAAgB,yBAAyB,IAAI,IAAI,CA8gBhD"}
1
+ {"version":3,"file":"protocols-query.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/protocols-query.spec.ts"],"names":[],"mappings":"AAwBA,wBAAgB,yBAAyB,IAAI,IAAI,CA+gBhD"}
@@ -1 +1 @@
1
- {"version":3,"file":"message-store.spec.d.ts","sourceRoot":"","sources":["../../../../tests/store/message-store.spec.ts"],"names":[],"mappings":"AAcA,wBAAgB,gBAAgB,IAAI,IAAI,CA2kBvC"}
1
+ {"version":3,"file":"message-store.spec.d.ts","sourceRoot":"","sources":["../../../../tests/store/message-store.spec.ts"],"names":[],"mappings":"AAcA,wBAAgB,gBAAgB,IAAI,IAAI,CA8lBvC"}
@@ -1 +1 @@
1
- {"version":3,"file":"test-suite.d.ts","sourceRoot":"","sources":["../../../tests/test-suite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAuCzG;;GAEG;AACH,qBAAa,SAAS;IAEpB;;;OAGG;WACW,2BAA2B,CAAC,SAAS,CAAC,EAAE;QACpD,YAAY,CAAC,EAAE,YAAY,CAAC;QAC5B,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,UAAU,CAAC,EAAE,UAAU,CAAC;QACxB,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;KACzC,GAAG,IAAI;CA8CT"}
1
+ {"version":3,"file":"test-suite.d.ts","sourceRoot":"","sources":["../../../tests/test-suite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAwCzG;;GAEG;AACH,qBAAa,SAAS;IAEpB;;;OAGG;WACW,2BAA2B,CAAC,SAAS,CAAC,EAAE;QACpD,YAAY,CAAC,EAAE,YAAY,CAAC;QAC5B,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,UAAU,CAAC,EAAE,UAAU,CAAC;QACxB,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;KACzC,GAAG,IAAI;CA+CT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enbox/dwn-sdk-js",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "A reference implementation of https://identity.foundation/decentralized-web-node/spec/",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,22 +8,22 @@ import { Message } from './message.js';
8
8
  * An abstract implementation of the `MessageInterface` interface.
9
9
  */
10
10
  export abstract class AbstractMessage<M extends GenericMessage> implements MessageInterface<M> {
11
- private _message: M;
11
+ private readonly _message: M;
12
12
  public get message(): M {
13
- return this._message as M;
13
+ return this._message;
14
14
  }
15
15
 
16
- private _signer: string | undefined;
16
+ private readonly _signer: string | undefined;
17
17
  public get signer(): string | undefined {
18
18
  return this._signer;
19
19
  }
20
20
 
21
- private _author: string | undefined;
21
+ private readonly _author: string | undefined;
22
22
  public get author(): string | undefined {
23
23
  return this._author;
24
24
  }
25
25
 
26
- private _signaturePayload: GenericSignaturePayload | undefined;
26
+ private readonly _signaturePayload: GenericSignaturePayload | undefined;
27
27
  public get signaturePayload(): GenericSignaturePayload | undefined {
28
28
  return this._signaturePayload;
29
29
  }
@@ -43,10 +43,10 @@ export abstract class AbstractMessage<M extends GenericMessage> implements Messa
43
43
 
44
44
  // if the message authorization contains author delegated grant, the author would be the grantor of the grant
45
45
  // else the author would be the signer of the message
46
- if (message.authorization.authorDelegatedGrant !== undefined) {
47
- this._author = Message.getSigner(message.authorization.authorDelegatedGrant);
48
- } else {
46
+ if (message.authorization.authorDelegatedGrant === undefined) {
49
47
  this._author = this._signer;
48
+ } else {
49
+ this._author = Message.getSigner(message.authorization.authorDelegatedGrant);
50
50
  }
51
51
 
52
52
  this._signaturePayload = Jws.decodePlainObjectPayload(message.authorization.signature);
@@ -146,8 +146,15 @@ export class GrantAuthorization {
146
146
  );
147
147
  }
148
148
 
149
- // For the Messages interface, a `Read` scope is a unified scope that also covers `Subscribe` and `Sync`.
150
- if (dwnInterface === DwnInterfaceName.Messages && permissionGrant.scope.method === DwnMethodName.Read) {
149
+ // Messages.Read is the only valid Messages scope and covers Read, Subscribe, and Sync operations.
150
+ // Reject any Messages grant with method !== Read (malformed or legacy stored data).
151
+ if (dwnInterface === DwnInterfaceName.Messages) {
152
+ if (permissionGrant.scope.method !== DwnMethodName.Read) {
153
+ throw new DwnError(
154
+ DwnErrorCode.GrantAuthorizationMethodMismatch,
155
+ `messages permission grant must have method 'Read', got '${permissionGrant.scope.method}' for grant ${permissionGrant.id}`
156
+ );
157
+ }
151
158
  const allowedMethods = [DwnMethodName.Read, DwnMethodName.Subscribe, DwnMethodName.Sync];
152
159
  if (!allowedMethods.includes(dwnMethod as DwnMethodName)) {
153
160
  throw new DwnError(
@@ -26,10 +26,10 @@ export class Message {
26
26
  }
27
27
 
28
28
  let author;
29
- if (message.authorization.authorDelegatedGrant !== undefined) {
30
- author = Message.getSigner(message.authorization.authorDelegatedGrant);
31
- } else {
29
+ if (message.authorization.authorDelegatedGrant === undefined) {
32
30
  author = Message.getSigner(message);
31
+ } else {
32
+ author = Message.getSigner(message.authorization.authorDelegatedGrant);
33
33
  }
34
34
 
35
35
  return author;
@@ -53,7 +53,7 @@ export async function verifyInvokedRole(
53
53
  );
54
54
  }
55
55
 
56
- if (protocolDefinition.uses === undefined || protocolDefinition.uses[parsed.alias] === undefined) {
56
+ if (protocolDefinition.uses?.[parsed.alias] === undefined) {
57
57
  throw new DwnError(
58
58
  DwnErrorCode.ProtocolAuthorizationNotARole,
59
59
  `Cross-protocol role alias '${parsed.alias}' in '${protocolRole}' does not exist in the protocol's 'uses' map.`
@@ -68,7 +68,7 @@ export async function verifyInvokedRole(
68
68
  tenant, roleProtocolUri, messageStore, governingTimestamp
69
69
  );
70
70
  const roleRuleSet = getRuleSetAtPath(roleProtocolPath, refDefinition.structure);
71
- if (roleRuleSet === undefined || !roleRuleSet.$role) {
71
+ if (!roleRuleSet?.$role) {
72
72
  throw new DwnError(
73
73
  DwnErrorCode.ProtocolAuthorizationNotARole,
74
74
  `Cross-protocol role path ${protocolRole} does not match role record type.`
@@ -77,7 +77,7 @@ export async function verifyInvokedRole(
77
77
  } else {
78
78
  // Local role: validate in the composing protocol's definition
79
79
  const roleRuleSet = getRuleSetAtPath(protocolRole, protocolDefinition.structure);
80
- if (roleRuleSet === undefined || !roleRuleSet.$role) {
80
+ if (!roleRuleSet?.$role) {
81
81
  throw new DwnError(
82
82
  DwnErrorCode.ProtocolAuthorizationNotARole,
83
83
  `Protocol path ${protocolRole} does not match role record type.`
@@ -28,7 +28,7 @@ export async function verifyProtocolPathAndContextId(
28
28
  fetchProtocolDefinition: FetchProtocolDefinitionFn,
29
29
  governingTimestamp?: string,
30
30
  ): Promise<void> {
31
- const declaredProtocolPath = inboundMessage.message.descriptor.protocolPath!;
31
+ const declaredProtocolPath = inboundMessage.message.descriptor.protocolPath;
32
32
  const declaredTypeName = getTypeName(declaredProtocolPath);
33
33
 
34
34
  const parentId = inboundMessage.message.descriptor.parentId;
@@ -47,7 +47,7 @@ export async function verifyProtocolPathAndContextId(
47
47
 
48
48
  // Determine the protocol URI for the parent query.
49
49
  // If the parent path segment has a `$ref` in the composing protocol, the parent lives in a different protocol.
50
- const childProtocol = inboundMessage.message.descriptor.protocol!;
50
+ const childProtocol = inboundMessage.message.descriptor.protocol;
51
51
  const parentProtocolUri = await resolveParentProtocolUri(
52
52
  tenant, childProtocol, declaredProtocolPath, messageStore, fetchProtocolDefinition, governingTimestamp
53
53
  );
@@ -174,7 +174,7 @@ export async function verifyTypeWithComposition(
174
174
  fetchProtocolDefinition: FetchProtocolDefinitionFn,
175
175
  governingTimestamp?: string,
176
176
  ): Promise<void> {
177
- const declaredProtocolPath = inboundMessage.descriptor.protocolPath!;
177
+ const declaredProtocolPath = inboundMessage.descriptor.protocolPath;
178
178
  const declaredTypeName = getTypeName(declaredProtocolPath);
179
179
 
180
180
  // Resolve which protocol types map to use.
@@ -231,7 +231,7 @@ export function verifyType(
231
231
  protocolTypes: ProtocolTypes,
232
232
  typeName?: string,
233
233
  ): void {
234
- const declaredTypeName = typeName ?? getTypeName(inboundMessage.descriptor.protocolPath!);
234
+ const declaredTypeName = typeName ?? getTypeName(inboundMessage.descriptor.protocolPath);
235
235
  const typeNames = Object.keys(protocolTypes);
236
236
 
237
237
  if (!typeNames.includes(declaredTypeName)) {
@@ -361,12 +361,12 @@ export async function verifyAsRoleRecordIfNeeded(
361
361
  );
362
362
  }
363
363
 
364
- const protocolPath = incomingRecordsWrite.message.descriptor.protocolPath!;
364
+ const protocolPath = incomingRecordsWrite.message.descriptor.protocolPath;
365
365
  const filter: Filter = {
366
366
  interface : DwnInterfaceName.Records,
367
367
  method : DwnMethodName.Write,
368
368
  isLatestBaseState : true,
369
- protocol : incomingRecordsWrite.message.descriptor.protocol!,
369
+ protocol : incomingRecordsWrite.message.descriptor.protocol,
370
370
  protocolPath,
371
371
  recipient,
372
372
  };
@@ -422,12 +422,12 @@ export async function verifyRecordLimit(
422
422
  const { max, strategy } = ruleSet.$recordLimit;
423
423
 
424
424
  // Build a filter to count existing records at the same protocol path and parent context.
425
- const protocolPath = incomingMessage.message.descriptor.protocolPath!;
425
+ const protocolPath = incomingMessage.message.descriptor.protocolPath;
426
426
  const filter: Filter = {
427
427
  interface : DwnInterfaceName.Records,
428
428
  method : DwnMethodName.Write,
429
429
  isLatestBaseState : true,
430
- protocol : incomingMessage.message.descriptor.protocol!,
430
+ protocol : incomingMessage.message.descriptor.protocol,
431
431
  protocolPath,
432
432
  };
433
433
 
@@ -445,7 +445,7 @@ export async function verifyRecordLimit(
445
445
  throw new DwnError(
446
446
  DwnErrorCode.ProtocolAuthorizationRecordLimitExceeded,
447
447
  `record limit of ${max} reached at protocol path '${protocolPath}'` +
448
- `${parentContextId !== '' ? ` under parent context '${parentContextId}'` : ''}` +
448
+ `${parentContextId === '' ? '' : ` under parent context '${parentContextId}'`}` +
449
449
  `: new records are rejected until existing records are deleted.`
450
450
  );
451
451
  }
@@ -61,7 +61,7 @@ export class ProtocolAuthorization {
61
61
  // fetch the protocol definition that was active at the governing timestamp
62
62
  const protocolDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
63
63
  tenant,
64
- incomingMessage.message.descriptor.protocol!,
64
+ incomingMessage.message.descriptor.protocol,
65
65
  messageStore,
66
66
  governingTimestamp,
67
67
  coreProtocols,
@@ -85,7 +85,7 @@ export class ProtocolAuthorization {
85
85
 
86
86
  // get the rule set for the inbound message
87
87
  const ruleSet = ProtocolAuthorization.getRuleSet(
88
- incomingMessage.message.descriptor.protocolPath!,
88
+ incomingMessage.message.descriptor.protocolPath,
89
89
  protocolDefinition,
90
90
  );
91
91
 
@@ -143,7 +143,7 @@ export class ProtocolAuthorization {
143
143
  // fetch the protocol definition that was active at the governing timestamp
144
144
  const protocolDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
145
145
  tenant,
146
- incomingMessage.message.descriptor.protocol!,
146
+ incomingMessage.message.descriptor.protocol,
147
147
  messageStore,
148
148
  governingTimestamp,
149
149
  coreProtocols,
@@ -151,7 +151,7 @@ export class ProtocolAuthorization {
151
151
 
152
152
  // get the rule set for the inbound message
153
153
  const ruleSet = ProtocolAuthorization.getRuleSet(
154
- incomingMessage.message.descriptor.protocolPath!,
154
+ incomingMessage.message.descriptor.protocolPath,
155
155
  protocolDefinition,
156
156
  );
157
157
 
@@ -161,8 +161,8 @@ export class ProtocolAuthorization {
161
161
  await verifyInvokedRole(
162
162
  tenant,
163
163
  incomingMessage,
164
- incomingMessage.message.descriptor.protocol!,
165
- incomingMessage.message.contextId!,
164
+ incomingMessage.message.descriptor.protocol,
165
+ incomingMessage.message.contextId,
166
166
  protocolDefinition,
167
167
  messageStore,
168
168
  boundFetchDefinition,
@@ -201,14 +201,14 @@ export class ProtocolAuthorization {
201
201
  const initialWrite = await fetchInitialWrite(
202
202
  tenant, newestRecordsWrite.message.recordId, messageStore
203
203
  );
204
- const governingTimestamp = initialWrite !== undefined
205
- ? initialWrite.descriptor.messageTimestamp
206
- : newestRecordsWrite.message.descriptor.messageTimestamp;
204
+ const governingTimestamp = initialWrite === undefined
205
+ ? newestRecordsWrite.message.descriptor.messageTimestamp
206
+ : initialWrite.descriptor.messageTimestamp;
207
207
 
208
208
  // fetch the protocol definition that was active when the record was created
209
209
  const protocolDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
210
210
  tenant,
211
- newestRecordsWrite.message.descriptor.protocol!,
211
+ newestRecordsWrite.message.descriptor.protocol,
212
212
  messageStore,
213
213
  governingTimestamp,
214
214
  coreProtocols,
@@ -216,7 +216,7 @@ export class ProtocolAuthorization {
216
216
 
217
217
  // get the rule set for the inbound message
218
218
  const ruleSet = ProtocolAuthorization.getRuleSet(
219
- newestRecordsWrite.message.descriptor.protocolPath!,
219
+ newestRecordsWrite.message.descriptor.protocolPath,
220
220
  protocolDefinition,
221
221
  );
222
222
 
@@ -226,8 +226,8 @@ export class ProtocolAuthorization {
226
226
  await verifyInvokedRole(
227
227
  tenant,
228
228
  incomingMessage,
229
- newestRecordsWrite.message.descriptor.protocol!,
230
- newestRecordsWrite.message.contextId!,
229
+ newestRecordsWrite.message.descriptor.protocol,
230
+ newestRecordsWrite.message.contextId,
231
231
  protocolDefinition,
232
232
  messageStore,
233
233
  boundFetchDefinition,
@@ -312,14 +312,14 @@ export class ProtocolAuthorization {
312
312
  const initialWrite = await fetchInitialWrite(
313
313
  tenant, incomingMessage.message.descriptor.recordId, messageStore
314
314
  );
315
- const governingTimestamp = initialWrite !== undefined
316
- ? initialWrite.descriptor.messageTimestamp
317
- : recordsWrite.message.descriptor.messageTimestamp;
315
+ const governingTimestamp = initialWrite === undefined
316
+ ? recordsWrite.message.descriptor.messageTimestamp
317
+ : initialWrite.descriptor.messageTimestamp;
318
318
 
319
319
  // fetch the protocol definition that was active when the record was created
320
320
  const protocolDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
321
321
  tenant,
322
- recordsWrite.message.descriptor.protocol!,
322
+ recordsWrite.message.descriptor.protocol,
323
323
  messageStore,
324
324
  governingTimestamp,
325
325
  coreProtocols,
@@ -327,7 +327,7 @@ export class ProtocolAuthorization {
327
327
 
328
328
  // get the rule set for the inbound message
329
329
  const ruleSet = ProtocolAuthorization.getRuleSet(
330
- recordsWrite.message.descriptor.protocolPath!,
330
+ recordsWrite.message.descriptor.protocolPath,
331
331
  protocolDefinition,
332
332
  );
333
333
 
@@ -337,8 +337,8 @@ export class ProtocolAuthorization {
337
337
  await verifyInvokedRole(
338
338
  tenant,
339
339
  incomingMessage,
340
- recordsWrite.message.descriptor.protocol!,
341
- recordsWrite.message.contextId!,
340
+ recordsWrite.message.descriptor.protocol,
341
+ recordsWrite.message.contextId,
342
342
  protocolDefinition,
343
343
  messageStore,
344
344
  boundFetchDefinition,
@@ -389,12 +389,12 @@ export class ProtocolAuthorization {
389
389
  protocol : protocolUri,
390
390
  };
391
391
 
392
- if (messageTimestamp !== undefined) {
393
- // temporal lookup: find the protocol definition active at the given timestamp
394
- query.messageTimestamp = { lte: messageTimestamp };
395
- } else {
392
+ if (messageTimestamp === undefined) {
396
393
  // default: return only the latest protocol definition
397
394
  query.isLatestBaseState = true;
395
+ } else {
396
+ // temporal lookup: find the protocol definition active at the given timestamp
397
+ query.messageTimestamp = { lte: messageTimestamp };
398
398
  }
399
399
 
400
400
  const { messages: protocols } = await messageStore.query(
@@ -153,7 +153,7 @@ export class RecordsGrantAuthorization {
153
153
 
154
154
  // If grant specifies a contextId, check that record falls under that contextId
155
155
  if (grantScope.contextId !== undefined) {
156
- if (recordsWriteMessage.contextId === undefined || !recordsWriteMessage.contextId.startsWith(grantScope.contextId)) {
156
+ if (!recordsWriteMessage.contextId?.startsWith(grantScope.contextId)) {
157
157
  throw new DwnError(
158
158
  DwnErrorCode.RecordsGrantAuthorizationScopeContextIdMismatch,
159
159
  `Grant scope specifies different contextId than what appears in the record`
@@ -20,9 +20,9 @@ export class ResumableTaskManager {
20
20
  public static readonly timeoutExtensionFrequencyInSeconds = 30;
21
21
 
22
22
  private resumableTaskBatchSize = 100;
23
- private resumableTaskHandlers: { [key:string]: (taskData: any) => Promise<void> };
23
+ private readonly resumableTaskHandlers: { [key:string]: (taskData: any) => Promise<void> };
24
24
 
25
- public constructor(private resumableTaskStore: ResumableTaskStore, storageController: StorageController) {
25
+ public constructor(private readonly resumableTaskStore: ResumableTaskStore, storageController: StorageController) {
26
26
  // assign resumable task handlers
27
27
  this.resumableTaskHandlers = {
28
28
  // NOTE: The arrow function is IMPORTANT here, else the `this` context will be lost within the invoked method.
package/src/dwn.ts CHANGED
@@ -34,20 +34,20 @@ import { DidDht, DidJwk, DidKey, DidResolverCacheMemory, DidWeb, UniversalResolv
34
34
  import { DwnInterfaceName, DwnMethodName } from './enums/dwn-interface-method.js';
35
35
 
36
36
  export class Dwn {
37
- private methodHandlers: { [key:string]: MethodHandler };
38
- private didResolver: DidResolver;
39
- private messageStore: MessageStore;
40
- private dataStore: DataStore;
41
- private resumableTaskStore: ResumableTaskStore;
42
- private stateIndex: StateIndex;
43
- private tenantGate: TenantGate;
44
- private eventLog?: EventLog;
45
- private storageController: StorageController;
46
- private resumableTaskManager: ResumableTaskManager;
47
- private _coreProtocols: CoreProtocolRegistry;
37
+ private readonly methodHandlers: { [key:string]: MethodHandler };
38
+ private readonly didResolver: DidResolver;
39
+ private readonly messageStore: MessageStore;
40
+ private readonly dataStore: DataStore;
41
+ private readonly resumableTaskStore: ResumableTaskStore;
42
+ private readonly stateIndex: StateIndex;
43
+ private readonly tenantGate: TenantGate;
44
+ private readonly eventLog?: EventLog;
45
+ private readonly storageController: StorageController;
46
+ private readonly resumableTaskManager: ResumableTaskManager;
47
+ private readonly _coreProtocols: CoreProtocolRegistry;
48
48
 
49
49
  /** Whether the DWN owns the resolver's lifecycle (i.e., created it via defaults). */
50
- private ownsResolver: boolean;
50
+ private readonly ownsResolver: boolean;
51
51
 
52
52
  private constructor(config: DwnConfig) {
53
53
  this.didResolver = config.didResolver!;
@@ -204,7 +204,7 @@ export class Dwn {
204
204
  const handlerKey = rawMessage.descriptor.interface + rawMessage.descriptor.method;
205
205
  const methodHandlerReply = await this.methodHandlers[handlerKey].handle({
206
206
  tenant,
207
- message: rawMessage as GenericMessage,
207
+ message: rawMessage,
208
208
  dataStream,
209
209
  subscriptionHandler
210
210
  });
@@ -65,21 +65,21 @@ export interface EventEmitterEventLogConfig {
65
65
  * For multi-node deployments, use a distributed implementation (NATS, Redis, etc.).
66
66
  */
67
67
  export class EventEmitterEventLog implements EventLog {
68
- private emitter = mitt<EmitterEvents>();
68
+ private readonly emitter = mitt<EmitterEvents>();
69
69
  private isOpen: boolean = false;
70
- private errorHandler: (error: any) => void = (error): void => { console.error('event log error', error); };
71
- private maxEventsPerTenant: number;
70
+ private readonly errorHandler: (error: any) => void = (error): void => { console.error('event log error', error); };
71
+ private readonly maxEventsPerTenant: number;
72
72
 
73
73
  /**
74
74
  * Per-tenant ordered event storage.
75
75
  * Key: tenant DID → Map of seq → StoredEntry.
76
76
  */
77
- private tenantLogs: Map<string, Map<number, StoredEntry>> = new Map();
77
+ private readonly tenantLogs: Map<string, Map<number, StoredEntry>> = new Map();
78
78
 
79
79
  /**
80
80
  * Per-tenant monotonic sequence counter.
81
81
  */
82
- private tenantSeqs: Map<string, number> = new Map();
82
+ private readonly tenantSeqs: Map<string, number> = new Map();
83
83
 
84
84
  /**
85
85
  * Epoch for this EventLog instance. Generated once at construction as a
@@ -131,9 +131,7 @@ export class EventEmitterEventLog implements EventLog {
131
131
  let reason: ProgressGapReason;
132
132
  if (cursor.streamId !== expectedStreamId) {
133
133
  reason = 'stream_mismatch';
134
- } else if (cursor.epoch !== this.epoch) {
135
- reason = 'epoch_mismatch';
136
- } else {
134
+ } else if (cursor.epoch === this.epoch) {
137
135
  // Check if position is still within replay bounds.
138
136
  const log = this.tenantLogs.get(tenant);
139
137
  if (log !== undefined && log.size > 0) {
@@ -148,6 +146,8 @@ export class EventEmitterEventLog implements EventLog {
148
146
  } else {
149
147
  return; // No events for tenant — cursor is vacuously valid (will get empty catch-up + EOSE).
150
148
  }
149
+ } else {
150
+ reason = 'epoch_mismatch';
151
151
  }
152
152
 
153
153
  // Build gap metadata.
@@ -226,7 +226,7 @@ export class EventEmitterEventLog implements EventLog {
226
226
  await this.validateCursor(tenant, cursor);
227
227
  }
228
228
 
229
- const cursorSeq = cursor !== undefined ? EventEmitterEventLog.parsePosition(cursor.position) : undefined;
229
+ const cursorSeq = cursor === undefined ? undefined : EventEmitterEventLog.parsePosition(cursor.position);
230
230
  const log = this.tenantLogs.get(tenant);
231
231
 
232
232
  if (log === undefined || log.size === 0) {
@@ -319,12 +319,12 @@ export class EventEmitterEventLog implements EventLog {
319
319
  if (filters !== undefined && filters.length > 0) {
320
320
  if (!FilterUtility.matchAnyFilter(payload.indexes, filters)) { return; }
321
321
  }
322
- if (!catchUpComplete) {
323
- pendingLiveEvents.push({ event: payload.event, seq: payload.seq, messageCid: payload.messageCid });
324
- } else {
322
+ if (catchUpComplete) {
325
323
  void tokenFromPayload(payload).then((token) => {
326
324
  listener({ type: 'event', cursor: token, event: payload.event });
327
325
  });
326
+ } else {
327
+ pendingLiveEvents.push({ event: payload.event, seq: payload.seq, messageCid: payload.messageCid });
328
328
  }
329
329
  };
330
330
 
@@ -334,9 +334,9 @@ export class EventEmitterEventLog implements EventLog {
334
334
  const readResult = await this.read(tenant, { cursor, filters });
335
335
  // The read cursor is the token of the last read event, or the input cursor if nothing new.
336
336
  const eoseCursor = readResult.cursor ?? cursor;
337
- const lastCatchUpSeq = readResult.cursor !== undefined
338
- ? EventEmitterEventLog.parsePosition(readResult.cursor.position)
339
- : cursorSeq;
337
+ const lastCatchUpSeq = readResult.cursor === undefined
338
+ ? cursorSeq
339
+ : EventEmitterEventLog.parsePosition(readResult.cursor.position);
340
340
 
341
341
  // Use the messageCid captured by read() during its synchronous iteration.
342
342
  // This eliminates re-lookup races: read() populates entry.messageCid before
@@ -18,7 +18,7 @@ type HandleArgs = { tenant: string, message: MessagesReadMessage };
18
18
 
19
19
  export class MessagesReadHandler implements MethodHandler {
20
20
 
21
- constructor(private deps: HandlerDependencies) {}
21
+ constructor(private readonly deps: HandlerDependencies) {}
22
22
 
23
23
  public async handle({ tenant, message }: HandleArgs): Promise<MessagesReadReply> {
24
24
  let messagesRead: MessagesRead;
@@ -52,16 +52,16 @@ export class MessagesReadHandler implements MethodHandler {
52
52
  const recordsWrite = entry.message as RecordsQueryReplyEntry;
53
53
  // RecordsWrite specific handling, if MessageStore has embedded `encodedData` return it with the entry.
54
54
  // we store `encodedData` along with the message if the data is below a certain threshold.
55
- if (recordsWrite.encodedData !== undefined) {
56
- const dataBytes = Encoder.base64UrlToBytes(recordsWrite.encodedData);
57
- entry.data = DataStream.fromBytes(dataBytes);
58
- delete recordsWrite.encodedData;
59
- } else {
60
- // otherwise check the data store for the associated data
55
+ if (recordsWrite.encodedData === undefined) {
56
+ // check the data store for the associated data
61
57
  const result = await this.deps.dataStore!.get(tenant, recordsWrite.recordId, recordsWrite.descriptor.dataCid);
62
58
  if (result?.dataStream !== undefined) {
63
59
  entry.data = result.dataStream;
64
60
  }
61
+ } else {
62
+ const dataBytes = Encoder.base64UrlToBytes(recordsWrite.encodedData);
63
+ entry.data = DataStream.fromBytes(dataBytes);
64
+ delete recordsWrite.encodedData;
65
65
  }
66
66
  }
67
67
 
@@ -14,7 +14,7 @@ import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
14
14
 
15
15
  export class MessagesSubscribeHandler implements MethodHandler {
16
16
 
17
- constructor(private deps: HandlerDependencies) {}
17
+ constructor(private readonly deps: HandlerDependencies) {}
18
18
 
19
19
  public async handle({
20
20
  tenant,
@@ -65,7 +65,7 @@ export class MessagesSubscribeHandler implements MethodHandler {
65
65
  const gapInfo = (error as any).gapInfo as ProgressGapInfo | undefined;
66
66
  return {
67
67
  status : { code: 410, detail: 'Progress token gap' },
68
- error : gapInfo !== undefined ? { code: 'ProgressGap' as const, ...gapInfo } : undefined,
68
+ error : gapInfo === undefined ? undefined : { code: 'ProgressGap' as const, ...gapInfo },
69
69
  };
70
70
  }
71
71
  return messageReplyFromError(error, 500);