@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
@@ -25,7 +25,7 @@ const DEFAULT_MAX_INLINE_DATA_SIZE = DwnConstant.maxDataSizeAllowedToBeEncoded;
25
25
 
26
26
  export class MessagesSyncHandler implements MethodHandler {
27
27
 
28
- constructor(private deps: HandlerDependencies) { }
28
+ constructor(private readonly deps: HandlerDependencies) { }
29
29
 
30
30
  public async handle({
31
31
  tenant,
@@ -51,9 +51,9 @@ export class MessagesSyncHandler implements MethodHandler {
51
51
  try {
52
52
  switch (action) {
53
53
  case 'root': {
54
- const rootHash = protocol !== undefined
55
- ? await this.deps.stateIndex!.getProtocolRoot(tenant, protocol)
56
- : await this.deps.stateIndex!.getRoot(tenant);
54
+ const rootHash = protocol === undefined
55
+ ? await this.deps.stateIndex!.getRoot(tenant)
56
+ : await this.deps.stateIndex!.getProtocolRoot(tenant, protocol);
57
57
  return {
58
58
  status : { code: 200, detail: 'OK' },
59
59
  root : hashToHex(rootHash),
@@ -62,9 +62,9 @@ export class MessagesSyncHandler implements MethodHandler {
62
62
 
63
63
  case 'subtree': {
64
64
  const bitPath = MessagesSyncHandler.parseBitPrefix(prefix!);
65
- const hash = protocol !== undefined
66
- ? await this.deps.stateIndex!.getProtocolSubtreeHash(tenant, protocol, bitPath)
67
- : await this.deps.stateIndex!.getSubtreeHash(tenant, bitPath);
65
+ const hash = protocol === undefined
66
+ ? await this.deps.stateIndex!.getSubtreeHash(tenant, bitPath)
67
+ : await this.deps.stateIndex!.getProtocolSubtreeHash(tenant, protocol, bitPath);
68
68
  return {
69
69
  status : { code: 200, detail: 'OK' },
70
70
  hash : hashToHex(hash),
@@ -73,9 +73,9 @@ export class MessagesSyncHandler implements MethodHandler {
73
73
 
74
74
  case 'leaves': {
75
75
  const bitPath = MessagesSyncHandler.parseBitPrefix(prefix!);
76
- const leaves = protocol !== undefined
77
- ? await this.deps.stateIndex!.getProtocolLeaves(tenant, protocol, bitPath)
78
- : await this.deps.stateIndex!.getLeaves(tenant, bitPath);
76
+ const leaves = protocol === undefined
77
+ ? await this.deps.stateIndex!.getLeaves(tenant, bitPath)
78
+ : await this.deps.stateIndex!.getProtocolLeaves(tenant, protocol, bitPath);
79
79
  return {
80
80
  status : { code: 200, detail: 'OK' },
81
81
  entries : leaves,
@@ -165,18 +165,18 @@ export class MessagesSyncHandler implements MethodHandler {
165
165
  if (clientHash === undefined) {
166
166
  // Server has entries the client doesn't — enumerate server leaves.
167
167
  const bitPath = MessagesSyncHandler.parseBitPrefix(pfx);
168
- const leaves = protocol !== undefined
169
- ? await stateIndex.getProtocolLeaves(tenant, protocol, bitPath)
170
- : await stateIndex.getLeaves(tenant, bitPath);
168
+ const leaves = protocol === undefined
169
+ ? await stateIndex.getLeaves(tenant, bitPath)
170
+ : await stateIndex.getProtocolLeaves(tenant, protocol, bitPath);
171
171
  onlyRemoteCids.push(...leaves);
172
172
  continue;
173
173
  }
174
174
 
175
175
  // Both sides have entries but they differ — enumerate both and set-diff.
176
176
  const bitPath = MessagesSyncHandler.parseBitPrefix(pfx);
177
- const serverLeaves = protocol !== undefined
178
- ? await stateIndex.getProtocolLeaves(tenant, protocol, bitPath)
179
- : await stateIndex.getLeaves(tenant, bitPath);
177
+ const serverLeaves = protocol === undefined
178
+ ? await stateIndex.getLeaves(tenant, bitPath)
179
+ : await stateIndex.getProtocolLeaves(tenant, protocol, bitPath);
180
180
 
181
181
  // We don't have the client's leaves, so we report all server leaves
182
182
  // as onlyRemote (the client will de-duplicate locally). We also
@@ -210,9 +210,9 @@ export class MessagesSyncHandler implements MethodHandler {
210
210
 
211
211
  const walk = async (prefix: string, currentDepth: number): Promise<void> => {
212
212
  const bitPath = MessagesSyncHandler.parseBitPrefix(prefix);
213
- const hash = protocol !== undefined
214
- ? await stateIndex.getProtocolSubtreeHash(tenant, protocol, bitPath)
215
- : await stateIndex.getSubtreeHash(tenant, bitPath);
213
+ const hash = protocol === undefined
214
+ ? await stateIndex.getSubtreeHash(tenant, bitPath)
215
+ : await stateIndex.getProtocolSubtreeHash(tenant, protocol, bitPath);
216
216
  const hexHash = hashToHex(hash);
217
217
 
218
218
  if (hexHash === defaultHashHex) {
@@ -15,7 +15,7 @@ import { getRuleSetAtPath, parseCrossProtocolRef } from '../utils/protocols.js';
15
15
 
16
16
  export class ProtocolsConfigureHandler implements MethodHandler {
17
17
 
18
- constructor(private deps: HandlerDependencies) { }
18
+ constructor(private readonly deps: HandlerDependencies) { }
19
19
 
20
20
  public async handle({
21
21
  tenant,
@@ -298,7 +298,7 @@ export class ProtocolsConfigureHandler implements MethodHandler {
298
298
 
299
299
  // Check that the role path exists and is marked $role: true in the referenced protocol
300
300
  const roleRuleSet = getRuleSetAtPath(parsed.protocolPath, refDefinition.structure);
301
- if (roleRuleSet === undefined || !roleRuleSet.$role) {
301
+ if (!roleRuleSet?.$role) {
302
302
  throw new DwnError(
303
303
  DwnErrorCode.ProtocolsConfigureInvalidCrossProtocolRole,
304
304
  `cross-protocol role '${actionRule.role}' at protocol path '${childProtocolPath}' ` +
@@ -11,7 +11,7 @@ import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.j
11
11
 
12
12
  export class ProtocolsQueryHandler implements MethodHandler {
13
13
 
14
- constructor(private deps: HandlerDependencies) { }
14
+ constructor(private readonly deps: HandlerDependencies) { }
15
15
 
16
16
  public async handle({
17
17
  tenant,
@@ -14,7 +14,7 @@ import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.j
14
14
 
15
15
  export class RecordsCountHandler 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,
@@ -18,7 +18,7 @@ import { ResumableTaskName } from '../core/resumable-task-manager.js';
18
18
 
19
19
  export class RecordsDeleteHandler implements MethodHandler {
20
20
 
21
- constructor(private deps: HandlerDependencies) { }
21
+ constructor(private readonly deps: HandlerDependencies) { }
22
22
 
23
23
  public async handle({
24
24
  tenant,
@@ -18,7 +18,7 @@ import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.j
18
18
 
19
19
  export class RecordsQueryHandler implements MethodHandler {
20
20
 
21
- constructor(private deps: HandlerDependencies) { }
21
+ constructor(private readonly deps: HandlerDependencies) { }
22
22
 
23
23
  public async handle({
24
24
  tenant,
@@ -20,7 +20,7 @@ import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.j
20
20
 
21
21
  export class RecordsReadHandler implements MethodHandler {
22
22
 
23
- constructor(private deps: HandlerDependencies) { }
23
+ constructor(private readonly deps: HandlerDependencies) { }
24
24
 
25
25
  public async handle({
26
26
  tenant,
@@ -115,11 +115,7 @@ export class RecordsReadHandler implements MethodHandler {
115
115
  }
116
116
 
117
117
  let data;
118
- if (matchedRecordsWrite.encodedData !== undefined) {
119
- const dataBytes = Encoder.base64UrlToBytes(matchedRecordsWrite.encodedData);
120
- data = DataStream.fromBytes(dataBytes);
121
- delete matchedRecordsWrite.encodedData;
122
- } else {
118
+ if (matchedRecordsWrite.encodedData === undefined) {
123
119
  const result = await this.deps.dataStore!.get(tenant, matchedRecordsWrite.recordId, matchedRecordsWrite.descriptor.dataCid);
124
120
  if (result?.dataStream === undefined) {
125
121
  // The message envelope exists but the record data is unavailable (e.g., evicted
@@ -131,6 +127,10 @@ export class RecordsReadHandler implements MethodHandler {
131
127
  };
132
128
  }
133
129
  data = result.dataStream;
130
+ } else {
131
+ const dataBytes = Encoder.base64UrlToBytes(matchedRecordsWrite.encodedData);
132
+ data = DataStream.fromBytes(dataBytes);
133
+ delete matchedRecordsWrite.encodedData;
134
134
  }
135
135
 
136
136
  const recordsReadReply: RecordsReadReply = {
@@ -20,7 +20,7 @@ import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.j
20
20
 
21
21
  export class RecordsSubscribeHandler implements MethodHandler {
22
22
 
23
- constructor(private deps: HandlerDependencies) { }
23
+ constructor(private readonly deps: HandlerDependencies) { }
24
24
 
25
25
  public async handle({
26
26
  tenant,
@@ -97,7 +97,7 @@ export class RecordsSubscribeHandler implements MethodHandler {
97
97
  const gapInfo = (error as any).gapInfo as ProgressGapInfo | undefined;
98
98
  return {
99
99
  status : { code: 410, detail: 'Progress token gap' },
100
- error : gapInfo !== undefined ? { code: 'ProgressGap' as const, ...gapInfo } : undefined,
100
+ error : gapInfo === undefined ? undefined : { code: 'ProgressGap' as const, ...gapInfo },
101
101
  };
102
102
  }
103
103
  return messageReplyFromError(error, 500);
@@ -27,7 +27,7 @@ type HandlerArgs = { tenant: string, message: RecordsWriteMessage, dataStream?:
27
27
 
28
28
  export class RecordsWriteHandler implements MethodHandler {
29
29
 
30
- constructor(private deps: HandlerDependencies) { }
30
+ constructor(private readonly deps: HandlerDependencies) { }
31
31
 
32
32
  public async handle({
33
33
  tenant,
@@ -106,7 +106,7 @@ export class RecordsWriteHandler implements MethodHandler {
106
106
  if (isInitial) {
107
107
  const hasInlineData = !!(newestExistingMessage as any).encodedData;
108
108
  const hasStoredData = this.deps.dataStore
109
- ? !!(await this.deps.dataStore.get(tenant, recordsWrite.message.recordId, message.descriptor.dataCid!))
109
+ ? !!(await this.deps.dataStore.get(tenant, recordsWrite.message.recordId, message.descriptor.dataCid))
110
110
  : false;
111
111
  existingLacksData = !hasInlineData && !hasStoredData;
112
112
  }
@@ -121,9 +121,9 @@ export class RecordsWriteHandler implements MethodHandler {
121
121
 
122
122
  // Look up the core protocol (if any) for the incoming message so that lifecycle hooks
123
123
  // can be dispatched generically rather than checking for specific protocol URIs.
124
- const coreProtocol = message.descriptor.protocol !== undefined
125
- ? this.deps.coreProtocols?.get(message.descriptor.protocol)
126
- : undefined;
124
+ const coreProtocol = message.descriptor.protocol === undefined
125
+ ? undefined
126
+ : this.deps.coreProtocols?.get(message.descriptor.protocol);
127
127
 
128
128
  try {
129
129
  if (newestExistingMessage?.descriptor.method === DwnMethodName.Delete) {
@@ -148,11 +148,8 @@ export class RecordsWriteHandler implements MethodHandler {
148
148
  let isLatestBaseState = false;
149
149
  let messageWithOptionalEncodedData = message as RecordsQueryReplyEntry;
150
150
 
151
- if (dataStream !== undefined) {
152
- messageWithOptionalEncodedData = await this.processMessageWithDataStream(tenant, message, dataStream);
153
- isLatestBaseState = true;
154
- } else {
155
- // else data stream is NOT provided
151
+ if (dataStream === undefined) {
152
+ // data stream is NOT provided
156
153
 
157
154
  // if the incoming message is not an initial write, and no dataStream is provided, we would allow it provided it passes validation
158
155
  // processMessageWithoutDataStream() abstracts that logic
@@ -161,6 +158,9 @@ export class RecordsWriteHandler implements MethodHandler {
161
158
  messageWithOptionalEncodedData = await this.processMessageWithoutDataStream(tenant, message, newestExistingWrite );
162
159
  isLatestBaseState = true;
163
160
  }
161
+ } else {
162
+ messageWithOptionalEncodedData = await this.processMessageWithDataStream(tenant, message, dataStream);
163
+ isLatestBaseState = true;
164
164
  }
165
165
 
166
166
  const indexes = await recordsWrite.constructIndexes(isLatestBaseState);
@@ -252,14 +252,14 @@ export class RecordsWriteHandler implements MethodHandler {
252
252
  // if data is below the threshold, we store it within MessageStore
253
253
  if (message.descriptor.dataSize <= DwnConstant.maxDataSizeAllowedToBeEncoded) {
254
254
  // validate data integrity before setting.
255
- const dataBytes = await DataStream.toBytes(dataStream!);
255
+ const dataBytes = await DataStream.toBytes(dataStream);
256
256
  const dataCid = await Cid.computeDagPbCidFromBytes(dataBytes);
257
257
  RecordsWriteHandler.validateDataIntegrity(message.descriptor.dataCid, message.descriptor.dataSize, dataCid, dataBytes.length);
258
258
 
259
259
  // Dispatch schema validation to the core protocol, if applicable.
260
- const coreProtocol = message.descriptor.protocol !== undefined
261
- ? this.deps.coreProtocols?.get(message.descriptor.protocol)
262
- : undefined;
260
+ const coreProtocol = message.descriptor.protocol === undefined
261
+ ? undefined
262
+ : this.deps.coreProtocols?.get(message.descriptor.protocol);
263
263
  if (coreProtocol?.validateRecord !== undefined) {
264
264
  coreProtocol.validateRecord(message, dataBytes);
265
265
  }
@@ -304,13 +304,13 @@ export class RecordsWriteHandler implements MethodHandler {
304
304
 
305
305
  if (dataSize <= DwnConstant.maxDataSizeAllowedToBeEncoded) {
306
306
  // we encode the data from the original write if it is smaller than the data-store threshold
307
- if (newestExistingWrite.encodedData !== undefined) {
308
- messageWithOptionalEncodedData.encodedData = newestExistingWrite.encodedData;
309
- } else {
307
+ if (newestExistingWrite.encodedData === undefined) {
310
308
  throw new DwnError(
311
309
  DwnErrorCode.RecordsWriteMissingEncodedDataInPrevious,
312
310
  `No dataStream was provided and unable to get data from previous message`
313
311
  );
312
+ } else {
313
+ messageWithOptionalEncodedData.encodedData = newestExistingWrite.encodedData;
314
314
  }
315
315
  } else {
316
316
  // else just make sure the data is in the data store
@@ -396,7 +396,7 @@ export class RecordsWriteHandler implements MethodHandler {
396
396
  ruleSet = ruleSet[pathSegments[i]] as typeof ruleSet;
397
397
  }
398
398
 
399
- if (ruleSet === undefined || ruleSet.$squash !== true) {
399
+ if (ruleSet?.$squash !== true) {
400
400
  return;
401
401
  }
402
402
 
package/src/index.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  export type { DwnConfig } from './dwn.js';
3
3
  export type { EventListener, EventLog, EventLogEntry, EventLogReadOptions, EventLogReadResult, EventLogSubscribeOptions, EventSubscription, MessageEvent, ProgressGapInfo, ProgressGapReason, ProgressToken, SubscriptionEose, SubscriptionEvent, SubscriptionListener, SubscriptionMessage, SubscriptionReply } from './types/subscriptions.js';
4
4
  export type { AuthorizationModel, Descriptor, DelegatedGrantRecordsWriteMessage, GenericMessage, GenericMessageReply, GenericSignaturePayload, MessageSort, MessageSubscription, Pagination, QueryResultEntry, Status } from './types/message-types.js';
5
- export type { MessagesFilter, MessagesReadMessage as MessagesReadMessage, MessagesReadReply as MessagesReadReply, MessagesReadReplyEntry as MessagesReadReplyEntry, MessagesReadDescriptor, MessagesSubscribeDescriptor, MessagesSubscribeMessage, MessagesSubscribeReply, MessagesSubscribeMessageOptions, MessagesSyncAction, MessagesSyncDescriptor, MessagesSyncDiffEntry, MessagesSyncMessage, MessagesSyncReply } from './types/messages-types.js';
5
+ export type { MessagesFilter, MessagesReadMessage, MessagesReadReply, MessagesReadReplyEntry, MessagesReadDescriptor, MessagesSubscribeDescriptor, MessagesSubscribeMessage, MessagesSubscribeReply, MessagesSubscribeMessageOptions, MessagesSyncAction, MessagesSyncDescriptor, MessagesSyncDiffEntry, MessagesSyncMessage, MessagesSyncReply } from './types/messages-types.js';
6
6
  export type { GT, LT, Filter, FilterValue, KeyValues, EqualFilter, OneOfFilter, RangeFilter, RangeCriterion, PaginationCursor, QueryOptions, RangeValue, StartsWithFilter } from './types/query-types.js';
7
7
  export type { ProtocolsConfigureDescriptor, ProtocolDefinition, ProtocolTypes, ProtocolRuleSet, ProtocolsQueryFilter, ProtocolsConfigureMessage, ProtocolsQueryMessage, ProtocolsQueryReply, ProtocolActionRule, ProtocolDeliveryStrategy, ProtocolPathEncryption, ProtocolsQueryDescriptor, ProtocolRecordLimitDefinition, ProtocolSizeDefinition, ProtocolTagsDefinition, ProtocolTagSchema, ProtocolType, ProtocolUses } from './types/protocols-types.js';
8
8
  export { ProtocolRecordLimitStrategy } from './types/protocols-types.js';
@@ -30,8 +30,8 @@ export { DwnConstant } from './core/dwn-constant.js';
30
30
  export { DwnError, DwnErrorCode } from './core/dwn-error.js';
31
31
  export { DwnInterfaceName, DwnMethodName } from './enums/dwn-interface-method.js';
32
32
  export { Encoder } from './utils/encoder.js';
33
- export { MessagesSubscribe as MessagesSubscribe } from './interfaces/messages-subscribe.js';
34
- export type { MessagesSubscribeOptions as MessagesSubscribeOptions } from './interfaces/messages-subscribe.js';
33
+ export { MessagesSubscribe } from './interfaces/messages-subscribe.js';
34
+ export type { MessagesSubscribeOptions } from './interfaces/messages-subscribe.js';
35
35
  export { Encryption, ContentEncryptionAlgorithm, KeyAgreementAlgorithm } from './utils/encryption.js';
36
36
  export type { JweEncryption, JweRecipient, JweRecipientHeader, JweProtectedHeader, JweKeyUnwrapPayload } from './utils/encryption.js';
37
37
  export { RecordsWrite } from './interfaces/records-write.js';
@@ -40,8 +40,8 @@ export { executeUnlessAborted } from './utils/abort.js';
40
40
  export { Jws } from './utils/jws.js';
41
41
  export type { KeyMaterial, PrivateKeyJwk, PublicKeyJwk, Jwk } from './types/jose-types.js';
42
42
  export { Message } from './core/message.js';
43
- export { MessagesRead as MessagesRead } from './interfaces/messages-read.js';
44
- export type { MessagesReadOptions as MessagesReadOptions } from './interfaces/messages-read.js';
43
+ export { MessagesRead } from './interfaces/messages-read.js';
44
+ export type { MessagesReadOptions } from './interfaces/messages-read.js';
45
45
  export { MessagesSync } from './interfaces/messages-sync.js';
46
46
  export type { MessagesSyncOptions } from './interfaces/messages-sync.js';
47
47
  export type { UnionMessageReply } from './core/message-reply.js';
@@ -377,16 +377,8 @@ export class ProtocolsConfigure extends AbstractMessage<ProtocolsConfigureMessag
377
377
  for (let j = i + 1; j < actionRules.length; j++) {
378
378
  const otherActionRule = actionRules[j];
379
379
 
380
- if (actionRule.who !== undefined) {
381
- if (actionRule.who === otherActionRule.who && actionRule.of === otherActionRule.of) {
382
- throw new DwnError(
383
- DwnErrorCode.ProtocolsConfigureDuplicateActorInRuleSet,
384
- `More than one action rule per actor ${actionRule.who} of ${actionRule.of} ` +
385
- `not allowed within a rule set: ${JSON.stringify(actionRule)}`
386
- );
387
- }
388
- } else {
389
- // else implicitly a role-based action rule
380
+ if (actionRule.who === undefined) {
381
+ // implicitly a role-based action rule
390
382
 
391
383
  if (actionRule.role === otherActionRule.role) {
392
384
  throw new DwnError(
@@ -394,6 +386,14 @@ export class ProtocolsConfigure extends AbstractMessage<ProtocolsConfigureMessag
394
386
  `More than one action rule per role ${actionRule.role} not allowed within a rule set: ${JSON.stringify(actionRule)}`
395
387
  );
396
388
  }
389
+ } else {
390
+ if (actionRule.who === otherActionRule.who && actionRule.of === otherActionRule.of) {
391
+ throw new DwnError(
392
+ DwnErrorCode.ProtocolsConfigureDuplicateActorInRuleSet,
393
+ `More than one action rule per actor ${actionRule.who} of ${actionRule.of} ` +
394
+ `not allowed within a rule set: ${JSON.stringify(actionRule)}`
395
+ );
396
+ }
397
397
  }
398
398
  }
399
399
  }
@@ -497,7 +497,7 @@ export class ProtocolsConfigure extends AbstractMessage<ProtocolsConfigureMessag
497
497
  }
498
498
 
499
499
  // validate alias exists in `uses`
500
- if (uses === undefined || uses[parsed.alias] === undefined) {
500
+ if (uses?.[parsed.alias] === undefined) {
501
501
  throw new DwnError(
502
502
  DwnErrorCode.ProtocolsConfigureInvalidRefAlias,
503
503
  `'$ref' alias '${parsed.alias}' at protocol path '${ruleSetProtocolPath}' does not exist in the 'uses' map.`
@@ -543,7 +543,7 @@ export class ProtocolsConfigure extends AbstractMessage<ProtocolsConfigureMessag
543
543
  );
544
544
  }
545
545
 
546
- if (uses === undefined || uses[parsed.alias] === undefined) {
546
+ if (uses?.[parsed.alias] === undefined) {
547
547
  const errorCode = fieldName === 'role'
548
548
  ? DwnErrorCode.ProtocolsConfigureInvalidCrossProtocolRole
549
549
  : DwnErrorCode.ProtocolsConfigureInvalidCrossProtocolOf;
@@ -110,7 +110,7 @@ export class RecordsDelete extends AbstractMessage<RecordsDeleteMessage> {
110
110
  * @param messageStore Used to check if the grant has been revoked.
111
111
  */
112
112
  public async authorizeDelegate(recordsWriteToDelete: RecordsWriteMessage, messageStore: MessageStore): Promise<void> {
113
- const delegatedGrant = PermissionGrant.parse(this.message.authorization!.authorDelegatedGrant!);
113
+ const delegatedGrant = PermissionGrant.parse(this.message.authorization.authorDelegatedGrant!);
114
114
  await RecordsGrantAuthorization.authorizeDelete({
115
115
  recordsDeleteMessage : this.message,
116
116
  recordsWriteToDelete,
@@ -135,9 +135,9 @@ export type CreateFromOptions = {
135
135
  * NOTE: Unable to extend `AbstractMessage` directly because the incompatible `_message` type, which is not just a generic `<M>` type.
136
136
  */
137
137
  export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
138
- private parentContextId: string | undefined;
138
+ private readonly parentContextId: string | undefined;
139
139
 
140
- private _message: InternalRecordsWriteMessage;
140
+ private readonly _message: InternalRecordsWriteMessage;
141
141
  /**
142
142
  * Valid JSON message representing this RecordsWrite.
143
143
  * @throws `DwnErrorCode.RecordsWriteMissingSigner` if the message is not signed yet.
@@ -232,10 +232,10 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
232
232
  if (message.authorization.ownerSignature !== undefined) {
233
233
  // if the message authorization contains owner delegated grant, the owner would be the grantor of the grant
234
234
  // else the owner would be the signer of the owner signature
235
- if (message.authorization.ownerDelegatedGrant !== undefined) {
236
- this._owner = Message.getSigner(message.authorization.ownerDelegatedGrant);
237
- } else {
235
+ if (message.authorization.ownerDelegatedGrant === undefined) {
238
236
  this._owner = Jws.getSignerDid(message.authorization.ownerSignature.signatures[0]);
237
+ } else {
238
+ this._owner = Message.getSigner(message.authorization.ownerDelegatedGrant);
239
239
  }
240
240
 
241
241
  this._ownerSignaturePayload = Jws.decodePlainObjectPayload(message.authorization.ownerSignature);
@@ -321,7 +321,7 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
321
321
  protocol : normalizeProtocolUrl(options.protocol),
322
322
  protocolPath : options.protocolPath,
323
323
  recipient : options.recipient,
324
- schema : options.schema !== undefined ? normalizeSchemaUrl(options.schema) : undefined,
324
+ schema : options.schema === undefined ? undefined : normalizeSchemaUrl(options.schema),
325
325
  tags : options.tags,
326
326
  parentId : RecordsWrite.getRecordIdFromContextId(options.parentContextId),
327
327
  dataCid,
@@ -524,11 +524,11 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
524
524
  // compute delegated grant ID and author if delegated grant is given
525
525
  let delegatedGrantId;
526
526
  let authorDid;
527
- if (delegatedGrant !== undefined) {
527
+ if (delegatedGrant === undefined) {
528
+ authorDid = Jws.extractDid(signer.keyId);
529
+ } else {
528
530
  delegatedGrantId = await Message.getCid(delegatedGrant);
529
531
  authorDid = Jws.getSignerDid(delegatedGrant.authorization.signature.signatures[0]);
530
- } else {
531
- authorDid = Jws.extractDid(signer.keyId);
532
532
  }
533
533
 
534
534
  const descriptor = this._message.descriptor;
@@ -549,7 +549,7 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
549
549
  // `signature` generation
550
550
  const signature = await createSignerSignature({
551
551
  recordId : this._message.recordId,
552
- contextId : this._message.contextId!, // contextId is computed just above, always defined here
552
+ contextId : this._message.contextId, // contextId is computed just above, always defined here
553
553
  descriptorCid,
554
554
  attestation : this._message.attestation,
555
555
  encryption : this._message.encryption,
@@ -872,7 +872,7 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
872
872
  public static async fetchInitialRecordsWrite(
873
873
  messageStore: MessageStore, tenant: string, recordId: string
874
874
  ): Promise<RecordsWrite | undefined> {
875
- return fetchInitialRecordsWrite(messageStore, tenant, recordId) as Promise<RecordsWrite | undefined>;
875
+ return fetchInitialRecordsWrite(messageStore, tenant, recordId);
876
876
  }
877
877
 
878
878
  /** Delegate to `fetchInitialRecordsWriteMessage` in `records-write-query.ts`. */
@@ -4,7 +4,7 @@ import type { MessageSigner } from '../../../types/signer.js';
4
4
  import { Encoder } from '../../../utils/encoder.js';
5
5
 
6
6
  export class GeneralJwsBuilder {
7
- private jws: GeneralJws;
7
+ private readonly jws: GeneralJws;
8
8
 
9
9
  private constructor(jws: GeneralJws) {
10
10
  this.jws = jws;
@@ -1,7 +1,7 @@
1
1
  import type { Cache } from '../../../types/cache.js';
2
2
  import type { GeneralJws } from '../../../types/jws-types.js';
3
3
  import type { PublicKeyJwk } from '../../../types/jose-types.js';
4
- import type { DidResolver, DidVerificationMethod } from '@enbox/dids';
4
+ import type { DidResolutionResult, DidResolver, DidVerificationMethod } from '@enbox/dids';
5
5
 
6
6
  import { Encoder } from '../../../utils/encoder.js';
7
7
  import { Jws } from '../../../utils/jws.js';
@@ -89,12 +89,19 @@ export class GeneralJwsVerifier {
89
89
 
90
90
  /**
91
91
  * Gets the public key given a fully qualified key ID (`kid`) by resolving the DID to its DID Document.
92
+ *
93
+ * Throws `GeneralJwsVerifierGetPublicKeyNotFound` when the public key cannot be located.
94
+ * The error message distinguishes between two failure modes so callers can tell them apart:
95
+ * 1. DID resolution failed (network error, DID not published, method not supported, etc.).
96
+ * The resolution metadata error code and message are included.
97
+ * 2. DID resolved successfully but the requested `kid` does not match any verification
98
+ * method in the DID Document. The list of available verification method IDs is included.
92
99
  */
93
100
  private static async getPublicKey(kid: string, didResolver: DidResolver): Promise<PublicKeyJwk> {
94
101
  // `resolve` throws exception if DID is invalid, DID method is not supported,
95
102
  // or resolving DID fails
96
103
  const did = Jws.extractDid(kid);
97
- const { didDocument } = await didResolver.resolve(did);
104
+ const { didDocument, didResolutionMetadata } = await didResolver.resolve(did);
98
105
  const { verificationMethod: verificationMethods = [] } = didDocument || {};
99
106
 
100
107
  let verificationMethod: DidVerificationMethod | undefined;
@@ -110,7 +117,10 @@ export class GeneralJwsVerifier {
110
117
  }
111
118
 
112
119
  if (!verificationMethod) {
113
- throw new DwnError(DwnErrorCode.GeneralJwsVerifierGetPublicKeyNotFound, 'public key needed to verify signature not found in DID Document');
120
+ throw new DwnError(
121
+ DwnErrorCode.GeneralJwsVerifierGetPublicKeyNotFound,
122
+ GeneralJwsVerifier.buildPublicKeyNotFoundMessage(kid, did, didDocument, didResolutionMetadata, verificationMethods),
123
+ );
114
124
  }
115
125
 
116
126
  validateJsonSchema('JwkVerificationMethod', verificationMethod);
@@ -119,4 +129,35 @@ export class GeneralJwsVerifier {
119
129
 
120
130
  return publicJwk as PublicKeyJwk;
121
131
  }
132
+
133
+ /**
134
+ * Builds a diagnostic error message for `GeneralJwsVerifierGetPublicKeyNotFound`.
135
+ * Surfaces resolution metadata or available verification methods so operators can
136
+ * distinguish between an unreachable DID and a `kid` mismatch.
137
+ */
138
+ private static buildPublicKeyNotFoundMessage(
139
+ kid: string,
140
+ did: string,
141
+ didDocument: DidResolutionResult['didDocument'],
142
+ didResolutionMetadata: DidResolutionResult['didResolutionMetadata'] | undefined,
143
+ verificationMethods: DidVerificationMethod[],
144
+ ): string {
145
+ const resolutionError = didResolutionMetadata?.error;
146
+ if (resolutionError !== undefined) {
147
+ const resolutionErrorMessage = didResolutionMetadata?.errorMessage;
148
+ const detail = resolutionErrorMessage ? `${resolutionError} — ${resolutionErrorMessage}` : resolutionError;
149
+ return `unable to resolve DID '${did}' to verify signature with kid '${kid}': ${detail}`;
150
+ }
151
+
152
+ if (didDocument === undefined || didDocument === null) {
153
+ return `DID Document not found for '${did}' when verifying signature with kid '${kid}'`;
154
+ }
155
+
156
+ if (verificationMethods.length === 0) {
157
+ return `DID Document for '${did}' has no verification methods to verify signature with kid '${kid}'`;
158
+ }
159
+
160
+ const availableIds = verificationMethods.map((method) => method.id).join(', ');
161
+ return `public key for kid '${kid}' not found in DID Document for '${did}' (available verification methods: [${availableIds}])`;
162
+ }
122
163
  }
@@ -605,7 +605,7 @@ export class PermissionsProtocol implements CoreProtocol {
605
605
  */
606
606
  private static validateTags(requestOrGrant: RecordsWriteMessage, scopedProtocol: string): void {
607
607
  // the protocol tag must be included with the record.
608
- if (requestOrGrant.descriptor.tags === undefined || requestOrGrant.descriptor.tags.protocol === undefined) {
608
+ if (requestOrGrant.descriptor.tags?.protocol === undefined) {
609
609
  throw new DwnError(
610
610
  DwnErrorCode.PermissionsProtocolValidateScopeMissingProtocolTag,
611
611
  'Permission grants must have a `tags` property that contains a protocol tag'
@@ -31,7 +31,7 @@ type SerializedLeafNode = {
31
31
  type SerializedNode = SerializedInternalNode | SerializedLeafNode;
32
32
 
33
33
  export class SMTStoreLevel implements SMTNodeStore {
34
- private db: LevelWrapper<string>;
34
+ private readonly db: LevelWrapper<string>;
35
35
  private nodesPartition!: LevelWrapper<string>;
36
36
  private metaPartition!: LevelWrapper<string>;
37
37
  private initialized = false;
@@ -8,7 +8,7 @@ import type { Hash, SMTNode, SMTNodeStore } from '../types/smt-types.js';
8
8
  import { hashToHex } from './smt-utils.js';
9
9
 
10
10
  export class SMTStoreMemory implements SMTNodeStore {
11
- private nodes: Map<string, SMTNode> = new Map();
11
+ private readonly nodes: Map<string, SMTNode> = new Map();
12
12
  private root: Hash | undefined;
13
13
 
14
14
  async open(): Promise<void> {