keri-ts 2.0.0 → 2.1.0

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 (229) hide show
  1. package/esm/keri/npm/src/acdc/chaining.js +223 -89
  2. package/esm/keri/npm/src/acdc/observing.js +2 -2
  3. package/esm/keri/npm/src/acdc/regbasing.js +20 -29
  4. package/esm/keri/npm/src/acdc/regengine.js +4 -6
  5. package/esm/keri/npm/src/acdc/registering.js +13 -10
  6. package/esm/keri/npm/src/acdc/registraring.js +4 -9
  7. package/esm/keri/npm/src/acdc/salting.js +127 -25
  8. package/esm/keri/npm/src/acdc/unblinding.js +2 -4
  9. package/esm/keri/npm/src/app/bootstrap/oobiery.js +1 -1
  10. package/esm/keri/npm/src/app/credentials/root-replicating.js +123 -0
  11. package/esm/keri/npm/src/app/credentials/verifying.js +21 -3
  12. package/esm/keri/npm/src/app/delivery/forwarding.js +49 -7
  13. package/esm/keri/npm/src/app/exchanges/exchanging.js +11 -12
  14. package/esm/keri/npm/src/app/identity/configing.js +17 -43
  15. package/esm/keri/npm/src/app/identity/habbing.js +54 -35
  16. package/esm/keri/npm/src/app/identity/keeping.js +1 -1
  17. package/esm/keri/npm/src/app/identity/lmdb-habery.js +12 -0
  18. package/esm/keri/npm/src/app/ipex/ipex-graph.js +7 -70
  19. package/esm/keri/npm/src/app/ipex/ipex-grouping.js +8 -5
  20. package/esm/keri/npm/src/app/ipex/ipex-v2.js +21 -5
  21. package/esm/keri/npm/src/app/ipex/ipexing.js +1 -1
  22. package/esm/keri/npm/src/app/mailbox/mailboxing.js +5 -9
  23. package/esm/keri/npm/src/app/multisig/group-members.js +14 -0
  24. package/esm/keri/npm/src/app/multisig/grouping.js +4 -3
  25. package/esm/keri/npm/src/app/multisig/multisig-workflows.js +7 -2
  26. package/esm/keri/npm/src/app/notifications/notifying.js +5 -9
  27. package/esm/keri/npm/src/app/protocol/protocol-processing.js +35 -3
  28. package/esm/keri/npm/src/app/queries/witness-inquisitor.js +2 -2
  29. package/esm/keri/npm/src/app/runtime/agent-runtime.js +7 -10
  30. package/esm/keri/npm/src/app/transport/byte-source.js +6 -42
  31. package/esm/keri/npm/src/app/transport/cesr-egress.js +77 -13
  32. package/esm/keri/npm/src/app/transport/file-bytes.js +41 -0
  33. package/esm/keri/npm/src/app/transport/http-messenger.js +14 -9
  34. package/esm/keri/npm/src/app/transport/message-source.js +1 -1
  35. package/esm/keri/npm/src/app/transport/messengering.js +3 -4
  36. package/esm/keri/npm/src/app/transport/node-http-client.js +21 -0
  37. package/esm/keri/npm/src/app/transport/tcp-dialer.js +14 -0
  38. package/esm/keri/npm/src/app/witness/receipt-client.js +2 -2
  39. package/esm/keri/npm/src/cli/common/context.js +2 -2
  40. package/esm/keri/npm/src/cli/common/existing.js +3 -5
  41. package/esm/keri/npm/src/cli/credentials/ipex.js +2 -1
  42. package/esm/keri/npm/src/cli/endpoints/oobi-clean.js +4 -3
  43. package/esm/keri/npm/src/cli/endpoints/oobi.js +2 -2
  44. package/esm/keri/npm/src/cli/identity/challenge.js +2 -2
  45. package/esm/keri/npm/src/cli/identity/incept.js +2 -2
  46. package/esm/keri/npm/src/cli/identity/init.js +4 -3
  47. package/esm/keri/npm/src/cli/identity/interact.js +2 -2
  48. package/esm/keri/npm/src/cli/identity/rotate.js +2 -2
  49. package/esm/keri/npm/src/cli/messaging/exchange.js +2 -2
  50. package/esm/keri/npm/src/cli/messaging/multisig.js +61 -3
  51. package/esm/keri/npm/src/cli/tools/annotate.js +2 -1
  52. package/esm/keri/npm/src/cli/tools/benchmark.js +2 -1
  53. package/esm/keri/npm/src/cli/tools/db-dump.js +1 -4
  54. package/esm/keri/npm/src/core/bytes.js +9 -0
  55. package/esm/keri/npm/src/core/kel/delegation-ancestry.js +92 -0
  56. package/esm/keri/npm/src/core/kel/eventing.js +1 -2
  57. package/esm/keri/npm/src/core/kel/kever.js +11 -9
  58. package/esm/keri/npm/src/core/mailbox/kram-policy.js +2 -3
  59. package/esm/keri/npm/src/core/mailbox/kram-pruning.js +15 -22
  60. package/esm/keri/npm/src/core/mailbox/kram-staging.js +2 -2
  61. package/esm/keri/npm/src/core/routing.js +2 -2
  62. package/esm/keri/npm/src/db/basing.js +149 -203
  63. package/esm/keri/npm/src/db/core/dber.js +1062 -0
  64. package/esm/keri/npm/src/db/core/index.js +4 -2
  65. package/esm/keri/npm/src/db/core/lmdb-opener.js +30 -0
  66. package/esm/keri/npm/src/db/core/lmdber.js +199 -1067
  67. package/esm/keri/npm/src/db/core/memstore.js +532 -0
  68. package/esm/keri/npm/src/db/core/path-manager.js +109 -223
  69. package/esm/keri/npm/src/db/core/store-owner.js +104 -0
  70. package/esm/keri/npm/src/db/core/webdber.js +252 -0
  71. package/esm/keri/npm/src/db/escrowing.js +2 -2
  72. package/esm/keri/npm/src/db/exchange/exchange-nests.js +3 -2
  73. package/esm/keri/npm/src/db/keeping.js +27 -121
  74. package/esm/keri/npm/src/db/koming.js +1 -1
  75. package/esm/keri/npm/src/db/lmdb-stores.js +68 -0
  76. package/esm/keri/npm/src/db/lmdb.js +6 -0
  77. package/esm/keri/npm/src/db/mailbox/mailboxing.js +12 -65
  78. package/esm/keri/npm/src/db/noting.js +11 -55
  79. package/esm/keri/npm/src/db/reger.js +43 -105
  80. package/esm/keri/npm/src/db/replay/witness-replay.js +2 -20
  81. package/esm/keri/npm/src/db/subing.js +1 -1
  82. package/esm/keri/npm/src/npm/db-lmdb.js +3 -0
  83. package/esm/keri/npm/src/npm/runtime-node.js +3 -0
  84. package/esm/keri/npm/src/runtime/index.js +9 -10
  85. package/esm/keri/npm/src/runtime/node.js +14 -0
  86. package/esm/keri/npm/src/vdr/eventing.js +1 -1
  87. package/esm/keri/npm/src/vdr/tel-publication.js +3 -3
  88. package/esm/keri/npm/src/version.js +2 -2
  89. package/package.json +11 -4
  90. package/types/acdc/chaining.d.ts +56 -6
  91. package/types/acdc/chaining.d.ts.map +1 -1
  92. package/types/acdc/regbasing.d.ts +7 -6
  93. package/types/acdc/regbasing.d.ts.map +1 -1
  94. package/types/acdc/regengine.d.ts.map +1 -1
  95. package/types/acdc/registering.d.ts +8 -4
  96. package/types/acdc/registering.d.ts.map +1 -1
  97. package/types/acdc/registraring.d.ts.map +1 -1
  98. package/types/acdc/salting.d.ts +53 -6
  99. package/types/acdc/salting.d.ts.map +1 -1
  100. package/types/acdc/unblinding.d.ts.map +1 -1
  101. package/types/app/credentials/root-replicating.d.ts +85 -0
  102. package/types/app/credentials/root-replicating.d.ts.map +1 -0
  103. package/types/app/credentials/verifying.d.ts +2 -1
  104. package/types/app/credentials/verifying.d.ts.map +1 -1
  105. package/types/app/delivery/forwarding.d.ts +10 -0
  106. package/types/app/delivery/forwarding.d.ts.map +1 -1
  107. package/types/app/exchanges/exchanging.d.ts +2 -0
  108. package/types/app/exchanges/exchanging.d.ts.map +1 -1
  109. package/types/app/identity/configing.d.ts +7 -5
  110. package/types/app/identity/configing.d.ts.map +1 -1
  111. package/types/app/identity/habbing.d.ts +23 -5
  112. package/types/app/identity/habbing.d.ts.map +1 -1
  113. package/types/app/identity/keeping.d.ts +1 -1
  114. package/types/app/identity/lmdb-habery.d.ts +6 -0
  115. package/types/app/identity/lmdb-habery.d.ts.map +1 -0
  116. package/types/app/ipex/ipex-graph.d.ts +4 -4
  117. package/types/app/ipex/ipex-graph.d.ts.map +1 -1
  118. package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
  119. package/types/app/ipex/ipex-v2.d.ts +11 -2
  120. package/types/app/ipex/ipex-v2.d.ts.map +1 -1
  121. package/types/app/ipex/ipexing.d.ts +3 -0
  122. package/types/app/ipex/ipexing.d.ts.map +1 -1
  123. package/types/app/mailbox/mailboxing.d.ts +1 -1
  124. package/types/app/mailbox/mailboxing.d.ts.map +1 -1
  125. package/types/app/multisig/group-members.d.ts +9 -0
  126. package/types/app/multisig/group-members.d.ts.map +1 -1
  127. package/types/app/multisig/grouping.d.ts.map +1 -1
  128. package/types/app/multisig/multisig-workflows.d.ts +2 -1
  129. package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
  130. package/types/app/notifications/notifying.d.ts +1 -1
  131. package/types/app/notifications/notifying.d.ts.map +1 -1
  132. package/types/app/protocol/parsering.d.ts +3 -1
  133. package/types/app/protocol/parsering.d.ts.map +1 -1
  134. package/types/app/protocol/protocol-processing.d.ts +2 -0
  135. package/types/app/protocol/protocol-processing.d.ts.map +1 -1
  136. package/types/app/runtime/agent-runtime.d.ts +7 -0
  137. package/types/app/runtime/agent-runtime.d.ts.map +1 -1
  138. package/types/app/transport/byte-source.d.ts +13 -10
  139. package/types/app/transport/byte-source.d.ts.map +1 -1
  140. package/types/app/transport/cesr-egress.d.ts +21 -7
  141. package/types/app/transport/cesr-egress.d.ts.map +1 -1
  142. package/types/app/transport/file-bytes.d.ts +11 -0
  143. package/types/app/transport/file-bytes.d.ts.map +1 -0
  144. package/types/app/transport/http-client.d.ts +3 -0
  145. package/types/app/transport/http-client.d.ts.map +1 -1
  146. package/types/app/transport/http-messenger.d.ts +15 -10
  147. package/types/app/transport/http-messenger.d.ts.map +1 -1
  148. package/types/app/transport/message-source.d.ts +1 -1
  149. package/types/app/transport/messengering.d.ts +2 -2
  150. package/types/app/transport/messengering.d.ts.map +1 -1
  151. package/types/app/transport/node-http-client.d.ts +10 -0
  152. package/types/app/transport/node-http-client.d.ts.map +1 -0
  153. package/types/app/transport/tcp-dialer.d.ts +21 -0
  154. package/types/app/transport/tcp-dialer.d.ts.map +1 -0
  155. package/types/cli/common/existing.d.ts.map +1 -1
  156. package/types/cli/credentials/ipex.d.ts.map +1 -1
  157. package/types/cli/endpoints/oobi-clean.d.ts.map +1 -1
  158. package/types/cli/identity/init.d.ts.map +1 -1
  159. package/types/cli/index.d.ts +1 -1
  160. package/types/cli/index.d.ts.map +1 -1
  161. package/types/cli/messaging/multisig.d.ts +10 -1
  162. package/types/cli/messaging/multisig.d.ts.map +1 -1
  163. package/types/cli/tools/annotate.d.ts.map +1 -1
  164. package/types/cli/tools/benchmark.d.ts.map +1 -1
  165. package/types/cli/tools/db-dump.d.ts.map +1 -1
  166. package/types/core/bytes.d.ts +2 -0
  167. package/types/core/bytes.d.ts.map +1 -1
  168. package/types/core/kel/delegation-ancestry.d.ts +41 -0
  169. package/types/core/kel/delegation-ancestry.d.ts.map +1 -0
  170. package/types/core/kel/eventing.d.ts.map +1 -1
  171. package/types/core/kel/kever.d.ts +5 -4
  172. package/types/core/kel/kever.d.ts.map +1 -1
  173. package/types/core/mailbox/kram-policy.d.ts.map +1 -1
  174. package/types/core/mailbox/kram-pruning.d.ts +1 -3
  175. package/types/core/mailbox/kram-pruning.d.ts.map +1 -1
  176. package/types/db/basing.d.ts +14 -23
  177. package/types/db/basing.d.ts.map +1 -1
  178. package/types/db/core/dber.d.ts +505 -0
  179. package/types/db/core/dber.d.ts.map +1 -0
  180. package/types/db/core/index.d.ts +4 -2
  181. package/types/db/core/index.d.ts.map +1 -1
  182. package/types/db/core/lmdb-opener.d.ts +17 -0
  183. package/types/db/core/lmdb-opener.d.ts.map +1 -0
  184. package/types/db/core/lmdber.d.ts +60 -383
  185. package/types/db/core/lmdber.d.ts.map +1 -1
  186. package/types/db/core/memstore.d.ts +129 -0
  187. package/types/db/core/memstore.d.ts.map +1 -0
  188. package/types/db/core/path-manager.d.ts +22 -45
  189. package/types/db/core/path-manager.d.ts.map +1 -1
  190. package/types/db/core/store-owner.d.ts +59 -0
  191. package/types/db/core/store-owner.d.ts.map +1 -0
  192. package/types/db/core/webdber.d.ts +127 -0
  193. package/types/db/core/webdber.d.ts.map +1 -0
  194. package/types/db/escrowing.d.ts +3 -3
  195. package/types/db/escrowing.d.ts.map +1 -1
  196. package/types/db/exchange/exchange-nests.d.ts.map +1 -1
  197. package/types/db/keeping.d.ts +9 -23
  198. package/types/db/keeping.d.ts.map +1 -1
  199. package/types/db/koming.d.ts +7 -8
  200. package/types/db/koming.d.ts.map +1 -1
  201. package/types/db/lmdb-stores.d.ts +45 -0
  202. package/types/db/lmdb-stores.d.ts.map +1 -0
  203. package/types/db/lmdb.d.ts +7 -0
  204. package/types/db/lmdb.d.ts.map +1 -0
  205. package/types/db/mailbox/mailboxing.d.ts +7 -21
  206. package/types/db/mailbox/mailboxing.d.ts.map +1 -1
  207. package/types/db/noting.d.ts +7 -12
  208. package/types/db/noting.d.ts.map +1 -1
  209. package/types/db/reger.d.ts +7 -11
  210. package/types/db/reger.d.ts.map +1 -1
  211. package/types/db/replay/witness-replay.d.ts +0 -2
  212. package/types/db/replay/witness-replay.d.ts.map +1 -1
  213. package/types/db/subing.d.ts +24 -25
  214. package/types/db/subing.d.ts.map +1 -1
  215. package/types/npm/db-lmdb.d.ts +4 -0
  216. package/types/npm/db-lmdb.d.ts.map +1 -0
  217. package/types/npm/runtime-node.d.ts +4 -0
  218. package/types/npm/runtime-node.d.ts.map +1 -0
  219. package/types/runtime/index.d.ts +9 -10
  220. package/types/runtime/index.d.ts.map +1 -1
  221. package/types/runtime/node.d.ts +15 -0
  222. package/types/runtime/node.d.ts.map +1 -0
  223. package/types/version.d.ts +2 -2
  224. package/esm/keri/npm/src/acdc/relating.js +0 -59
  225. package/esm/keri/npm/src/db/baser-defaults.js +0 -11
  226. package/types/acdc/relating.d.ts +0 -21
  227. package/types/acdc/relating.d.ts.map +0 -1
  228. package/types/db/baser-defaults.d.ts +0 -5
  229. package/types/db/baser-defaults.d.ts.map +0 -1
@@ -1,5 +1,6 @@
1
1
  import { ValidationError } from "../../core/errors.js";
2
- import { createNoter, Notice } from "../../db/noting.js";
2
+ import { openOwner } from "../../db/core/store-owner.js";
3
+ import { Noter, Notice } from "../../db/noting.js";
3
4
  import { Signaler } from "./signaling.js";
4
5
  export function notice(attrs, options = {}) {
5
6
  const dt = typeof options.dt === "string"
@@ -17,19 +18,14 @@ export function notice(attrs, options = {}) {
17
18
  /** Derive sidecar-open options from the owning `Habery` path/layout settings. */
18
19
  export function noterOptionsForHabery(hby, options = {}) {
19
20
  return {
20
- name: hby.name,
21
- base: hby.base,
22
- temp: hby.temp,
23
- headDirPath: hby.headDirPath,
24
- compat: hby.compat,
25
- readonly: hby.readonly,
26
- reopen: true,
21
+ ...hby.storeIdentity(),
27
22
  ...options,
28
23
  };
29
24
  }
30
25
  /** Open the notification sidecar that belongs to one `Habery`. */
31
26
  export function* openNoterForHabery(hby, options = {}) {
32
- return yield* createNoter(noterOptionsForHabery(hby, options));
27
+ const identity = noterOptionsForHabery(hby, options);
28
+ return yield* openOwner(new Noter(hby.opener.create(Noter.Family, identity)), "Noter", identity);
33
29
  }
34
30
  /**
35
31
  * Signed durable controller notifications with transient `/notification` pings.
@@ -1,11 +1,24 @@
1
1
  import { call } from "effection";
2
2
  import { Deck } from "../../core/deck.js";
3
+ import { ValidationError } from "../../core/errors.js";
3
4
  import { Kevery } from "../../core/kel/eventing.js";
5
+ import { consoleLogger } from "../../core/logger.js";
4
6
  import { BasicReplyRouteHandler, Revery } from "../../core/routing.js";
5
7
  import { Exchanger } from "../exchanges/exchanging.js";
6
8
  import { QueryReplies } from "../queries/query-replies.js";
7
9
  import { runtimeTurn } from "../runtime/runtime-turn.js";
8
10
  import { dispatchEnvelope, envelopeFromFrame, queryEnvelopeFromDispatch, } from "./parsering.js";
11
+ /**
12
+ * Identify a refusal of one already-extracted message, which must not end its stream.
13
+ *
14
+ * KERIpy's parser resumes after any non-extraction exception. This is deliberately narrower:
15
+ * infrastructure failures, programmer errors and cancellation must still reach the input owner.
16
+ * A dispatch-side ParserError also propagates, because it indicates corrupt local state and
17
+ * skipping would advance a mailbox cursor past a message that was never processed.
18
+ */
19
+ function isInvalidMessageError(error) {
20
+ return error instanceof ValidationError;
21
+ }
9
22
  /**
10
23
  * Dispatch to synchronous semantic owners and publish their committed output.
11
24
  *
@@ -140,6 +153,8 @@ export class ProtocolProcessor {
140
153
  * @param options Local intake policy, hosted mailbox provenance and whether to advance escrows.
141
154
  * @param kvy Input-specific Kevery in this domain; defaults to the shared owner.
142
155
  * @returns Exact dispatch result and current mailbox authorization at its synchronous query decision.
156
+ * A message refused by validation after extraction is an `invalidMessage` drop, so the caller
157
+ * continues with the next frame as KERIpy's parser does.
143
158
  * @throws Domain mismatch, infrastructure/handler or cleanup errors propagate; publication still runs in the dispatch finalizer.
144
159
  */
145
160
  dispatch(frame, { local = this.kvy.local, mailboxAid, escrows = false } = {}, kvy = this.kvy) {
@@ -151,9 +166,26 @@ export class ProtocolProcessor {
151
166
  const self = this;
152
167
  return call(function* () {
153
168
  try {
154
- const result = yield* dispatchEnvelope(envelopeFromFrame(frame, local), self.rvy, kvy, self.exc, self.tvy ?? undefined, self.vry ?? undefined, mailboxAid, self.kvy, // One authoritative v2 sender policy and KRAM intake across all inputs.
155
- self.registry ?? undefined, self.qvy);
156
- const mailboxQueryAuthorized = result.envelope.serder.route === "mbx"
169
+ const envelope = envelopeFromFrame(frame, local);
170
+ let result;
171
+ let invalid = false;
172
+ try {
173
+ result = yield* dispatchEnvelope(envelope, self.rvy, kvy, self.exc, self.tvy ?? undefined, self.vry ?? undefined, mailboxAid, self.kvy, // One authoritative v2 sender policy and KRAM intake across all inputs.
174
+ self.registry ?? undefined, self.qvy);
175
+ }
176
+ catch (error) {
177
+ if (!isInvalidMessageError(error))
178
+ throw error;
179
+ invalid = true;
180
+ consoleLogger.warn("Skipping invalid message", {
181
+ said: envelope.serder.said,
182
+ ilk: envelope.serder.ilk,
183
+ route: envelope.serder.route,
184
+ detail: error.message,
185
+ });
186
+ result = { envelope, decision: { kind: "drop", reason: "invalidMessage", detail: error.message } };
187
+ }
188
+ const mailboxQueryAuthorized = !invalid && result.envelope.serder.route === "mbx"
157
189
  && kvy.isMailboxQueryAuthorized(queryEnvelopeFromDispatch(result.envelope));
158
190
  // Capture this request's facts before optional escrows can suspend or change key state.
159
191
  self.publishCues();
@@ -19,7 +19,7 @@ import { introduce } from "../delivery/introducing.js";
19
19
  import { runtimeTurn } from "../runtime/runtime-turn.js";
20
20
  import { CesrHttpRefusal } from "../transport/cesr-egress.js";
21
21
  import { HTTPMessenger } from "../transport/http-messenger.js";
22
- import { TCPMessenger } from "../transport/tcp-messenger.js";
22
+ import { requireTcpDialer } from "../transport/tcp-dialer.js";
23
23
  import { TransportError } from "../transport/transport-error.js";
24
24
  /** First eligible role used by KERIpy WitnessInquisitor before random endpoint selection. */
25
25
  const QUERY_ROLE_PRIORITY = [Roles.controller, Roles.agent, Roles.witness];
@@ -309,7 +309,7 @@ export class WitnessInquisitor {
309
309
  // Only this attempt owns signed bytes; failed attempts are never automatically resubmitted.
310
310
  const http = this.http, clock = this.clock;
311
311
  if (new URL(delivery.url).protocol === "tcp:") {
312
- yield* new TCPMessenger(delivery.url, clock, this.protocol).send(delivery.body, {
312
+ yield* requireTcpDialer(http).messenger(delivery.url, clock, this.protocol).send(delivery.body, {
313
313
  signal: controller.signal,
314
314
  replies: true,
315
315
  local: true,
@@ -11,9 +11,10 @@ import { Kevery } from "../../core/kel/eventing.js";
11
11
  import { Kramer } from "../../core/mailbox/kraming.js";
12
12
  import { CREDENTIAL_MAILBOX_TOPIC, DELEGATE_MAILBOX_TOPIC, RECEIPT_MAILBOX_TOPIC, REPLAY_MAILBOX_TOPIC, REPLY_MAILBOX_TOPIC, } from "../../core/mailbox/mailbox-topics.js";
13
13
  import { Revery } from "../../core/routing.js";
14
+ import { openOwner } from "../../db/core/store-owner.js";
14
15
  import { Mailboxer } from "../../db/mailbox/mailboxing.js";
15
16
  import { Noter } from "../../db/noting.js";
16
- import { createReger } from "../../db/reger.js";
17
+ import { Reger } from "../../db/reger.js";
17
18
  import { Regery as VdrRegery } from "../../vdr/credentialing.js";
18
19
  import { Tevery } from "../../vdr/eventing.js";
19
20
  import { Authenticator } from "../bootstrap/authenticating.js";
@@ -161,6 +162,7 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
161
162
  loadIpexHandlers(hby, exc, {
162
163
  notifier,
163
164
  registry: acdc?.store ?? null,
165
+ grantWalk: options.grantWalk,
164
166
  });
165
167
  // Construction adopts stored copies an earlier handler-less Exchanger left unescrowed.
166
168
  const registryRoot = options.registryRoots !== "refuse" && acdc ? new RegistryRoot(hby, acdc, notifier) : null;
@@ -324,7 +326,7 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
324
326
  function* openRuntimeNoter(hby) {
325
327
  return yield* resource(function* (provide) {
326
328
  const options = noterOptionsForHabery(hby);
327
- const store = new Noter(options);
329
+ const store = new Noter(hby.opener.create(Noter.Family, options));
328
330
  try {
329
331
  if (!(yield* store.reopen(options)))
330
332
  throw new DatabaseNotOpenError("Failed to open runtime Noter");
@@ -344,7 +346,7 @@ function* openRuntimeNoter(hby) {
344
346
  function* openRuntimeMailboxer(hby) {
345
347
  return yield* resource(function* (provide) {
346
348
  const options = mailboxerOptionsForHabery(hby);
347
- const store = new Mailboxer(options);
349
+ const store = new Mailboxer(hby.opener.create(Mailboxer.Family, options));
348
350
  try {
349
351
  if (!(yield* store.reopen(options)))
350
352
  throw new DatabaseNotOpenError("Failed to open runtime Mailboxer");
@@ -380,13 +382,8 @@ function* openAcdcRegeryForHabery(hby) {
380
382
  */
381
383
  function* openRegerForHabery(hby) {
382
384
  return yield* resource(function* (provide) {
383
- const store = yield* call(() => createReger({
384
- name: hby.name,
385
- base: hby.base,
386
- temp: hby.temp,
387
- headDirPath: hby.headDirPath,
388
- compat: hby.compat,
389
- }));
385
+ const identity = { name: hby.name, base: hby.base, temp: hby.temp };
386
+ const store = yield* openOwner(new Reger(hby.opener.create(Reger.Family, identity)), "Reger", identity);
390
387
  try {
391
388
  yield* provide(store);
392
389
  }
@@ -1,6 +1,8 @@
1
- /** Transport readers. Each operation owns its reader and joins cancellation. */
2
- /** Cancellation and chunk size for byte-array and file sources. */
3
- import * as dntShim from "../../_dnt.shims.js";
1
+ /**
2
+ * Host-neutral transport readers. Each operation owns its reader and joins
3
+ * cancellation. The local-file reader lives in `file-bytes.ts` because it
4
+ * needs host file access.
5
+ */
4
6
  /**
5
7
  * Adapt an already resident finite value into independent bounded parser chunks.
6
8
  *
@@ -81,44 +83,6 @@ export async function* streamBytes(stream, { signal } = {}) {
81
83
  throw errors[0];
82
84
  }
83
85
  }
84
- /**
85
- * Stream a local file with fixed-size owned buffers and close it on break or abort.
86
- *
87
- * @param path Local filesystem path opened read-only for this iteration.
88
- * @param options Optional cancellation and positive read buffer size in bytes; defaults to 65536.
89
- * @yields Owned buffers up to the selected chunk size until file EOF.
90
- * @throws Open/read failures or cancellation; the file closes on EOF, break or failure.
91
- */
92
- export async function* fileBytes(path, { signal, maxChunkBytes = 64 * 1024 } = {}) {
93
- checkLimit(maxChunkBytes);
94
- signal?.throwIfAborted();
95
- const file = await dntShim.Deno.open(path, { read: true });
96
- let closed = false;
97
- /** Interrupt a pending read and release the file exactly once. */
98
- const close = () => {
99
- if (!closed) {
100
- closed = true;
101
- file.close();
102
- }
103
- };
104
- signal?.addEventListener("abort", close, { once: true });
105
- try {
106
- while (true) {
107
- signal?.throwIfAborted();
108
- const chunk = new Uint8Array(maxChunkBytes);
109
- const size = await file.read(chunk);
110
- signal?.throwIfAborted();
111
- if (size === null)
112
- return;
113
- if (size > 0)
114
- yield chunk.subarray(0, size);
115
- }
116
- }
117
- finally {
118
- signal?.removeEventListener("abort", close);
119
- close();
120
- }
121
- }
122
86
  /**
123
87
  * Collect an explicitly finite operation; bulk ingress should consume its source directly.
124
88
  *
@@ -147,7 +111,7 @@ export async function collectBytes(source) {
147
111
  * @param limit Requested per-chunk byte count.
148
112
  * @throws RangeError unless the count is a positive safe integer.
149
113
  */
150
- function checkLimit(limit) {
114
+ export function checkLimit(limit) {
151
115
  if (!Number.isSafeInteger(limit) || limit < 1)
152
116
  throw new RangeError("Chunk size must be a positive safe integer");
153
117
  }
@@ -5,15 +5,19 @@
5
5
  * caller consumes that body before leaving the enclosing scope. Neither path
6
6
  * implicitly feeds successful response bytes into protocol processing.
7
7
  *
8
- * Match KERIpy's detached-attachment POST contract while retaining the exact
9
- * signed body. Only the known pre-intake Falcon media refusal permits a second
10
- * request; authentication/application failures and network errors are not retries.
8
+ * Match KERIpy HTTPMessenger's two wire shapes. A JSON/CBOR/MGPK frame is one
9
+ * detached-attachment POST retaining the exact signed body; only the known
10
+ * pre-intake Falcon media refusal permits a second request, and
11
+ * authentication/application failures and network errors are not retries.
12
+ * A native CESR frame (counter-prefixed body, text or binary domain) is one
13
+ * whole opaque PUT of the serialized frame, as KERIpy sends since PR 1751,
14
+ * because a native body is not JSON and cannot travel in the detached form.
11
15
  */
12
- import { attachmentPayload, byteString, collectPayload, parse, } from "cesr-ts";
16
+ import { attachmentPayload, byteString, collectPayload, framePayload, Kinds, parse, sniff, } from "cesr-ts";
13
17
  import { call, ensure, race, resource, scoped } from "effection";
14
18
  import { ValidationError } from "../../core/errors.js";
15
19
  import { abortable, cleanupFailures, throwOnAbort } from "../runtime/abortable.js";
16
- import { CESR_ATTACHMENT_HEADER, CESR_CONTENT_TYPE, CESR_DESTINATION_HEADER, KERIPY_CESR_JSON_CONTENT_TYPE, } from "./cesr-http.js";
20
+ import { buildCesrStreamRequest, CESR_ATTACHMENT_HEADER, CESR_CONTENT_TYPE, CESR_DESTINATION_HEADER, KERIPY_CESR_JSON_CONTENT_TYPE, } from "./cesr-http.js";
17
21
  /** Positive remote HTTP refusal, distinct from source, transport, storage and cleanup failure. */
18
22
  export class CesrHttpRefusal extends ValidationError {
19
23
  /**
@@ -108,19 +112,79 @@ function openFrameResponse(url, frame, http, options) {
108
112
  }
109
113
  });
110
114
  }
115
+ /**
116
+ * Recognize a frame whose body is native CESR rather than a JSON/CBOR/MGPK message.
117
+ * KERIpy HTTPMessenger decides by sniffing the message cold start for a counter in
118
+ * either domain; a hydrated native body carries kind CESR and its raw bytes begin
119
+ * with that fixed-field counter. Opaque fallback bodies without a counter stay ordinary.
120
+ *
121
+ * @param frame Parsed frame whose body kind and raw bytes decide the wire shape.
122
+ * @returns True when the frame must travel as one whole PUT instead of a detached POST.
123
+ */
124
+ export function isNativeCesrFrame(frame) {
125
+ if (frame.body.kind !== Kinds.cesr)
126
+ return false;
127
+ const cold = sniff(frame.body.raw);
128
+ return cold === "txt" || cold === "bny";
129
+ }
130
+ /**
131
+ * Select the qualification domain for one native frame's PUT body.
132
+ * The parser hydrates native bodies as qualified text, so the admitted attachment
133
+ * wire is the remaining evidence of a binary source; a bare body stays text.
134
+ *
135
+ * @param frame Native frame whose attachments retain their admitted domain.
136
+ * @returns The source domain KERIpy would have forwarded unchanged.
137
+ */
138
+ function nativeFrameDomain(frame) {
139
+ const evidence = frame.attachments[0]?.raw;
140
+ return evidence && sniff(evidence) === "bny" ? "bny" : "txt";
141
+ }
142
+ /**
143
+ * Prepare KERIpy HTTPMessenger's native-stream PUT for one frame.
144
+ * The shared serializer emits the frame's root genus selector, body and one
145
+ * attachment enclosure in the source domain, and that whole payload is the body
146
+ * with an explicit length, exactly as HTTPStreamMessenger sends a prepared stream.
147
+ * Detached CESR-ATTACHMENT/CESR-Genus headers do not apply and no legacy media
148
+ * fallback exists; caller authentication headers are retained.
149
+ *
150
+ * @param frame Native frame; its serialized bytes are the complete request body.
151
+ * @param options Destination, extra headers and optional cancellation.
152
+ * @returns One PUT request whose body is the serialized frame.
153
+ */
154
+ function* nativeFrameRequest(frame, options) {
155
+ const domain = nativeFrameDomain(frame);
156
+ const bytes = yield* abortable((signal) => collectPayload(framePayload(frame, { domain }), signal), options.signal);
157
+ const prepared = buildCesrStreamRequest(bytes, { destination: options.destination });
158
+ const headers = new Headers(options.headers);
159
+ headers.delete(CESR_DESTINATION_HEADER);
160
+ headers.delete(CESR_ATTACHMENT_HEADER);
161
+ headers.delete("CESR-Genus");
162
+ for (const [key, value] of Object.entries(prepared.headers))
163
+ headers.set(key, value);
164
+ headers.set("Content-Length", String(bytes.byteLength));
165
+ return {
166
+ method: "PUT",
167
+ redirect: "manual",
168
+ headers,
169
+ signal: options.signal,
170
+ body: prepared.body,
171
+ };
172
+ }
111
173
  /**
112
174
  * Prepare finite request bytes before opening any network attempt.
113
- * Ordinary POSTs put normalized text attachments in CESR-ATTACHMENT and send the
114
- * original body. CESR-Genus retains the observed counter context when stream framing is removed.
115
- * Requests retain
175
+ * A native frame yields exactly one whole PUT. Ordinary POSTs put normalized text
176
+ * attachments in CESR-ATTACHMENT and send the original body. CESR-Genus retains
177
+ * the observed counter context when stream framing is removed. Requests retain
116
178
  * caller authentication headers; sender-owned framing/destination headers replace
117
179
  * conflicting caller values. The fallback shares the prepared bytes.
118
180
  *
119
181
  * @param frame Parsed signed body and attachments; framing preserves the signed body bytes.
120
182
  * @param options Destination, extra headers and optional cancellation for ordinary signed-message POSTs.
121
- * @returns Current and legacy media choices sharing the same signed body.
183
+ * @returns One native PUT, or the current and legacy media choices sharing the same signed body.
122
184
  */
123
185
  function* frameRequests(frame, options) {
186
+ if (isNativeCesrFrame(frame))
187
+ return [yield* nativeFrameRequest(frame, options)];
124
188
  const header = byteString(yield* abortable((signal) => collectPayload(attachmentPayload(frame, { domain: "txt" }), signal), options.signal));
125
189
  const body = frame.body.raw;
126
190
  const types = [CESR_CONTENT_TYPE, KERIPY_CESR_JSON_CONTENT_TYPE];
@@ -202,8 +266,8 @@ function* sendFrame(url, frame, http, options) {
202
266
  }
203
267
  /**
204
268
  * Send a CESR source and throw on a completed peer refusal.
205
- * One parsed frame becomes one POST, and its request scope closes before the next
206
- * source pull. A refusal stops the sequence; prior frames may already be delivered.
269
+ * One parsed frame becomes one request (a detached POST, or one whole PUT for a
270
+ * native frame), and its request scope closes before the next source pull. A refusal stops the sequence; prior frames may already be delivered.
207
271
  * Cancellation aborts active work, joins any pending source pull and returns the
208
272
  * parser iterator before leaving. There is no automatic retry beyond media fallback.
209
273
  * A pending asynchronous source pull can finish after cancellation is requested;
@@ -224,8 +288,8 @@ export function* postCesr(url, source, http, options = {}) {
224
288
  }
225
289
  /**
226
290
  * Send frames sequentially and return a completed peer refusal as data.
227
- * One parsed frame becomes one POST, and its request scope closes before the next
228
- * source pull. A refusal stops the sequence; prior frames may already be delivered.
291
+ * One parsed frame becomes one request (a detached POST, or one whole PUT for a
292
+ * native frame), and its request scope closes before the next source pull. A refusal stops the sequence; prior frames may already be delivered.
229
293
  * Cancellation aborts active work, joins any pending source pull and returns the
230
294
  * parser iterator before leaving. There is no automatic retry beyond media fallback.
231
295
  *
@@ -0,0 +1,41 @@
1
+ /** Local-file byte source. Host-only: it opens files through `Deno`. */
2
+ import * as dntShim from "../../_dnt.shims.js";
3
+ import { checkLimit } from "./byte-source.js";
4
+ /**
5
+ * Stream a local file with fixed-size owned buffers and close it on break or abort.
6
+ *
7
+ * @param path Local filesystem path opened read-only for this iteration.
8
+ * @param options Optional cancellation and positive read buffer size in bytes; defaults to 65536.
9
+ * @yields Owned buffers up to the selected chunk size until file EOF.
10
+ * @throws Open/read failures or cancellation; the file closes on EOF, break or failure.
11
+ */
12
+ export async function* fileBytes(path, { signal, maxChunkBytes = 64 * 1024 } = {}) {
13
+ checkLimit(maxChunkBytes);
14
+ signal?.throwIfAborted();
15
+ const file = await dntShim.Deno.open(path, { read: true });
16
+ let closed = false;
17
+ /** Interrupt a pending read and release the file exactly once. */
18
+ const close = () => {
19
+ if (!closed) {
20
+ closed = true;
21
+ file.close();
22
+ }
23
+ };
24
+ signal?.addEventListener("abort", close, { once: true });
25
+ try {
26
+ while (true) {
27
+ signal?.throwIfAborted();
28
+ const chunk = new Uint8Array(maxChunkBytes);
29
+ const size = await file.read(chunk);
30
+ signal?.throwIfAborted();
31
+ if (size === null)
32
+ return;
33
+ if (size > 0)
34
+ yield chunk.subarray(0, size);
35
+ }
36
+ }
37
+ finally {
38
+ signal?.removeEventListener("abort", close);
39
+ close();
40
+ }
41
+ }
@@ -1,15 +1,18 @@
1
1
  import { chunkBytes } from "./byte-source.js";
2
2
  import { attemptPostCesr } from "./cesr-egress.js";
3
3
  /**
4
- * Send ordinary signed messages as ordered HTTP POSTs and finish response cleanup.
4
+ * Send ordinary signed messages as ordered HTTP requests and finish response cleanup.
5
5
  * Producers own preparation and Poster owns queued work. This component needs no
6
6
  * Habery, protocol processor, parser state, timer or response history.
7
7
  *
8
- * Corresponds to the ordinary POST role of KERIpy HTTPMessenger. Complete CESR
9
- * frames become separate POSTs: original signed body in the request body, text
10
- * attachments in CESR-ATTACHMENT. Only the recognized pre-intake media refusal
11
- * permits a second attempt with legacy media metadata. Successful response bytes
12
- * are drained and discarded; protocol receiving belongs to independent intake.
8
+ * Corresponds to KERIpy HTTPMessenger. Each complete CESR frame is one request,
9
+ * shaped by its body: a JSON/CBOR/MGPK frame is a POST with the original signed
10
+ * body in the request body and text attachments in CESR-ATTACHMENT, where only
11
+ * the recognized pre-intake media refusal permits a second attempt with legacy
12
+ * media metadata; a native CESR frame (counter-prefixed body) is one whole PUT of
13
+ * the serialized frame with Content-Length and CESR-DESTINATION, matching KERIpy
14
+ * since PR 1751 and without detached headers or media fallback. Successful response
15
+ * bytes are drained and discarded; protocol receiving belongs to independent intake.
13
16
  */
14
17
  export class HTTPMessenger {
15
18
  /** Bind one endpoint and request metadata; construction performs no I/O. */
@@ -42,9 +45,11 @@ export class HTTPMessenger {
42
45
  return this.sendSource((signal) => chunkBytes(msg, { signal }), options);
43
46
  }
44
47
  /**
45
- * Iterate ordinary messages into POSTs; this is not whole-stream PUT delivery.
46
- * A later malformed message cannot prevent an earlier valid POST. Parser,
47
- * transport, source and cleanup failures propagate; HTTP refusal is typed data.
48
+ * Iterate messages into one request each; this is not whole-stream PUT delivery.
49
+ * A multi-message native stream becomes successive per-frame PUTs, not KERIpy's
50
+ * single bulk PUT. A later malformed message cannot prevent an earlier valid
51
+ * request. Parser, transport, source and cleanup failures propagate; HTTP
52
+ * refusal is typed data.
48
53
  */
49
54
  sendSource(source, options = {}) {
50
55
  return attemptPostCesr(this.url, source, this.http, { ...this.options, ...options });
@@ -12,7 +12,7 @@ import { rethrowCleanupFailure } from "../runtime/abortable.js";
12
12
  * @param protocol Borrowed dispatcher over synchronous domain commits and correlated cue publication.
13
13
  * @param kvy Input-owned KEL processor bound to the same store, reply verifier and cue flow.
14
14
  * @param options Dispatch policy and optional upstream cancellation; defaults follow the shared processor.
15
- * @throws Parsing, dispatch and cleanup failures propagate after the pending pull and iterator cleanup join.
15
+ * @throws Parsing, infrastructure dispatch and cleanup failures propagate after the pending pull and iterator cleanup join; one invalid message does not.
16
16
  */
17
17
  export function* processMessages(source, protocol, kvy, options = {}) {
18
18
  const input = call(function* () {
@@ -9,8 +9,7 @@
9
9
  import { ValidationError } from "../../core/errors.js";
10
10
  import { HTTPMessenger } from "./http-messenger.js";
11
11
  import { HTTPStreamMessenger } from "./http-stream-messenger.js";
12
- import { TCPMessenger } from "./tcp-messenger.js";
13
- import { TCPStreamMessenger } from "./tcp-stream-messenger.js";
12
+ import { requireTcpDialer } from "./tcp-dialer.js";
14
13
  /** Choose HTTPS, HTTP, then TCP and reject a mismatched advertised scheme before I/O. */
15
14
  function endpointFrom(urls) {
16
15
  for (const scheme of ["https", "http", "tcp"]) {
@@ -43,7 +42,7 @@ function endpointFrom(urls) {
43
42
  export function messengerFrom(destination, urls, http, clock, headers) {
44
43
  const endpoint = endpointFrom(urls);
45
44
  if (endpoint.protocol === "tcp:")
46
- return new TCPMessenger(endpoint.href, clock);
45
+ return requireTcpDialer(http).messenger(endpoint.href, clock);
47
46
  return new HTTPMessenger(endpoint.href, http, { destination, headers });
48
47
  }
49
48
  /**
@@ -63,6 +62,6 @@ export function messengerFrom(destination, urls, http, clock, headers) {
63
62
  export function streamMessengerFrom(destination, urls, payload, http, clock, headers) {
64
63
  const endpoint = endpointFrom(urls);
65
64
  if (endpoint.protocol === "tcp:")
66
- return new TCPStreamMessenger(endpoint.href, clock, payload);
65
+ return requireTcpDialer(http).streamMessenger(endpoint.href, clock, payload);
67
66
  return new HTTPStreamMessenger(endpoint.href, http, payload, { destination, headers });
68
67
  }
@@ -0,0 +1,21 @@
1
+ /** HTTP client plus TCP egress, for hosts with sockets. */
2
+ import { FetchHttpClient } from "./http-client.js";
3
+ import { TCPMessenger } from "./tcp-messenger.js";
4
+ import { TCPStreamMessenger } from "./tcp-stream-messenger.js";
5
+ /** Dials TCP endpoints through `node:net`. */
6
+ export const nodeTcpDialer = {
7
+ messenger: (url, clock, protocol = null) => new TCPMessenger(url, clock, protocol),
8
+ streamMessenger: (url, clock, payload) => new TCPStreamMessenger(url, clock, payload),
9
+ };
10
+ /** A `FetchHttpClient` that can also reach `tcp:` endpoints. */
11
+ export class NodeHttpClient extends FetchHttpClient {
12
+ constructor() {
13
+ super(...arguments);
14
+ Object.defineProperty(this, "tcp", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: nodeTcpDialer
19
+ });
20
+ }
21
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Host seam for TCP egress.
3
+ *
4
+ * Browsers have no TCP, so `HttpClient` carries an optional dialer supplied by
5
+ * hosts that do. Code that reaches a `tcp:` endpoint asks for it here and fails
6
+ * clearly when this host cannot dial.
7
+ */
8
+ import { ValidationError } from "../../core/errors.js";
9
+ /** Return the host's dialer, or fail for a `tcp:` endpoint this host cannot reach. */
10
+ export function requireTcpDialer(http) {
11
+ if (!http.tcp)
12
+ throw new ValidationError("TCP endpoints are unavailable on this host.");
13
+ return http.tcp;
14
+ }
@@ -7,7 +7,7 @@ import { abortable } from "../runtime/abortable.js";
7
7
  import { collectBytes } from "../transport/byte-source.js";
8
8
  import { buildCesrRequest, CESR_CONTENT_TYPE, KERIPY_CESR_JSON_CONTENT_TYPE } from "../transport/cesr-http.js";
9
9
  import { HTTPMessenger } from "../transport/http-messenger.js";
10
- import { TCPMessenger } from "../transport/tcp-messenger.js";
10
+ import { requireTcpDialer } from "../transport/tcp-dialer.js";
11
11
  import { inspectReceiptMessage } from "./receipt-messages.js";
12
12
  const WitnessReceiptPollAttempts = 20;
13
13
  const WitnessReceiptPollDelayMs = 100;
@@ -71,7 +71,7 @@ export function* sendWitnessMessage(hab, witness, bytes, http, clock, protocol,
71
71
  }
72
72
  const parsed = new URL(url);
73
73
  if (parsed.protocol === "tcp:") {
74
- yield* new TCPMessenger(url, clock, protocol).send(bytes, {
74
+ yield* requireTcpDialer(http).messenger(url, clock, protocol).send(bytes, {
75
75
  replies: Boolean(protocol),
76
76
  local: true,
77
77
  });
@@ -1,6 +1,6 @@
1
1
  import { createAgentRuntime } from "../../app/runtime/agent-runtime.js";
2
2
  import { systemClock } from "../../app/runtime/runtime-clock.js";
3
- import { FetchHttpClient } from "../../app/transport/http-client.js";
3
+ import { NodeHttpClient } from "../../app/transport/node-http-client.js";
4
4
  import { ValidationError } from "../../core/errors.js";
5
5
  import { setupHby } from "./existing.js";
6
6
  /** Open an existing Habery for one CLI command and close it after the callback. */
@@ -54,7 +54,7 @@ export function* withExistingHab(args, alias, options, use) {
54
54
  */
55
55
  export function* withAgentRuntime(args, options, use) {
56
56
  return yield* withExistingHabery(args, options, function* ({ hby }) {
57
- const runtime = yield* (options.dependencies?.createAgentRuntime ?? createAgentRuntime)(hby, new FetchHttpClient(), systemClock, { kram: hby.cf?.get().kram });
57
+ const runtime = yield* (options.dependencies?.createAgentRuntime ?? createAgentRuntime)(hby, new NodeHttpClient(), systemClock, { kram: hby.cf?.get().kram });
58
58
  let failure;
59
59
  try {
60
60
  return yield* use({ hby, runtime });
@@ -1,6 +1,6 @@
1
1
  import * as dntShim from "../../_dnt.shims.js";
2
- import { createHabery } from "../../app/identity/habbing.js";
3
- import { createKeeper, Keeper } from "../../db/keeping.js";
2
+ import { createHabery } from "../../app/identity/lmdb-habery.js";
3
+ import { createKeeper, lmdbKeeper } from "../../db/lmdb-stores.js";
4
4
  import { readPasscode } from "./passcode.js";
5
5
  /**
6
6
  * Return true when the named keeper already exists and contains keeper globals.
@@ -10,7 +10,7 @@ import { readPasscode } from "./passcode.js";
10
10
  * keystore" without mutating on-disk state during the probe.
11
11
  */
12
12
  function* keeperExists(name, base = "", temp = false, headDirPath, compat = false) {
13
- const keeper = new Keeper({
13
+ const keeper = lmdbKeeper({
14
14
  name,
15
15
  base,
16
16
  temp,
@@ -22,8 +22,6 @@ function* keeperExists(name, base = "", temp = false, headDirPath, compat = fals
22
22
  name,
23
23
  base,
24
24
  temp,
25
- headDirPath,
26
- compat,
27
25
  reopen: true,
28
26
  readonly: true,
29
27
  });
@@ -9,7 +9,8 @@ import { isLocalGroupHab, localGroupMember } from "../../app/multisig/group-memb
9
9
  import { MULTISIG_EXN_ROUTE } from "../../app/multisig/grouping.js";
10
10
  import { abortable } from "../../app/runtime/abortable.js";
11
11
  import { runAgentRuntime, settleMailboxPollBatch } from "../../app/runtime/agent-runtime.js";
12
- import { chunkBytes, collectBytes, fileBytes } from "../../app/transport/byte-source.js";
12
+ import { chunkBytes, collectBytes } from "../../app/transport/byte-source.js";
13
+ import { fileBytes } from "../../app/transport/file-bytes.js";
13
14
  import { parseGvrsn } from "../../core/attachment-countering.js";
14
15
  import { ValidationError } from "../../core/errors.js";
15
16
  import { exchange } from "../../core/exchange/protocol-exchanging.js";
@@ -2,9 +2,10 @@
2
2
  import * as dntShim from "../../_dnt.shims.js";
3
3
  import { call } from "effection";
4
4
  import { DatabaseOperationError, ValidationError } from "../../core/errors.js";
5
- import { baserDefaults } from "../../db/baser-defaults.js";
6
- import { createBaser } from "../../db/basing.js";
5
+ import { Baser } from "../../db/basing.js";
6
+ import { lmdbDefaultsFor } from "../../db/core/lmdb-opener.js";
7
7
  import { PathManager } from "../../db/core/path-manager.js";
8
+ import { createBaser } from "../../db/lmdb-stores.js";
8
9
  import { parseBooleanOption, parseStringOption } from "../common/parsing.js";
9
10
  import { writeJsonLine } from "../common/rendering.js";
10
11
  /** Read a nonempty JSON list, preserving exact keys and first-seen order. */
@@ -56,7 +57,7 @@ export function* oobiCleanCommand(args) {
56
57
  const keys = yield* loadKeys(args.keyFile);
57
58
  // Resolve through ordinary path preparation before Baser can create data.mdb.
58
59
  // Empty directories are ordinary startup effects; missing databases still fail.
59
- const paths = new PathManager(options, baserDefaults(options.compat));
60
+ const paths = new PathManager(options, lmdbDefaultsFor(Baser.Family, options.compat));
60
61
  paths.name = name;
61
62
  yield* paths.reopen();
62
63
  const path = paths.path;