wire-mesh-core 1.13.4 → 1.15.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 (47) hide show
  1. package/dist/adapters/frame-codec.d.cts +1 -1
  2. package/dist/adapters/frame-codec.d.mts +1 -1
  3. package/dist/adapters/node-identity.d.cts +2 -2
  4. package/dist/adapters/node-identity.d.mts +2 -2
  5. package/dist/adapters/tcp-transport.d.cts +1 -1
  6. package/dist/adapters/tcp-transport.d.mts +1 -1
  7. package/dist/adapters/tls-transport.d.cts +1 -1
  8. package/dist/adapters/tls-transport.d.mts +1 -1
  9. package/dist/domain/capability-request.cjs +118 -0
  10. package/dist/domain/capability-request.d.cts +56 -0
  11. package/dist/domain/capability-request.d.mts +56 -0
  12. package/dist/domain/capability-request.mjs +115 -0
  13. package/dist/domain/device-id.d.cts +1 -1
  14. package/dist/domain/device-id.d.mts +1 -1
  15. package/dist/domain/handshake.d.cts +1 -1
  16. package/dist/domain/handshake.d.mts +1 -1
  17. package/dist/domain/mesh-session.d.cts +3 -3
  18. package/dist/domain/mesh-session.d.mts +3 -3
  19. package/dist/domain/relay-hub.d.cts +1 -1
  20. package/dist/domain/relay-hub.d.mts +1 -1
  21. package/dist/domain/revocation-view.cjs +1 -1
  22. package/dist/domain/revocation-view.d.cts +1 -1
  23. package/dist/domain/revocation-view.d.mts +1 -1
  24. package/dist/domain/revocation-view.mjs +1 -1
  25. package/dist/domain/room-token-verification.cjs +1 -1
  26. package/dist/domain/room-token-verification.d.cts +1 -1
  27. package/dist/domain/room-token-verification.d.mts +1 -1
  28. package/dist/domain/room-token-verification.mjs +1 -1
  29. package/dist/domain/tokens.cjs +5 -0
  30. package/dist/domain/tokens.d.cts +3 -3
  31. package/dist/domain/tokens.d.mts +3 -3
  32. package/dist/domain/tokens.mjs +5 -0
  33. package/dist/generated/protocol.cjs +4 -2
  34. package/dist/generated/protocol.d.cts +1 -1
  35. package/dist/generated/protocol.d.mts +1 -1
  36. package/dist/generated/protocol.mjs +4 -2
  37. package/dist/{identity-DvBEkcS9.d.mts → identity-D8iJZRZZ.d.mts} +1 -1
  38. package/dist/{identity-ijL0IsUT.d.cts → identity-DkEe1465.d.cts} +1 -1
  39. package/dist/ports/identity.d.cts +1 -1
  40. package/dist/ports/identity.d.mts +1 -1
  41. package/dist/ports/transport.d.cts +2 -29
  42. package/dist/ports/transport.d.mts +2 -29
  43. package/dist/{protocol-BwFGx9cg.d.cts → protocol-MnxTzpRP.d.cts} +2 -0
  44. package/dist/{protocol-BwFGx9cg.d.mts → protocol-MnxTzpRP.d.mts} +2 -0
  45. package/dist/transport-Da7GP9ya.d.cts +30 -0
  46. package/dist/transport-ESMXRz3s.d.mts +30 -0
  47. package/package.json +5 -1
@@ -1,4 +1,4 @@
1
- import { E as Frame } from "../protocol-BwFGx9cg.cjs";
1
+ import { E as Frame } from "../protocol-MnxTzpRP.cjs";
2
2
  //#region src/adapters/frame-codec.d.ts
3
3
  export declare function messageFromFrame(frame: Frame): Uint8Array<ArrayBuffer>;
4
4
  /** A frame that fails schema validation, caught separately from a decode failure so it can be dropped without disconnecting. */
@@ -1,4 +1,4 @@
1
- import { E as Frame } from "../protocol-BwFGx9cg.mjs";
1
+ import { E as Frame } from "../protocol-MnxTzpRP.mjs";
2
2
  //#region src/adapters/frame-codec.d.ts
3
3
  export declare function messageFromFrame(frame: Frame): Uint8Array<ArrayBuffer>;
4
4
  /** A frame that fails schema validation, caught separately from a decode failure so it can be dropped without disconnecting. */
@@ -1,5 +1,5 @@
1
- import { N as IdentityKey, b as DeviceId } from "../protocol-BwFGx9cg.cjs";
2
- import { t as IdentityPort } from "../identity-ijL0IsUT.cjs";
1
+ import { N as IdentityKey, b as DeviceId } from "../protocol-MnxTzpRP.cjs";
2
+ import { t as IdentityPort } from "../identity-DkEe1465.cjs";
3
3
  import { webcrypto } from "node:crypto";
4
4
  //#region src/adapters/node-identity.d.ts
5
5
  export declare function deriveDeviceId(publicKey: Uint8Array): Promise<DeviceId>;
@@ -1,5 +1,5 @@
1
- import { N as IdentityKey, b as DeviceId } from "../protocol-BwFGx9cg.mjs";
2
- import { t as IdentityPort } from "../identity-DvBEkcS9.mjs";
1
+ import { N as IdentityKey, b as DeviceId } from "../protocol-MnxTzpRP.mjs";
2
+ import { t as IdentityPort } from "../identity-D8iJZRZZ.mjs";
3
3
  import { webcrypto } from "node:crypto";
4
4
  //#region src/adapters/node-identity.d.ts
5
5
  export declare function deriveDeviceId(publicKey: Uint8Array): Promise<DeviceId>;
@@ -1,4 +1,4 @@
1
- import { Transport } from "../ports/transport.cjs";
1
+ import { r as Transport } from "../transport-Da7GP9ya.cjs";
2
2
  //#region src/adapters/tcp-transport.d.ts
3
3
  /** A Node net.Socket-based Transport: length-prefixed, CBOR-encoded frames over plain TCP -- matching Cascade's own transport shape, since interop with Cascade nodes is wire-mesh's stated goal. Framing (not TLS) is this adapter's own concern; a TLS-terminated variant is a separate adapter behind the same Transport contract. */
4
4
  export declare function createTcpTransport(): Transport;
@@ -1,4 +1,4 @@
1
- import { Transport } from "../ports/transport.mjs";
1
+ import { r as Transport } from "../transport-ESMXRz3s.mjs";
2
2
  //#region src/adapters/tcp-transport.d.ts
3
3
  /** A Node net.Socket-based Transport: length-prefixed, CBOR-encoded frames over plain TCP -- matching Cascade's own transport shape, since interop with Cascade nodes is wire-mesh's stated goal. Framing (not TLS) is this adapter's own concern; a TLS-terminated variant is a separate adapter behind the same Transport contract. */
4
4
  export declare function createTcpTransport(): Transport;
@@ -1,4 +1,4 @@
1
- import { Transport } from "../ports/transport.cjs";
1
+ import { r as Transport } from "../transport-Da7GP9ya.cjs";
2
2
  //#region src/adapters/tls-transport.d.ts
3
3
  export interface TlsIdentity {
4
4
  certificatePem: string;
@@ -1,4 +1,4 @@
1
- import { Transport } from "../ports/transport.mjs";
1
+ import { r as Transport } from "../transport-ESMXRz3s.mjs";
2
2
  //#region src/adapters/tls-transport.d.ts
3
3
  export interface TlsIdentity {
4
4
  certificatePem: string;
@@ -0,0 +1,118 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_generated_protocol = require("../generated/protocol.cjs");
3
+ const require_domain_tokens = require("./tokens.cjs");
4
+ //#region src/domain/capability-request.ts
5
+ /**
6
+ * The generic, capability-agnostic capability-request / capability-grant-ok primitive (wire-mesh#78, spec/management.cddl). Lifts core/room's own room.join shape -- an ungated ask, held open, a human (or any other domain-supplied decision) accepts or refuses, acceptance mints and returns a token on the same response -- out of that one domain so any capability can reuse it, not just room:member. core/room's own room-client.ts is the reference consumer: it rewires requestToJoin/createRoomRouter's room.join handling onto requestCapability/createCapabilityRequestHandler below, supplying room-specific extension fields (its member list) through this module's own extensions mechanism rather than this module knowing anything about rooms.
7
+ *
8
+ * Two responsibilities live here, split the same way tokens.ts and room-token-verification.ts already split verification concerns: requestCapability is the asking side (a thin wrapper over MeshSession.sendManageRequest, parsing the grant response), and createCapabilityRequestHandler is the receiving side (validates the incoming ask, arms a receiver-side timeout so an unanswered request never hangs a requester forever, and hands the decision to the domain).
9
+ */
10
+ const TOKEN_ID_BYTE_LENGTH = 16;
11
+ function randomTokenId() {
12
+ const bytes = new Uint8Array(TOKEN_ID_BYTE_LENGTH);
13
+ crypto.getRandomValues(bytes);
14
+ return bytes;
15
+ }
16
+ /**
17
+ * Builds a capability-request command per management.cddl. The outer `manage-command.verb` is the capability string itself -- the same value as this map's own `params.capability` field -- never a generic literal: capability-verb's own CDDL grammar is a closed alternation of colon-delimited `domain:noun` regexes (spec/tokens.cddl), so a bare literal like "capability" could never satisfy it, and routing by capability (the same way room.send/room.join already share the ROOM_MEMBER_CAPABILITY outer verb) is how a receiver's own per-capability handler knows which grant this ask is even for. `params.verb` is the fixed "capability.request" marker that distinguishes this ask from any other verb sharing the same outer capability (mirroring room.send/room.join's own inner `params.verb` split under one shared outer verb). `valid-until`, when given, bounds how long this ask is worth granting (wire-mesh#82) -- a receiver refuses outright once its own clock has passed it, rather than presenting a stale ask to a human for approval.
18
+ */
19
+ function buildCapabilityRequestCommand(capability, validUntil) {
20
+ return {
21
+ verb: capability,
22
+ params: {
23
+ verb: "capability.request",
24
+ capability,
25
+ ...validUntil !== void 0 ? { "valid-until": validUntil } : {}
26
+ }
27
+ };
28
+ }
29
+ /**
30
+ * Sends a deliberately ungated capability-request (no token field at all -- per management.cddl's own header comment, this primitive puts access control entirely in the receiving side's own decision, not a capability check on the request itself, the same design room.join already established). Resolves with the freshly granted capability-grant-ok on approval (its own open `* tstr => any` tail may carry domain-specific extension fields, e.g. core/room's member list -- a caller that needs those parses the raw result itself, the same way room-client.ts's own requestToJoin wrapper does); rejects on denial (an ordinary manage-error) or a malformed response.
31
+ *
32
+ * targetDevice and timeoutMs forward directly to MeshSession.sendManageRequest's own identically-named parameters (relay routing and a requester-side give-up bound respectively -- wire-mesh#80 is already implemented there, not duplicated here). validUntil, when given, is attached to the request itself (wire-mesh#82) so a slow-to-answer receiver -- or a relay/facilitator forwarding this request on the caller's behalf -- can refuse or drop a now-stale ask outright rather than holding or forwarding it.
33
+ */
34
+ async function requestCapability(session, capability, scope, targetDevice, timeoutMs, validUntil) {
35
+ const outcome = await session.sendManageRequest(buildCapabilityRequestCommand(capability, validUntil), scope, targetDevice, void 0, timeoutMs);
36
+ if (outcome.result !== "ok") throw new Error(`capability request for "${capability}" was refused (${outcome.code})`);
37
+ const parsed = require_generated_protocol.capabilityGrantOkSchema.safeParse(outcome);
38
+ if (!parsed.success) throw new Error(`capability request for "${capability}" response was malformed`);
39
+ return parsed.data;
40
+ }
41
+ /**
42
+ * Builds a reusable handler for one capability's incoming capability-requests. The returned function is the generic counterpart to room-client.ts's own (now capability-specific) handleRoomJoin: given one IncomingManageRequest, it refuses a request for the wrong capability or a malformed payload as `{result:"error", code:"malformed"}`, refuses an already-expired request (per its own `valid-until`, wire-mesh#82) as `{result:"error", code:"expired"}` without ever invoking onRequest, otherwise arms the receiver-side timeout described on CreateCapabilityRequestHandlerOptions.timeoutMs and calls onRequest so the domain can accept (minting a fresh token via mintCapabilityToken and responding `{result:"ok", "granted-token": token, ...extensions}`) or reject (an ordinary manage-error) via the event's own decide().
43
+ */
44
+ function createCapabilityRequestHandler(options) {
45
+ return async function handleCapabilityRequest(incoming) {
46
+ const parsed = require_generated_protocol.capabilityRequestSchema.safeParse(incoming.command.params);
47
+ if (!parsed.success || parsed.data.capability !== options.capability) {
48
+ await incoming.respond({
49
+ result: "error",
50
+ code: "malformed"
51
+ });
52
+ return;
53
+ }
54
+ const validUntil = parsed.data["valid-until"];
55
+ if (validUntil !== void 0 && validUntil <= options.clock.now()) {
56
+ await incoming.respond({
57
+ result: "error",
58
+ code: "expired"
59
+ });
60
+ return;
61
+ }
62
+ let settled = false;
63
+ const timeoutHandle = setTimeout(() => {
64
+ if (settled) return;
65
+ settled = true;
66
+ incoming.respond({
67
+ result: "error",
68
+ code: "timeout",
69
+ message: "no decision within the capability-request timeout"
70
+ }).catch(() => void 0);
71
+ }, options.timeoutMs);
72
+ timeoutHandle.unref();
73
+ options.onRequest({
74
+ scope: incoming.scope,
75
+ requesterDevice: options.bearerDevice,
76
+ async decide(decision) {
77
+ if (settled) return;
78
+ settled = true;
79
+ clearTimeout(timeoutHandle);
80
+ if (decision.kind === "reject") {
81
+ await incoming.respond({
82
+ result: "error",
83
+ code: "denied",
84
+ ...decision.reason !== void 0 ? { message: decision.reason } : {}
85
+ });
86
+ return;
87
+ }
88
+ const verdict = await require_domain_tokens.mintCapabilityToken({
89
+ identity: options.identity,
90
+ clock: options.clock,
91
+ tokenId: randomTokenId(),
92
+ bearer: options.bearerDevice,
93
+ capability: decision.capability,
94
+ scope: incoming.scope,
95
+ expires: decision.expires,
96
+ ...decision.delegationsRemaining !== void 0 ? { delegationsRemaining: decision.delegationsRemaining } : {}
97
+ });
98
+ if (!verdict.ok) {
99
+ await incoming.respond({
100
+ result: "error",
101
+ code: "mint_failed"
102
+ });
103
+ return;
104
+ }
105
+ const grantedToken = verdict.token;
106
+ await incoming.respond({
107
+ result: "ok",
108
+ "granted-token": grantedToken,
109
+ ...decision.extensions ?? {}
110
+ });
111
+ }
112
+ });
113
+ };
114
+ }
115
+ //#endregion
116
+ exports.buildCapabilityRequestCommand = buildCapabilityRequestCommand;
117
+ exports.createCapabilityRequestHandler = createCapabilityRequestHandler;
118
+ exports.requestCapability = requestCapability;
@@ -0,0 +1,56 @@
1
+ import { P as ManageCommand, a as CapabilityScope, b as DeviceId, r as CapabilityGrantOk } from "../protocol-MnxTzpRP.cjs";
2
+ import { t as IdentityPort } from "../identity-DkEe1465.cjs";
3
+ import { t as Clock } from "../clock-DiSx-WKM.cjs";
4
+ import { IncomingManageRequest, MeshSession } from "./mesh-session.cjs";
5
+ //#region src/domain/capability-request.d.ts
6
+ /**
7
+ * Builds a capability-request command per management.cddl. The outer `manage-command.verb` is the capability string itself -- the same value as this map's own `params.capability` field -- never a generic literal: capability-verb's own CDDL grammar is a closed alternation of colon-delimited `domain:noun` regexes (spec/tokens.cddl), so a bare literal like "capability" could never satisfy it, and routing by capability (the same way room.send/room.join already share the ROOM_MEMBER_CAPABILITY outer verb) is how a receiver's own per-capability handler knows which grant this ask is even for. `params.verb` is the fixed "capability.request" marker that distinguishes this ask from any other verb sharing the same outer capability (mirroring room.send/room.join's own inner `params.verb` split under one shared outer verb). `valid-until`, when given, bounds how long this ask is worth granting (wire-mesh#82) -- a receiver refuses outright once its own clock has passed it, rather than presenting a stale ask to a human for approval.
8
+ */
9
+ export declare function buildCapabilityRequestCommand(capability: string, validUntil?: number): ManageCommand;
10
+ /**
11
+ * Sends a deliberately ungated capability-request (no token field at all -- per management.cddl's own header comment, this primitive puts access control entirely in the receiving side's own decision, not a capability check on the request itself, the same design room.join already established). Resolves with the freshly granted capability-grant-ok on approval (its own open `* tstr => any` tail may carry domain-specific extension fields, e.g. core/room's member list -- a caller that needs those parses the raw result itself, the same way room-client.ts's own requestToJoin wrapper does); rejects on denial (an ordinary manage-error) or a malformed response.
12
+ *
13
+ * targetDevice and timeoutMs forward directly to MeshSession.sendManageRequest's own identically-named parameters (relay routing and a requester-side give-up bound respectively -- wire-mesh#80 is already implemented there, not duplicated here). validUntil, when given, is attached to the request itself (wire-mesh#82) so a slow-to-answer receiver -- or a relay/facilitator forwarding this request on the caller's behalf -- can refuse or drop a now-stale ask outright rather than holding or forwarding it.
14
+ */
15
+ export declare function requestCapability(session: Readonly<MeshSession>, capability: string, scope: Readonly<CapabilityScope>, targetDevice?: DeviceId, timeoutMs?: number, validUntil?: number): Promise<CapabilityGrantOk>;
16
+ /**
17
+ * A receiver's decision on one incoming capability-request, mirroring room-client.ts's own (now capability-specific) RoomJoinDecision, generalized to any capability: "accept" mints and returns a fresh token; "reject" sends an ordinary manage-error carrying an optional human-readable reason.
18
+ */
19
+ export type CapabilityGrantDecision = {
20
+ kind: "accept";
21
+ /** The capability the minted token actually carries -- usually, but not necessarily, the same string the request itself asked for (a receiver is free to grant something narrower). */
22
+ capability: string;
23
+ expires: number;
24
+ delegationsRemaining?: number;
25
+ /** Fields the domain wants merged onto the `{result:"ok", "granted-token": token, ...}` response, riding capability-grant-ok's own open `* tstr => any` tail -- the mechanism core/room's own room-join-ok uses for its `members` field, generalized so this module never needs to know what any particular capability's own grant response should additionally carry. Omit for a capability (e.g. a bare exec grant) whose response needs nothing beyond the token itself. */
26
+ extensions?: Record<string, unknown>;
27
+ } | {
28
+ kind: "reject";
29
+ reason?: string;
30
+ };
31
+ /** One incoming, not-yet-expired capability-request, surfaced for the domain to accept or reject via decide(). */
32
+ export interface CapabilityGrantRequestEvent {
33
+ /** The scope this request's own manage-request-frame carries -- e.g. core/room's `{kind:"room", path: roomPath}` -- passed through unchanged so the domain can inspect it (a room handler reads `.path` back out) without this module needing to know its shape. */
34
+ scope: Readonly<CapabilityScope>;
35
+ /** The peer device-id authenticated on the connection this request arrived over -- the requester, and so the future bearer of any token minted on acceptance. Same role as RoomRouterOptions.peerDevice / RoomJoinRequestEvent.requesterDevice. */
36
+ requesterDevice: DeviceId;
37
+ /** Resolves this request with the domain's decision. Settles the request's response exactly once: whichever of a real decide() call or the handler's own receiver-side timeout comes first wins, and the other is a no-op -- the same single-settle guarantee agent-comms' own PendingConnection timer/accept/reject/disconnect race already established (ported here, not reinvented). */
38
+ decide: (decision: Readonly<CapabilityGrantDecision>) => Promise<void>;
39
+ }
40
+ export interface CreateCapabilityRequestHandlerOptions {
41
+ /** The capability this handler grants. Checked against both the incoming request's own `params.capability` field (a mismatch is refused as malformed rather than trusted -- nothing about manage-command.verb structurally guarantees params.capability agrees with it) and used as the scope this handler is willing to act on at all; a caller wanting to grant several distinct capabilities over one session constructs one handler per capability, the same way core/room constructs one handler for `room:member` and nothing else. */
42
+ capability: string;
43
+ identity: IdentityPort;
44
+ clock: Clock;
45
+ /** The peer device-id authenticated on this session's own connection -- the requester, and so the future bearer of any token this handler mints. One handler is constructed per session for the same reason one RoomRouter is (RoomRouterOptions.peerDevice): MeshSession exposes no way for domain code to learn the authenticated peer independently. */
46
+ bearerDevice: DeviceId;
47
+ /** Receiver-side auto-reject window (wire-mesh#81): how long an incoming request may sit awaiting the domain's decision before this side responds with a real manage-error timeout rather than leaving the requester's own sendManageRequest hanging indefinitely. Ported from agent-comms' PendingConnection pattern (`wire-mesh-transport.ts`'s `pendingConnectionTimeoutMs` / `expirePendingConnection`): an unref'd timer so a stray one can never by itself keep the process alive, cleared the instant decide() is actually called so it can never fire after the request has already been answered. IncomingManageRequest exposes no requester-disconnect signal at this layer (unlike agent-comms' own transport, which owns the raw connection), so only the timeout half of that pattern is implemented here -- there is nothing to detect the requester giving up early honestly, so this module does not pretend to. */
48
+ timeoutMs: number;
49
+ /** Called once per incoming, not-yet-expired capability-request, for the domain to accept or reject via the event's own decide(). */
50
+ onRequest: (event: Readonly<CapabilityGrantRequestEvent>) => void;
51
+ }
52
+ /**
53
+ * Builds a reusable handler for one capability's incoming capability-requests. The returned function is the generic counterpart to room-client.ts's own (now capability-specific) handleRoomJoin: given one IncomingManageRequest, it refuses a request for the wrong capability or a malformed payload as `{result:"error", code:"malformed"}`, refuses an already-expired request (per its own `valid-until`, wire-mesh#82) as `{result:"error", code:"expired"}` without ever invoking onRequest, otherwise arms the receiver-side timeout described on CreateCapabilityRequestHandlerOptions.timeoutMs and calls onRequest so the domain can accept (minting a fresh token via mintCapabilityToken and responding `{result:"ok", "granted-token": token, ...extensions}`) or reject (an ordinary manage-error) via the event's own decide().
54
+ */
55
+ export declare function createCapabilityRequestHandler(options: Readonly<CreateCapabilityRequestHandlerOptions>): (incoming: Readonly<IncomingManageRequest>) => Promise<void>;
56
+ //#endregion
@@ -0,0 +1,56 @@
1
+ import { P as ManageCommand, a as CapabilityScope, b as DeviceId, r as CapabilityGrantOk } from "../protocol-MnxTzpRP.mjs";
2
+ import { t as IdentityPort } from "../identity-D8iJZRZZ.mjs";
3
+ import { t as Clock } from "../clock-DiSx-WKM.mjs";
4
+ import { IncomingManageRequest, MeshSession } from "./mesh-session.mjs";
5
+ //#region src/domain/capability-request.d.ts
6
+ /**
7
+ * Builds a capability-request command per management.cddl. The outer `manage-command.verb` is the capability string itself -- the same value as this map's own `params.capability` field -- never a generic literal: capability-verb's own CDDL grammar is a closed alternation of colon-delimited `domain:noun` regexes (spec/tokens.cddl), so a bare literal like "capability" could never satisfy it, and routing by capability (the same way room.send/room.join already share the ROOM_MEMBER_CAPABILITY outer verb) is how a receiver's own per-capability handler knows which grant this ask is even for. `params.verb` is the fixed "capability.request" marker that distinguishes this ask from any other verb sharing the same outer capability (mirroring room.send/room.join's own inner `params.verb` split under one shared outer verb). `valid-until`, when given, bounds how long this ask is worth granting (wire-mesh#82) -- a receiver refuses outright once its own clock has passed it, rather than presenting a stale ask to a human for approval.
8
+ */
9
+ export declare function buildCapabilityRequestCommand(capability: string, validUntil?: number): ManageCommand;
10
+ /**
11
+ * Sends a deliberately ungated capability-request (no token field at all -- per management.cddl's own header comment, this primitive puts access control entirely in the receiving side's own decision, not a capability check on the request itself, the same design room.join already established). Resolves with the freshly granted capability-grant-ok on approval (its own open `* tstr => any` tail may carry domain-specific extension fields, e.g. core/room's member list -- a caller that needs those parses the raw result itself, the same way room-client.ts's own requestToJoin wrapper does); rejects on denial (an ordinary manage-error) or a malformed response.
12
+ *
13
+ * targetDevice and timeoutMs forward directly to MeshSession.sendManageRequest's own identically-named parameters (relay routing and a requester-side give-up bound respectively -- wire-mesh#80 is already implemented there, not duplicated here). validUntil, when given, is attached to the request itself (wire-mesh#82) so a slow-to-answer receiver -- or a relay/facilitator forwarding this request on the caller's behalf -- can refuse or drop a now-stale ask outright rather than holding or forwarding it.
14
+ */
15
+ export declare function requestCapability(session: Readonly<MeshSession>, capability: string, scope: Readonly<CapabilityScope>, targetDevice?: DeviceId, timeoutMs?: number, validUntil?: number): Promise<CapabilityGrantOk>;
16
+ /**
17
+ * A receiver's decision on one incoming capability-request, mirroring room-client.ts's own (now capability-specific) RoomJoinDecision, generalized to any capability: "accept" mints and returns a fresh token; "reject" sends an ordinary manage-error carrying an optional human-readable reason.
18
+ */
19
+ export type CapabilityGrantDecision = {
20
+ kind: "accept";
21
+ /** The capability the minted token actually carries -- usually, but not necessarily, the same string the request itself asked for (a receiver is free to grant something narrower). */
22
+ capability: string;
23
+ expires: number;
24
+ delegationsRemaining?: number;
25
+ /** Fields the domain wants merged onto the `{result:"ok", "granted-token": token, ...}` response, riding capability-grant-ok's own open `* tstr => any` tail -- the mechanism core/room's own room-join-ok uses for its `members` field, generalized so this module never needs to know what any particular capability's own grant response should additionally carry. Omit for a capability (e.g. a bare exec grant) whose response needs nothing beyond the token itself. */
26
+ extensions?: Record<string, unknown>;
27
+ } | {
28
+ kind: "reject";
29
+ reason?: string;
30
+ };
31
+ /** One incoming, not-yet-expired capability-request, surfaced for the domain to accept or reject via decide(). */
32
+ export interface CapabilityGrantRequestEvent {
33
+ /** The scope this request's own manage-request-frame carries -- e.g. core/room's `{kind:"room", path: roomPath}` -- passed through unchanged so the domain can inspect it (a room handler reads `.path` back out) without this module needing to know its shape. */
34
+ scope: Readonly<CapabilityScope>;
35
+ /** The peer device-id authenticated on the connection this request arrived over -- the requester, and so the future bearer of any token minted on acceptance. Same role as RoomRouterOptions.peerDevice / RoomJoinRequestEvent.requesterDevice. */
36
+ requesterDevice: DeviceId;
37
+ /** Resolves this request with the domain's decision. Settles the request's response exactly once: whichever of a real decide() call or the handler's own receiver-side timeout comes first wins, and the other is a no-op -- the same single-settle guarantee agent-comms' own PendingConnection timer/accept/reject/disconnect race already established (ported here, not reinvented). */
38
+ decide: (decision: Readonly<CapabilityGrantDecision>) => Promise<void>;
39
+ }
40
+ export interface CreateCapabilityRequestHandlerOptions {
41
+ /** The capability this handler grants. Checked against both the incoming request's own `params.capability` field (a mismatch is refused as malformed rather than trusted -- nothing about manage-command.verb structurally guarantees params.capability agrees with it) and used as the scope this handler is willing to act on at all; a caller wanting to grant several distinct capabilities over one session constructs one handler per capability, the same way core/room constructs one handler for `room:member` and nothing else. */
42
+ capability: string;
43
+ identity: IdentityPort;
44
+ clock: Clock;
45
+ /** The peer device-id authenticated on this session's own connection -- the requester, and so the future bearer of any token this handler mints. One handler is constructed per session for the same reason one RoomRouter is (RoomRouterOptions.peerDevice): MeshSession exposes no way for domain code to learn the authenticated peer independently. */
46
+ bearerDevice: DeviceId;
47
+ /** Receiver-side auto-reject window (wire-mesh#81): how long an incoming request may sit awaiting the domain's decision before this side responds with a real manage-error timeout rather than leaving the requester's own sendManageRequest hanging indefinitely. Ported from agent-comms' PendingConnection pattern (`wire-mesh-transport.ts`'s `pendingConnectionTimeoutMs` / `expirePendingConnection`): an unref'd timer so a stray one can never by itself keep the process alive, cleared the instant decide() is actually called so it can never fire after the request has already been answered. IncomingManageRequest exposes no requester-disconnect signal at this layer (unlike agent-comms' own transport, which owns the raw connection), so only the timeout half of that pattern is implemented here -- there is nothing to detect the requester giving up early honestly, so this module does not pretend to. */
48
+ timeoutMs: number;
49
+ /** Called once per incoming, not-yet-expired capability-request, for the domain to accept or reject via the event's own decide(). */
50
+ onRequest: (event: Readonly<CapabilityGrantRequestEvent>) => void;
51
+ }
52
+ /**
53
+ * Builds a reusable handler for one capability's incoming capability-requests. The returned function is the generic counterpart to room-client.ts's own (now capability-specific) handleRoomJoin: given one IncomingManageRequest, it refuses a request for the wrong capability or a malformed payload as `{result:"error", code:"malformed"}`, refuses an already-expired request (per its own `valid-until`, wire-mesh#82) as `{result:"error", code:"expired"}` without ever invoking onRequest, otherwise arms the receiver-side timeout described on CreateCapabilityRequestHandlerOptions.timeoutMs and calls onRequest so the domain can accept (minting a fresh token via mintCapabilityToken and responding `{result:"ok", "granted-token": token, ...extensions}`) or reject (an ordinary manage-error) via the event's own decide().
54
+ */
55
+ export declare function createCapabilityRequestHandler(options: Readonly<CreateCapabilityRequestHandlerOptions>): (incoming: Readonly<IncomingManageRequest>) => Promise<void>;
56
+ //#endregion
@@ -0,0 +1,115 @@
1
+ import { capabilityGrantOkSchema, capabilityRequestSchema } from "../generated/protocol.mjs";
2
+ import { mintCapabilityToken } from "./tokens.mjs";
3
+ //#region src/domain/capability-request.ts
4
+ /**
5
+ * The generic, capability-agnostic capability-request / capability-grant-ok primitive (wire-mesh#78, spec/management.cddl). Lifts core/room's own room.join shape -- an ungated ask, held open, a human (or any other domain-supplied decision) accepts or refuses, acceptance mints and returns a token on the same response -- out of that one domain so any capability can reuse it, not just room:member. core/room's own room-client.ts is the reference consumer: it rewires requestToJoin/createRoomRouter's room.join handling onto requestCapability/createCapabilityRequestHandler below, supplying room-specific extension fields (its member list) through this module's own extensions mechanism rather than this module knowing anything about rooms.
6
+ *
7
+ * Two responsibilities live here, split the same way tokens.ts and room-token-verification.ts already split verification concerns: requestCapability is the asking side (a thin wrapper over MeshSession.sendManageRequest, parsing the grant response), and createCapabilityRequestHandler is the receiving side (validates the incoming ask, arms a receiver-side timeout so an unanswered request never hangs a requester forever, and hands the decision to the domain).
8
+ */
9
+ const TOKEN_ID_BYTE_LENGTH = 16;
10
+ function randomTokenId() {
11
+ const bytes = new Uint8Array(TOKEN_ID_BYTE_LENGTH);
12
+ crypto.getRandomValues(bytes);
13
+ return bytes;
14
+ }
15
+ /**
16
+ * Builds a capability-request command per management.cddl. The outer `manage-command.verb` is the capability string itself -- the same value as this map's own `params.capability` field -- never a generic literal: capability-verb's own CDDL grammar is a closed alternation of colon-delimited `domain:noun` regexes (spec/tokens.cddl), so a bare literal like "capability" could never satisfy it, and routing by capability (the same way room.send/room.join already share the ROOM_MEMBER_CAPABILITY outer verb) is how a receiver's own per-capability handler knows which grant this ask is even for. `params.verb` is the fixed "capability.request" marker that distinguishes this ask from any other verb sharing the same outer capability (mirroring room.send/room.join's own inner `params.verb` split under one shared outer verb). `valid-until`, when given, bounds how long this ask is worth granting (wire-mesh#82) -- a receiver refuses outright once its own clock has passed it, rather than presenting a stale ask to a human for approval.
17
+ */
18
+ function buildCapabilityRequestCommand(capability, validUntil) {
19
+ return {
20
+ verb: capability,
21
+ params: {
22
+ verb: "capability.request",
23
+ capability,
24
+ ...validUntil !== void 0 ? { "valid-until": validUntil } : {}
25
+ }
26
+ };
27
+ }
28
+ /**
29
+ * Sends a deliberately ungated capability-request (no token field at all -- per management.cddl's own header comment, this primitive puts access control entirely in the receiving side's own decision, not a capability check on the request itself, the same design room.join already established). Resolves with the freshly granted capability-grant-ok on approval (its own open `* tstr => any` tail may carry domain-specific extension fields, e.g. core/room's member list -- a caller that needs those parses the raw result itself, the same way room-client.ts's own requestToJoin wrapper does); rejects on denial (an ordinary manage-error) or a malformed response.
30
+ *
31
+ * targetDevice and timeoutMs forward directly to MeshSession.sendManageRequest's own identically-named parameters (relay routing and a requester-side give-up bound respectively -- wire-mesh#80 is already implemented there, not duplicated here). validUntil, when given, is attached to the request itself (wire-mesh#82) so a slow-to-answer receiver -- or a relay/facilitator forwarding this request on the caller's behalf -- can refuse or drop a now-stale ask outright rather than holding or forwarding it.
32
+ */
33
+ async function requestCapability(session, capability, scope, targetDevice, timeoutMs, validUntil) {
34
+ const outcome = await session.sendManageRequest(buildCapabilityRequestCommand(capability, validUntil), scope, targetDevice, void 0, timeoutMs);
35
+ if (outcome.result !== "ok") throw new Error(`capability request for "${capability}" was refused (${outcome.code})`);
36
+ const parsed = capabilityGrantOkSchema.safeParse(outcome);
37
+ if (!parsed.success) throw new Error(`capability request for "${capability}" response was malformed`);
38
+ return parsed.data;
39
+ }
40
+ /**
41
+ * Builds a reusable handler for one capability's incoming capability-requests. The returned function is the generic counterpart to room-client.ts's own (now capability-specific) handleRoomJoin: given one IncomingManageRequest, it refuses a request for the wrong capability or a malformed payload as `{result:"error", code:"malformed"}`, refuses an already-expired request (per its own `valid-until`, wire-mesh#82) as `{result:"error", code:"expired"}` without ever invoking onRequest, otherwise arms the receiver-side timeout described on CreateCapabilityRequestHandlerOptions.timeoutMs and calls onRequest so the domain can accept (minting a fresh token via mintCapabilityToken and responding `{result:"ok", "granted-token": token, ...extensions}`) or reject (an ordinary manage-error) via the event's own decide().
42
+ */
43
+ function createCapabilityRequestHandler(options) {
44
+ return async function handleCapabilityRequest(incoming) {
45
+ const parsed = capabilityRequestSchema.safeParse(incoming.command.params);
46
+ if (!parsed.success || parsed.data.capability !== options.capability) {
47
+ await incoming.respond({
48
+ result: "error",
49
+ code: "malformed"
50
+ });
51
+ return;
52
+ }
53
+ const validUntil = parsed.data["valid-until"];
54
+ if (validUntil !== void 0 && validUntil <= options.clock.now()) {
55
+ await incoming.respond({
56
+ result: "error",
57
+ code: "expired"
58
+ });
59
+ return;
60
+ }
61
+ let settled = false;
62
+ const timeoutHandle = setTimeout(() => {
63
+ if (settled) return;
64
+ settled = true;
65
+ incoming.respond({
66
+ result: "error",
67
+ code: "timeout",
68
+ message: "no decision within the capability-request timeout"
69
+ }).catch(() => void 0);
70
+ }, options.timeoutMs);
71
+ timeoutHandle.unref();
72
+ options.onRequest({
73
+ scope: incoming.scope,
74
+ requesterDevice: options.bearerDevice,
75
+ async decide(decision) {
76
+ if (settled) return;
77
+ settled = true;
78
+ clearTimeout(timeoutHandle);
79
+ if (decision.kind === "reject") {
80
+ await incoming.respond({
81
+ result: "error",
82
+ code: "denied",
83
+ ...decision.reason !== void 0 ? { message: decision.reason } : {}
84
+ });
85
+ return;
86
+ }
87
+ const verdict = await mintCapabilityToken({
88
+ identity: options.identity,
89
+ clock: options.clock,
90
+ tokenId: randomTokenId(),
91
+ bearer: options.bearerDevice,
92
+ capability: decision.capability,
93
+ scope: incoming.scope,
94
+ expires: decision.expires,
95
+ ...decision.delegationsRemaining !== void 0 ? { delegationsRemaining: decision.delegationsRemaining } : {}
96
+ });
97
+ if (!verdict.ok) {
98
+ await incoming.respond({
99
+ result: "error",
100
+ code: "mint_failed"
101
+ });
102
+ return;
103
+ }
104
+ const grantedToken = verdict.token;
105
+ await incoming.respond({
106
+ result: "ok",
107
+ "granted-token": grantedToken,
108
+ ...decision.extensions ?? {}
109
+ });
110
+ }
111
+ });
112
+ };
113
+ }
114
+ //#endregion
115
+ export { buildCapabilityRequestCommand, createCapabilityRequestHandler, requestCapability };
@@ -1,4 +1,4 @@
1
- import { b as DeviceId } from "../protocol-BwFGx9cg.cjs";
1
+ import { b as DeviceId } from "../protocol-MnxTzpRP.cjs";
2
2
  //#region src/domain/device-id.d.ts
3
3
  /** Lowercase, byte-exact hex for an arbitrary-length byte string -- the same encoding convention deviceIdToHex uses for the fixed-length device-id case, extracted so any other byte string needing a stable, displayable, map-keyable text form (e.g. a token-id, which tokens.cddl defines as an arbitrary-length bstr rather than a 32-byte device-id) can use the identical convention without going through a device-id-shaped function. */
4
4
  export declare function bytesToHex(bytes: Uint8Array): string;
@@ -1,4 +1,4 @@
1
- import { b as DeviceId } from "../protocol-BwFGx9cg.mjs";
1
+ import { b as DeviceId } from "../protocol-MnxTzpRP.mjs";
2
2
  //#region src/domain/device-id.d.ts
3
3
  /** Lowercase, byte-exact hex for an arbitrary-length byte string -- the same encoding convention deviceIdToHex uses for the fixed-length device-id case, extracted so any other byte string needing a stable, displayable, map-keyable text form (e.g. a token-id, which tokens.cddl defines as an arbitrary-length bstr rather than a 32-byte device-id) can use the identical convention without going through a device-id-shaped function. */
4
4
  export declare function bytesToHex(bytes: Uint8Array): string;
@@ -1,4 +1,4 @@
1
- import { $ as ProtocolVersion, C as DomainId, j as HandshakeFrame } from "../protocol-BwFGx9cg.cjs";
1
+ import { $ as ProtocolVersion, C as DomainId, j as HandshakeFrame } from "../protocol-MnxTzpRP.cjs";
2
2
  //#region src/domain/handshake.d.ts
3
3
  /** The highest protocol version this build of core understands. */
4
4
  export declare const SUPPORTED_PROTOCOL_VERSION: ProtocolVersion;
@@ -1,4 +1,4 @@
1
- import { $ as ProtocolVersion, C as DomainId, j as HandshakeFrame } from "../protocol-BwFGx9cg.mjs";
1
+ import { $ as ProtocolVersion, C as DomainId, j as HandshakeFrame } from "../protocol-MnxTzpRP.mjs";
2
2
  //#region src/domain/handshake.d.ts
3
3
  /** The highest protocol version this build of core understands. */
4
4
  export declare const SUPPORTED_PROTOCOL_VERSION: ProtocolVersion;
@@ -1,7 +1,7 @@
1
- import { $ as ProtocolVersion, E as Frame, G as PeerAdvert, I as ManageError, L as ManageOk, P as ManageCommand, a as CapabilityScope, b as DeviceId, o as CapabilityToken, ut as RevocationEntry } from "../protocol-BwFGx9cg.cjs";
2
- import { t as IdentityPort } from "../identity-ijL0IsUT.cjs";
1
+ import { $ as ProtocolVersion, E as Frame, G as PeerAdvert, I as ManageError, L as ManageOk, P as ManageCommand, a as CapabilityScope, b as DeviceId, o as CapabilityToken, ut as RevocationEntry } from "../protocol-MnxTzpRP.cjs";
2
+ import { t as IdentityPort } from "../identity-DkEe1465.cjs";
3
3
  import { t as Clock } from "../clock-DiSx-WKM.cjs";
4
- import { Connection, Transport } from "../ports/transport.cjs";
4
+ import { r as Transport, t as Connection } from "../transport-Da7GP9ya.cjs";
5
5
  //#region src/domain/mesh-session.d.ts
6
6
  /** How long to wait for the node's handshake before calling it unanswered. A relay-only node never sends one; that is a state to display, not an error. */
7
7
  export declare const HANDSHAKE_TIMEOUT_MS = 3000;
@@ -1,7 +1,7 @@
1
- import { $ as ProtocolVersion, E as Frame, G as PeerAdvert, I as ManageError, L as ManageOk, P as ManageCommand, a as CapabilityScope, b as DeviceId, o as CapabilityToken, ut as RevocationEntry } from "../protocol-BwFGx9cg.mjs";
2
- import { t as IdentityPort } from "../identity-DvBEkcS9.mjs";
1
+ import { $ as ProtocolVersion, E as Frame, G as PeerAdvert, I as ManageError, L as ManageOk, P as ManageCommand, a as CapabilityScope, b as DeviceId, o as CapabilityToken, ut as RevocationEntry } from "../protocol-MnxTzpRP.mjs";
2
+ import { t as IdentityPort } from "../identity-D8iJZRZZ.mjs";
3
3
  import { t as Clock } from "../clock-DiSx-WKM.mjs";
4
- import { Connection, Transport } from "../ports/transport.mjs";
4
+ import { r as Transport, t as Connection } from "../transport-ESMXRz3s.mjs";
5
5
  //#region src/domain/mesh-session.d.ts
6
6
  /** How long to wait for the node's handshake before calling it unanswered. A relay-only node never sends one; that is a state to display, not an error. */
7
7
  export declare const HANDSHAKE_TIMEOUT_MS = 3000;
@@ -1,4 +1,4 @@
1
- import { Connection } from "../ports/transport.cjs";
1
+ import { t as Connection } from "../transport-Da7GP9ya.cjs";
2
2
  //#region src/domain/relay-hub.d.ts
3
3
  export interface RelayHub {
4
4
  /** Drives one accepted connection until it closes: registers gossip-advertised devices, answers relay-connect by pairing and notifying the target, and forwards relay-data within established pairings. Resolves when the connection's frame stream ends. */
@@ -1,4 +1,4 @@
1
- import { Connection } from "../ports/transport.mjs";
1
+ import { t as Connection } from "../transport-ESMXRz3s.mjs";
2
2
  //#region src/domain/relay-hub.d.ts
3
3
  export interface RelayHub {
4
4
  /** Drives one accepted connection until it closes: registers gossip-advertised devices, answers relay-connect by pairing and notifying the target, and forwards relay-data within established pairings. Resolves when the connection's frame stream ends. */
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_domain_device_id = require("./device-id.cjs");
3
2
  const require_domain_tokens = require("./tokens.cjs");
3
+ const require_domain_device_id = require("./device-id.cjs");
4
4
  //#region src/domain/revocation-view.ts
5
5
  function revocationKey(tokenId, issuer) {
6
6
  return `${require_domain_device_id.bytesToHex(tokenId)}:${require_domain_device_id.deviceIdToHex(issuer)}`;
@@ -1,4 +1,4 @@
1
- import { ut as RevocationEntry } from "../protocol-BwFGx9cg.cjs";
1
+ import { ut as RevocationEntry } from "../protocol-MnxTzpRP.cjs";
2
2
  import { RevocationCheck, RevocationEntryVerdict, VerifyRevocationEntryOptions } from "./tokens.cjs";
3
3
  //#region src/domain/revocation-view.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { ut as RevocationEntry } from "../protocol-BwFGx9cg.mjs";
1
+ import { ut as RevocationEntry } from "../protocol-MnxTzpRP.mjs";
2
2
  import { RevocationCheck, RevocationEntryVerdict, VerifyRevocationEntryOptions } from "./tokens.mjs";
3
3
  //#region src/domain/revocation-view.d.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
- import { bytesToHex, deviceIdToHex } from "./device-id.mjs";
2
1
  import { verifyRevocationEntry } from "./tokens.mjs";
2
+ import { bytesToHex, deviceIdToHex } from "./device-id.mjs";
3
3
  //#region src/domain/revocation-view.ts
4
4
  function revocationKey(tokenId, issuer) {
5
5
  return `${bytesToHex(tokenId)}:${deviceIdToHex(issuer)}`;
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_domain_tokens = require("./tokens.cjs");
2
3
  const require_domain_device_id = require("./device-id.cjs");
3
4
  const require_domain_room_path = require("./room-path.cjs");
4
- const require_domain_tokens = require("./tokens.cjs");
5
5
  //#region src/domain/room-token-verification.ts
6
6
  /**
7
7
  * core/room's six verifier obligations (spec/room.cddl), layered on top of verifyCapabilityToken (obligations 2, 4, and 5 -- bearer match, ordinary token-claims checks, and delegations-remaining narrowing -- already live there). This module adds the two obligations specific to room-shaped scopes: the chain must terminate at the correct root for the path's own shape (1), and the token's own scope must actually name the room the request claims to act on (3). Obligation 6 (refuse an unrecognised content-type/kind) is a message-handling concern, not a token-verification one, and belongs to each consumer's own room verb router instead.
@@ -1,4 +1,4 @@
1
- import { Ot as TokenClaims, b as DeviceId, o as CapabilityToken } from "../protocol-BwFGx9cg.cjs";
1
+ import { Ot as TokenClaims, b as DeviceId, o as CapabilityToken } from "../protocol-MnxTzpRP.cjs";
2
2
  import { TokenVerdictReason, VerifyCapabilityTokenOptions } from "./tokens.cjs";
3
3
  //#region src/domain/room-token-verification.d.ts
4
4
  /** The one capability every core/room verb (room.send/read/leave/members) is gated by, per spec/room.cddl -- room.join/room.invite are deliberately ungated instead and need no token check at all. */
@@ -1,4 +1,4 @@
1
- import { Ot as TokenClaims, b as DeviceId, o as CapabilityToken } from "../protocol-BwFGx9cg.mjs";
1
+ import { Ot as TokenClaims, b as DeviceId, o as CapabilityToken } from "../protocol-MnxTzpRP.mjs";
2
2
  import { TokenVerdictReason, VerifyCapabilityTokenOptions } from "./tokens.mjs";
3
3
  //#region src/domain/room-token-verification.d.ts
4
4
  /** The one capability every core/room verb (room.send/read/leave/members) is gated by, per spec/room.cddl -- room.join/room.invite are deliberately ungated instead and need no token check at all. */
@@ -1,6 +1,6 @@
1
+ import { verifyCapabilityToken } from "./tokens.mjs";
1
2
  import { deviceIdToHex } from "./device-id.mjs";
2
3
  import { parseRoomPath } from "./room-path.mjs";
3
- import { verifyCapabilityToken } from "./tokens.mjs";
4
4
  //#region src/domain/room-token-verification.ts
5
5
  /**
6
6
  * core/room's six verifier obligations (spec/room.cddl), layered on top of verifyCapabilityToken (obligations 2, 4, and 5 -- bearer match, ordinary token-claims checks, and delegations-remaining narrowing -- already live there). This module adds the two obligations specific to room-shaped scopes: the chain must terminate at the correct root for the path's own shape (1), and the token's own scope must actually name the room the request claims to act on (3). Obligation 6 (refuse an unrecognised content-type/kind) is a message-handling concern, not a token-verification one, and belongs to each consumer's own room verb router instead.
@@ -118,6 +118,11 @@ async function verifyTokenChain(token, options) {
118
118
  ok: false,
119
119
  reason: "not_yet_valid"
120
120
  };
121
+ const validUntil = claims["valid-until"];
122
+ if (validUntil !== void 0 && validUntil <= now) return {
123
+ ok: false,
124
+ reason: "content_expired"
125
+ };
121
126
  if (await options.revocation.isRevoked(claims["token-id"], claims.issuer)) return {
122
127
  ok: false,
123
128
  reason: "revoked"
@@ -1,5 +1,5 @@
1
- import { Ot as TokenClaims, b as DeviceId, lt as RevocationClaims, o as CapabilityToken, ut as RevocationEntry } from "../protocol-BwFGx9cg.cjs";
2
- import { t as IdentityPort } from "../identity-ijL0IsUT.cjs";
1
+ import { Ot as TokenClaims, b as DeviceId, lt as RevocationClaims, o as CapabilityToken, ut as RevocationEntry } from "../protocol-MnxTzpRP.cjs";
2
+ import { t as IdentityPort } from "../identity-DkEe1465.cjs";
3
3
  import { t as Clock } from "../clock-DiSx-WKM.cjs";
4
4
  //#region src/domain/tokens.d.ts
5
5
  /**
@@ -8,7 +8,7 @@ import { t as Clock } from "../clock-DiSx-WKM.cjs";
8
8
  export interface RevocationCheck {
9
9
  isRevoked: (tokenId: Uint8Array, issuer: DeviceId) => Promise<boolean>;
10
10
  }
11
- export type TokenVerdictReason = "malformed" | "bad_signature" | "wrong_issuer" | "bearer_mismatch" | "expired" | "not_yet_valid" | "revoked" | "delegation_exceeds_parent" | "parent_invalid";
11
+ export type TokenVerdictReason = "malformed" | "bad_signature" | "wrong_issuer" | "bearer_mismatch" | "expired" | "not_yet_valid" | "content_expired" | "revoked" | "delegation_exceeds_parent" | "parent_invalid";
12
12
  export type TokenVerdict = {
13
13
  ok: true;
14
14
  claims: TokenClaims;
@@ -1,5 +1,5 @@
1
- import { Ot as TokenClaims, b as DeviceId, lt as RevocationClaims, o as CapabilityToken, ut as RevocationEntry } from "../protocol-BwFGx9cg.mjs";
2
- import { t as IdentityPort } from "../identity-DvBEkcS9.mjs";
1
+ import { Ot as TokenClaims, b as DeviceId, lt as RevocationClaims, o as CapabilityToken, ut as RevocationEntry } from "../protocol-MnxTzpRP.mjs";
2
+ import { t as IdentityPort } from "../identity-D8iJZRZZ.mjs";
3
3
  import { t as Clock } from "../clock-DiSx-WKM.mjs";
4
4
  //#region src/domain/tokens.d.ts
5
5
  /**
@@ -8,7 +8,7 @@ import { t as Clock } from "../clock-DiSx-WKM.mjs";
8
8
  export interface RevocationCheck {
9
9
  isRevoked: (tokenId: Uint8Array, issuer: DeviceId) => Promise<boolean>;
10
10
  }
11
- export type TokenVerdictReason = "malformed" | "bad_signature" | "wrong_issuer" | "bearer_mismatch" | "expired" | "not_yet_valid" | "revoked" | "delegation_exceeds_parent" | "parent_invalid";
11
+ export type TokenVerdictReason = "malformed" | "bad_signature" | "wrong_issuer" | "bearer_mismatch" | "expired" | "not_yet_valid" | "content_expired" | "revoked" | "delegation_exceeds_parent" | "parent_invalid";
12
12
  export type TokenVerdict = {
13
13
  ok: true;
14
14
  claims: TokenClaims;
@@ -117,6 +117,11 @@ async function verifyTokenChain(token, options) {
117
117
  ok: false,
118
118
  reason: "not_yet_valid"
119
119
  };
120
+ const validUntil = claims["valid-until"];
121
+ if (validUntil !== void 0 && validUntil <= now) return {
122
+ ok: false,
123
+ reason: "content_expired"
124
+ };
120
125
  if (await options.revocation.isRevoked(claims["token-id"], claims.issuer)) return {
121
126
  ok: false,
122
127
  reason: "revoked"
@@ -247,7 +247,8 @@ const roomNoticeClaimsSchema = zod.z.lazy(() => zod.z.object({
247
247
  "posted-at": zod.z.number().int().nonnegative(),
248
248
  "content-type": zod.z.string(),
249
249
  "content": zod.z.instanceof(Uint8Array),
250
- "refs": zod.z.array(zod.z.lazy(() => messageRefSchema)).optional()
250
+ "refs": zod.z.array(zod.z.lazy(() => messageRefSchema)).optional(),
251
+ "valid-until": zod.z.number().int().nonnegative().optional()
251
252
  }).catchall(zod.z.unknown()));
252
253
  const streamSessionSchema = zod.z.lazy(() => zod.z.number().int().nonnegative());
253
254
  const streamDataFrameSchema = zod.z.lazy(() => zod.z.object({
@@ -305,7 +306,8 @@ const tokenClaimsSchema = zod.z.lazy(() => zod.z.object({
305
306
  "expires": zod.z.number().int().nonnegative(),
306
307
  "not-before": zod.z.number().int().nonnegative().optional(),
307
308
  "parent": zod.z.instanceof(Uint8Array).optional(),
308
- "delegations-remaining": zod.z.number().int().nonnegative().optional()
309
+ "delegations-remaining": zod.z.number().int().nonnegative().optional(),
310
+ "valid-until": zod.z.number().int().nonnegative().optional()
309
311
  }).catchall(zod.z.unknown()));
310
312
  const pingFrameSchema = zod.z.lazy(() => zod.z.object({ "type": zod.z.literal("ping") }));
311
313
  const closeFrameSchema = zod.z.lazy(() => zod.z.object({
@@ -1,2 +1,2 @@
1
- import { $ as ProtocolVersion, $n as roomReadSchema, $t as deviceIdSchema, A as HandleRecord, An as procSpawnSchema, At as WebrtcIceCandidate, B as MessageRef, Bn as revocationAnnounceFrameSchema, Bt as closeFrameSchema, C as DomainId, Cn as peerAdvertSchema, Ct as StreamAckFrame, D as FrameVariant, Dn as privateUseDomainIdSchema, Dt as SyncPunchFrame, E as Frame, En as privateUseCapabilitySchema, Et as StreamSession, F as ManageCommandParams, Fn as ptyWriteSchema, Ft as capabilityGrantOkSchema, G as PeerAdvert, Gn as roomJoinSchema, Gt as coseHeaderKidSchema, H as NamespacedDomainId, Hn as revocationEntrySchema, Ht as coreCapabilitySchema, I as ManageError, In as relayConnectFrameSchema, It as capabilityRequestSchema, J as PrivateUseCapability, Jn as roomMembersOkSchema, Jt as coseTokenHeadersSchema, K as PeerIdentity, Kn as roomLeaveSchema, Kt as coseHeaderLabelSchema, L as ManageOk, Ln as relayDataFrameSchema, Lt as capabilityScopeSchema, M as IceCandidateInit, Mn as ptyKillSchema, Mt as WireCandidate, N as IdentityKey, Nn as ptyResizeSchema, Nt as candidateKindSchema, O as GossipFrame, On as procKillSchema, Ot as TokenClaims, P as ManageCommand, Pn as ptySpawnSchema, Pt as candidatesFrameSchema, Q as ProcSpawn, Qn as roomPathSchema, Qt as deviceIdHexSchema, R as ManageRequestFrame, Rn as relayInboundFrameSchema, Rt as capabilityTokenSchema, S as DmRoomPath, Sn as ownerNamedRoomPathSchema, St as RoomSend, T as ExecSessionInfo, Tn as pingFrameSchema, Tt as StreamEndFrame, U as ObservedAddressFrame, Un as roomInviteSchema, Ut as coreDomainNameSchema, V as NamespacedCapability, Vn as revocationClaimsSchema, Vt as coordinatorFrameSchema, W as OwnerNamedRoomPath, Wn as roomJoinOkSchema, Wt as coseHeaderAlgSchema, X as ProcKill, Xn as roomNoticeClaimsSchema, Xt as dataHaveFrameSchema, Y as PrivateUseDomainId, Yn as roomMembersSchema, Yt as dataEntriesFrameSchema, Z as ProcSignal, Zn as roomNoticeSchema, Zt as dataRequestFrameSchema, _ as DataEntriesFrame, _n as manageResponseFrameSchema, _t as RoomMembersOk, a as CapabilityScope, an as frameVariantSchema, ar as syncPunchFrameSchema, at as RelayDataFrame, b as DeviceId, bn as namespacedDomainIdSchema, bt as RoomPath, c as CloseFrame, cn as handleRecordSchema, cr as webrtcIceCandidateSchema, ct as RevocationAnnounceFrame, d as CoreDomainName, dn as identityKeySchema, dt as RoomInvite, en as dmRoomPathSchema, er as roomSendSchema, et as PtyKill, f as CoseHeaderAlg, fn as manageCommandParamsSchema, ft as RoomJoin, g as CoseTokenHeaders, gn as manageRequestFrameSchema, gt as RoomMembers, h as CoseSign1, hn as manageOkSchema, ht as RoomMember, i as CapabilityRequest, in as frameSchema, ir as streamSessionSchema, it as RelayConnectFrame, j as HandshakeFrame, jn as protocolVersionSchema, jt as WebrtcOffer, k as HandleClaims, kn as procSignalSchema, kt as WebrtcAnswer, l as CoordinatorFrame, ln as handshakeFrameSchema, lr as webrtcOfferSchema, lt as RevocationClaims, m as CoseHeaderLabel, mn as manageErrorSchema, mt as RoomLeave, n as CandidatesFrame, nn as execListSchema, nr as streamDataFrameSchema, nt as PtySpawn, o as CapabilityToken, on as gossipFrameSchema, or as tokenClaimsSchema, ot as RelayInboundFrame, p as CoseHeaderKid, pn as manageCommandSchema, pt as RoomJoinOk, q as PingFrame, qn as roomMemberSchema, qt as coseSign1Schema, r as CapabilityGrantOk, rn as execSessionInfoSchema, rr as streamEndFrameSchema, rt as PtyWrite, s as CapabilityVerb, sn as handleClaimsSchema, sr as webrtcAnswerSchema, st as RelayOfferFrame, t as CandidateKind, tn as domainIdSchema, tr as streamAckFrameSchema, tt as PtyResize, u as CoreCapability, un as iceCandidateInitSchema, ur as wireCandidateSchema, ut as RevocationEntry, v as DataHaveFrame, vn as messageRefSchema, vt as RoomNotice, w as ExecList, wn as peerIdentitySchema, wt as StreamDataFrame, x as DeviceIdHex, xn as observedAddressFrameSchema, xt as RoomRead, y as DataRequestFrame, yn as namespacedCapabilitySchema, yt as RoomNoticeClaims, z as ManageResponseFrame, zn as relayOfferFrameSchema, zt as capabilityVerbSchema } from "../protocol-BwFGx9cg.cjs";
1
+ import { $ as ProtocolVersion, $n as roomReadSchema, $t as deviceIdSchema, A as HandleRecord, An as procSpawnSchema, At as WebrtcIceCandidate, B as MessageRef, Bn as revocationAnnounceFrameSchema, Bt as closeFrameSchema, C as DomainId, Cn as peerAdvertSchema, Ct as StreamAckFrame, D as FrameVariant, Dn as privateUseDomainIdSchema, Dt as SyncPunchFrame, E as Frame, En as privateUseCapabilitySchema, Et as StreamSession, F as ManageCommandParams, Fn as ptyWriteSchema, Ft as capabilityGrantOkSchema, G as PeerAdvert, Gn as roomJoinSchema, Gt as coseHeaderKidSchema, H as NamespacedDomainId, Hn as revocationEntrySchema, Ht as coreCapabilitySchema, I as ManageError, In as relayConnectFrameSchema, It as capabilityRequestSchema, J as PrivateUseCapability, Jn as roomMembersOkSchema, Jt as coseTokenHeadersSchema, K as PeerIdentity, Kn as roomLeaveSchema, Kt as coseHeaderLabelSchema, L as ManageOk, Ln as relayDataFrameSchema, Lt as capabilityScopeSchema, M as IceCandidateInit, Mn as ptyKillSchema, Mt as WireCandidate, N as IdentityKey, Nn as ptyResizeSchema, Nt as candidateKindSchema, O as GossipFrame, On as procKillSchema, Ot as TokenClaims, P as ManageCommand, Pn as ptySpawnSchema, Pt as candidatesFrameSchema, Q as ProcSpawn, Qn as roomPathSchema, Qt as deviceIdHexSchema, R as ManageRequestFrame, Rn as relayInboundFrameSchema, Rt as capabilityTokenSchema, S as DmRoomPath, Sn as ownerNamedRoomPathSchema, St as RoomSend, T as ExecSessionInfo, Tn as pingFrameSchema, Tt as StreamEndFrame, U as ObservedAddressFrame, Un as roomInviteSchema, Ut as coreDomainNameSchema, V as NamespacedCapability, Vn as revocationClaimsSchema, Vt as coordinatorFrameSchema, W as OwnerNamedRoomPath, Wn as roomJoinOkSchema, Wt as coseHeaderAlgSchema, X as ProcKill, Xn as roomNoticeClaimsSchema, Xt as dataHaveFrameSchema, Y as PrivateUseDomainId, Yn as roomMembersSchema, Yt as dataEntriesFrameSchema, Z as ProcSignal, Zn as roomNoticeSchema, Zt as dataRequestFrameSchema, _ as DataEntriesFrame, _n as manageResponseFrameSchema, _t as RoomMembersOk, a as CapabilityScope, an as frameVariantSchema, ar as syncPunchFrameSchema, at as RelayDataFrame, b as DeviceId, bn as namespacedDomainIdSchema, bt as RoomPath, c as CloseFrame, cn as handleRecordSchema, cr as webrtcIceCandidateSchema, ct as RevocationAnnounceFrame, d as CoreDomainName, dn as identityKeySchema, dt as RoomInvite, en as dmRoomPathSchema, er as roomSendSchema, et as PtyKill, f as CoseHeaderAlg, fn as manageCommandParamsSchema, ft as RoomJoin, g as CoseTokenHeaders, gn as manageRequestFrameSchema, gt as RoomMembers, h as CoseSign1, hn as manageOkSchema, ht as RoomMember, i as CapabilityRequest, in as frameSchema, ir as streamSessionSchema, it as RelayConnectFrame, j as HandshakeFrame, jn as protocolVersionSchema, jt as WebrtcOffer, k as HandleClaims, kn as procSignalSchema, kt as WebrtcAnswer, l as CoordinatorFrame, ln as handshakeFrameSchema, lr as webrtcOfferSchema, lt as RevocationClaims, m as CoseHeaderLabel, mn as manageErrorSchema, mt as RoomLeave, n as CandidatesFrame, nn as execListSchema, nr as streamDataFrameSchema, nt as PtySpawn, o as CapabilityToken, on as gossipFrameSchema, or as tokenClaimsSchema, ot as RelayInboundFrame, p as CoseHeaderKid, pn as manageCommandSchema, pt as RoomJoinOk, q as PingFrame, qn as roomMemberSchema, qt as coseSign1Schema, r as CapabilityGrantOk, rn as execSessionInfoSchema, rr as streamEndFrameSchema, rt as PtyWrite, s as CapabilityVerb, sn as handleClaimsSchema, sr as webrtcAnswerSchema, st as RelayOfferFrame, t as CandidateKind, tn as domainIdSchema, tr as streamAckFrameSchema, tt as PtyResize, u as CoreCapability, un as iceCandidateInitSchema, ur as wireCandidateSchema, ut as RevocationEntry, v as DataHaveFrame, vn as messageRefSchema, vt as RoomNotice, w as ExecList, wn as peerIdentitySchema, wt as StreamDataFrame, x as DeviceIdHex, xn as observedAddressFrameSchema, xt as RoomRead, y as DataRequestFrame, yn as namespacedCapabilitySchema, yt as RoomNoticeClaims, z as ManageResponseFrame, zn as relayOfferFrameSchema, zt as capabilityVerbSchema } from "../protocol-MnxTzpRP.cjs";
2
2
  export { CandidateKind, CandidatesFrame, CapabilityGrantOk, CapabilityRequest, CapabilityScope, CapabilityToken, CapabilityVerb, CloseFrame, CoordinatorFrame, CoreCapability, CoreDomainName, CoseHeaderAlg, CoseHeaderKid, CoseHeaderLabel, CoseSign1, CoseTokenHeaders, DataEntriesFrame, DataHaveFrame, DataRequestFrame, DeviceId, DeviceIdHex, DmRoomPath, DomainId, ExecList, ExecSessionInfo, Frame, FrameVariant, GossipFrame, HandleClaims, HandleRecord, HandshakeFrame, IceCandidateInit, IdentityKey, ManageCommand, ManageCommandParams, ManageError, ManageOk, ManageRequestFrame, ManageResponseFrame, MessageRef, NamespacedCapability, NamespacedDomainId, ObservedAddressFrame, OwnerNamedRoomPath, PeerAdvert, PeerIdentity, PingFrame, PrivateUseCapability, PrivateUseDomainId, ProcKill, ProcSignal, ProcSpawn, ProtocolVersion, PtyKill, PtyResize, PtySpawn, PtyWrite, RelayConnectFrame, RelayDataFrame, RelayInboundFrame, RelayOfferFrame, RevocationAnnounceFrame, RevocationClaims, RevocationEntry, RoomInvite, RoomJoin, RoomJoinOk, RoomLeave, RoomMember, RoomMembers, RoomMembersOk, RoomNotice, RoomNoticeClaims, RoomPath, RoomRead, RoomSend, StreamAckFrame, StreamDataFrame, StreamEndFrame, StreamSession, SyncPunchFrame, TokenClaims, WebrtcAnswer, WebrtcIceCandidate, WebrtcOffer, WireCandidate, candidateKindSchema, candidatesFrameSchema, capabilityGrantOkSchema, capabilityRequestSchema, capabilityScopeSchema, capabilityTokenSchema, capabilityVerbSchema, closeFrameSchema, coordinatorFrameSchema, coreCapabilitySchema, coreDomainNameSchema, coseHeaderAlgSchema, coseHeaderKidSchema, coseHeaderLabelSchema, coseSign1Schema, coseTokenHeadersSchema, dataEntriesFrameSchema, dataHaveFrameSchema, dataRequestFrameSchema, deviceIdHexSchema, deviceIdSchema, dmRoomPathSchema, domainIdSchema, execListSchema, execSessionInfoSchema, frameSchema, frameVariantSchema, gossipFrameSchema, handleClaimsSchema, handleRecordSchema, handshakeFrameSchema, iceCandidateInitSchema, identityKeySchema, manageCommandParamsSchema, manageCommandSchema, manageErrorSchema, manageOkSchema, manageRequestFrameSchema, manageResponseFrameSchema, messageRefSchema, namespacedCapabilitySchema, namespacedDomainIdSchema, observedAddressFrameSchema, ownerNamedRoomPathSchema, peerAdvertSchema, peerIdentitySchema, pingFrameSchema, privateUseCapabilitySchema, privateUseDomainIdSchema, procKillSchema, procSignalSchema, procSpawnSchema, protocolVersionSchema, ptyKillSchema, ptyResizeSchema, ptySpawnSchema, ptyWriteSchema, relayConnectFrameSchema, relayDataFrameSchema, relayInboundFrameSchema, relayOfferFrameSchema, revocationAnnounceFrameSchema, revocationClaimsSchema, revocationEntrySchema, roomInviteSchema, roomJoinOkSchema, roomJoinSchema, roomLeaveSchema, roomMemberSchema, roomMembersOkSchema, roomMembersSchema, roomNoticeClaimsSchema, roomNoticeSchema, roomPathSchema, roomReadSchema, roomSendSchema, streamAckFrameSchema, streamDataFrameSchema, streamEndFrameSchema, streamSessionSchema, syncPunchFrameSchema, tokenClaimsSchema, webrtcAnswerSchema, webrtcIceCandidateSchema, webrtcOfferSchema, wireCandidateSchema };
@@ -1,2 +1,2 @@
1
- import { $ as ProtocolVersion, $n as roomReadSchema, $t as deviceIdSchema, A as HandleRecord, An as procSpawnSchema, At as WebrtcIceCandidate, B as MessageRef, Bn as revocationAnnounceFrameSchema, Bt as closeFrameSchema, C as DomainId, Cn as peerAdvertSchema, Ct as StreamAckFrame, D as FrameVariant, Dn as privateUseDomainIdSchema, Dt as SyncPunchFrame, E as Frame, En as privateUseCapabilitySchema, Et as StreamSession, F as ManageCommandParams, Fn as ptyWriteSchema, Ft as capabilityGrantOkSchema, G as PeerAdvert, Gn as roomJoinSchema, Gt as coseHeaderKidSchema, H as NamespacedDomainId, Hn as revocationEntrySchema, Ht as coreCapabilitySchema, I as ManageError, In as relayConnectFrameSchema, It as capabilityRequestSchema, J as PrivateUseCapability, Jn as roomMembersOkSchema, Jt as coseTokenHeadersSchema, K as PeerIdentity, Kn as roomLeaveSchema, Kt as coseHeaderLabelSchema, L as ManageOk, Ln as relayDataFrameSchema, Lt as capabilityScopeSchema, M as IceCandidateInit, Mn as ptyKillSchema, Mt as WireCandidate, N as IdentityKey, Nn as ptyResizeSchema, Nt as candidateKindSchema, O as GossipFrame, On as procKillSchema, Ot as TokenClaims, P as ManageCommand, Pn as ptySpawnSchema, Pt as candidatesFrameSchema, Q as ProcSpawn, Qn as roomPathSchema, Qt as deviceIdHexSchema, R as ManageRequestFrame, Rn as relayInboundFrameSchema, Rt as capabilityTokenSchema, S as DmRoomPath, Sn as ownerNamedRoomPathSchema, St as RoomSend, T as ExecSessionInfo, Tn as pingFrameSchema, Tt as StreamEndFrame, U as ObservedAddressFrame, Un as roomInviteSchema, Ut as coreDomainNameSchema, V as NamespacedCapability, Vn as revocationClaimsSchema, Vt as coordinatorFrameSchema, W as OwnerNamedRoomPath, Wn as roomJoinOkSchema, Wt as coseHeaderAlgSchema, X as ProcKill, Xn as roomNoticeClaimsSchema, Xt as dataHaveFrameSchema, Y as PrivateUseDomainId, Yn as roomMembersSchema, Yt as dataEntriesFrameSchema, Z as ProcSignal, Zn as roomNoticeSchema, Zt as dataRequestFrameSchema, _ as DataEntriesFrame, _n as manageResponseFrameSchema, _t as RoomMembersOk, a as CapabilityScope, an as frameVariantSchema, ar as syncPunchFrameSchema, at as RelayDataFrame, b as DeviceId, bn as namespacedDomainIdSchema, bt as RoomPath, c as CloseFrame, cn as handleRecordSchema, cr as webrtcIceCandidateSchema, ct as RevocationAnnounceFrame, d as CoreDomainName, dn as identityKeySchema, dt as RoomInvite, en as dmRoomPathSchema, er as roomSendSchema, et as PtyKill, f as CoseHeaderAlg, fn as manageCommandParamsSchema, ft as RoomJoin, g as CoseTokenHeaders, gn as manageRequestFrameSchema, gt as RoomMembers, h as CoseSign1, hn as manageOkSchema, ht as RoomMember, i as CapabilityRequest, in as frameSchema, ir as streamSessionSchema, it as RelayConnectFrame, j as HandshakeFrame, jn as protocolVersionSchema, jt as WebrtcOffer, k as HandleClaims, kn as procSignalSchema, kt as WebrtcAnswer, l as CoordinatorFrame, ln as handshakeFrameSchema, lr as webrtcOfferSchema, lt as RevocationClaims, m as CoseHeaderLabel, mn as manageErrorSchema, mt as RoomLeave, n as CandidatesFrame, nn as execListSchema, nr as streamDataFrameSchema, nt as PtySpawn, o as CapabilityToken, on as gossipFrameSchema, or as tokenClaimsSchema, ot as RelayInboundFrame, p as CoseHeaderKid, pn as manageCommandSchema, pt as RoomJoinOk, q as PingFrame, qn as roomMemberSchema, qt as coseSign1Schema, r as CapabilityGrantOk, rn as execSessionInfoSchema, rr as streamEndFrameSchema, rt as PtyWrite, s as CapabilityVerb, sn as handleClaimsSchema, sr as webrtcAnswerSchema, st as RelayOfferFrame, t as CandidateKind, tn as domainIdSchema, tr as streamAckFrameSchema, tt as PtyResize, u as CoreCapability, un as iceCandidateInitSchema, ur as wireCandidateSchema, ut as RevocationEntry, v as DataHaveFrame, vn as messageRefSchema, vt as RoomNotice, w as ExecList, wn as peerIdentitySchema, wt as StreamDataFrame, x as DeviceIdHex, xn as observedAddressFrameSchema, xt as RoomRead, y as DataRequestFrame, yn as namespacedCapabilitySchema, yt as RoomNoticeClaims, z as ManageResponseFrame, zn as relayOfferFrameSchema, zt as capabilityVerbSchema } from "../protocol-BwFGx9cg.mjs";
1
+ import { $ as ProtocolVersion, $n as roomReadSchema, $t as deviceIdSchema, A as HandleRecord, An as procSpawnSchema, At as WebrtcIceCandidate, B as MessageRef, Bn as revocationAnnounceFrameSchema, Bt as closeFrameSchema, C as DomainId, Cn as peerAdvertSchema, Ct as StreamAckFrame, D as FrameVariant, Dn as privateUseDomainIdSchema, Dt as SyncPunchFrame, E as Frame, En as privateUseCapabilitySchema, Et as StreamSession, F as ManageCommandParams, Fn as ptyWriteSchema, Ft as capabilityGrantOkSchema, G as PeerAdvert, Gn as roomJoinSchema, Gt as coseHeaderKidSchema, H as NamespacedDomainId, Hn as revocationEntrySchema, Ht as coreCapabilitySchema, I as ManageError, In as relayConnectFrameSchema, It as capabilityRequestSchema, J as PrivateUseCapability, Jn as roomMembersOkSchema, Jt as coseTokenHeadersSchema, K as PeerIdentity, Kn as roomLeaveSchema, Kt as coseHeaderLabelSchema, L as ManageOk, Ln as relayDataFrameSchema, Lt as capabilityScopeSchema, M as IceCandidateInit, Mn as ptyKillSchema, Mt as WireCandidate, N as IdentityKey, Nn as ptyResizeSchema, Nt as candidateKindSchema, O as GossipFrame, On as procKillSchema, Ot as TokenClaims, P as ManageCommand, Pn as ptySpawnSchema, Pt as candidatesFrameSchema, Q as ProcSpawn, Qn as roomPathSchema, Qt as deviceIdHexSchema, R as ManageRequestFrame, Rn as relayInboundFrameSchema, Rt as capabilityTokenSchema, S as DmRoomPath, Sn as ownerNamedRoomPathSchema, St as RoomSend, T as ExecSessionInfo, Tn as pingFrameSchema, Tt as StreamEndFrame, U as ObservedAddressFrame, Un as roomInviteSchema, Ut as coreDomainNameSchema, V as NamespacedCapability, Vn as revocationClaimsSchema, Vt as coordinatorFrameSchema, W as OwnerNamedRoomPath, Wn as roomJoinOkSchema, Wt as coseHeaderAlgSchema, X as ProcKill, Xn as roomNoticeClaimsSchema, Xt as dataHaveFrameSchema, Y as PrivateUseDomainId, Yn as roomMembersSchema, Yt as dataEntriesFrameSchema, Z as ProcSignal, Zn as roomNoticeSchema, Zt as dataRequestFrameSchema, _ as DataEntriesFrame, _n as manageResponseFrameSchema, _t as RoomMembersOk, a as CapabilityScope, an as frameVariantSchema, ar as syncPunchFrameSchema, at as RelayDataFrame, b as DeviceId, bn as namespacedDomainIdSchema, bt as RoomPath, c as CloseFrame, cn as handleRecordSchema, cr as webrtcIceCandidateSchema, ct as RevocationAnnounceFrame, d as CoreDomainName, dn as identityKeySchema, dt as RoomInvite, en as dmRoomPathSchema, er as roomSendSchema, et as PtyKill, f as CoseHeaderAlg, fn as manageCommandParamsSchema, ft as RoomJoin, g as CoseTokenHeaders, gn as manageRequestFrameSchema, gt as RoomMembers, h as CoseSign1, hn as manageOkSchema, ht as RoomMember, i as CapabilityRequest, in as frameSchema, ir as streamSessionSchema, it as RelayConnectFrame, j as HandshakeFrame, jn as protocolVersionSchema, jt as WebrtcOffer, k as HandleClaims, kn as procSignalSchema, kt as WebrtcAnswer, l as CoordinatorFrame, ln as handshakeFrameSchema, lr as webrtcOfferSchema, lt as RevocationClaims, m as CoseHeaderLabel, mn as manageErrorSchema, mt as RoomLeave, n as CandidatesFrame, nn as execListSchema, nr as streamDataFrameSchema, nt as PtySpawn, o as CapabilityToken, on as gossipFrameSchema, or as tokenClaimsSchema, ot as RelayInboundFrame, p as CoseHeaderKid, pn as manageCommandSchema, pt as RoomJoinOk, q as PingFrame, qn as roomMemberSchema, qt as coseSign1Schema, r as CapabilityGrantOk, rn as execSessionInfoSchema, rr as streamEndFrameSchema, rt as PtyWrite, s as CapabilityVerb, sn as handleClaimsSchema, sr as webrtcAnswerSchema, st as RelayOfferFrame, t as CandidateKind, tn as domainIdSchema, tr as streamAckFrameSchema, tt as PtyResize, u as CoreCapability, un as iceCandidateInitSchema, ur as wireCandidateSchema, ut as RevocationEntry, v as DataHaveFrame, vn as messageRefSchema, vt as RoomNotice, w as ExecList, wn as peerIdentitySchema, wt as StreamDataFrame, x as DeviceIdHex, xn as observedAddressFrameSchema, xt as RoomRead, y as DataRequestFrame, yn as namespacedCapabilitySchema, yt as RoomNoticeClaims, z as ManageResponseFrame, zn as relayOfferFrameSchema, zt as capabilityVerbSchema } from "../protocol-MnxTzpRP.mjs";
2
2
  export { CandidateKind, CandidatesFrame, CapabilityGrantOk, CapabilityRequest, CapabilityScope, CapabilityToken, CapabilityVerb, CloseFrame, CoordinatorFrame, CoreCapability, CoreDomainName, CoseHeaderAlg, CoseHeaderKid, CoseHeaderLabel, CoseSign1, CoseTokenHeaders, DataEntriesFrame, DataHaveFrame, DataRequestFrame, DeviceId, DeviceIdHex, DmRoomPath, DomainId, ExecList, ExecSessionInfo, Frame, FrameVariant, GossipFrame, HandleClaims, HandleRecord, HandshakeFrame, IceCandidateInit, IdentityKey, ManageCommand, ManageCommandParams, ManageError, ManageOk, ManageRequestFrame, ManageResponseFrame, MessageRef, NamespacedCapability, NamespacedDomainId, ObservedAddressFrame, OwnerNamedRoomPath, PeerAdvert, PeerIdentity, PingFrame, PrivateUseCapability, PrivateUseDomainId, ProcKill, ProcSignal, ProcSpawn, ProtocolVersion, PtyKill, PtyResize, PtySpawn, PtyWrite, RelayConnectFrame, RelayDataFrame, RelayInboundFrame, RelayOfferFrame, RevocationAnnounceFrame, RevocationClaims, RevocationEntry, RoomInvite, RoomJoin, RoomJoinOk, RoomLeave, RoomMember, RoomMembers, RoomMembersOk, RoomNotice, RoomNoticeClaims, RoomPath, RoomRead, RoomSend, StreamAckFrame, StreamDataFrame, StreamEndFrame, StreamSession, SyncPunchFrame, TokenClaims, WebrtcAnswer, WebrtcIceCandidate, WebrtcOffer, WireCandidate, candidateKindSchema, candidatesFrameSchema, capabilityGrantOkSchema, capabilityRequestSchema, capabilityScopeSchema, capabilityTokenSchema, capabilityVerbSchema, closeFrameSchema, coordinatorFrameSchema, coreCapabilitySchema, coreDomainNameSchema, coseHeaderAlgSchema, coseHeaderKidSchema, coseHeaderLabelSchema, coseSign1Schema, coseTokenHeadersSchema, dataEntriesFrameSchema, dataHaveFrameSchema, dataRequestFrameSchema, deviceIdHexSchema, deviceIdSchema, dmRoomPathSchema, domainIdSchema, execListSchema, execSessionInfoSchema, frameSchema, frameVariantSchema, gossipFrameSchema, handleClaimsSchema, handleRecordSchema, handshakeFrameSchema, iceCandidateInitSchema, identityKeySchema, manageCommandParamsSchema, manageCommandSchema, manageErrorSchema, manageOkSchema, manageRequestFrameSchema, manageResponseFrameSchema, messageRefSchema, namespacedCapabilitySchema, namespacedDomainIdSchema, observedAddressFrameSchema, ownerNamedRoomPathSchema, peerAdvertSchema, peerIdentitySchema, pingFrameSchema, privateUseCapabilitySchema, privateUseDomainIdSchema, procKillSchema, procSignalSchema, procSpawnSchema, protocolVersionSchema, ptyKillSchema, ptyResizeSchema, ptySpawnSchema, ptyWriteSchema, relayConnectFrameSchema, relayDataFrameSchema, relayInboundFrameSchema, relayOfferFrameSchema, revocationAnnounceFrameSchema, revocationClaimsSchema, revocationEntrySchema, roomInviteSchema, roomJoinOkSchema, roomJoinSchema, roomLeaveSchema, roomMemberSchema, roomMembersOkSchema, roomMembersSchema, roomNoticeClaimsSchema, roomNoticeSchema, roomPathSchema, roomReadSchema, roomSendSchema, streamAckFrameSchema, streamDataFrameSchema, streamEndFrameSchema, streamSessionSchema, syncPunchFrameSchema, tokenClaimsSchema, webrtcAnswerSchema, webrtcIceCandidateSchema, webrtcOfferSchema, wireCandidateSchema };
@@ -246,7 +246,8 @@ const roomNoticeClaimsSchema = z.lazy(() => z.object({
246
246
  "posted-at": z.number().int().nonnegative(),
247
247
  "content-type": z.string(),
248
248
  "content": z.instanceof(Uint8Array),
249
- "refs": z.array(z.lazy(() => messageRefSchema)).optional()
249
+ "refs": z.array(z.lazy(() => messageRefSchema)).optional(),
250
+ "valid-until": z.number().int().nonnegative().optional()
250
251
  }).catchall(z.unknown()));
251
252
  const streamSessionSchema = z.lazy(() => z.number().int().nonnegative());
252
253
  const streamDataFrameSchema = z.lazy(() => z.object({
@@ -304,7 +305,8 @@ const tokenClaimsSchema = z.lazy(() => z.object({
304
305
  "expires": z.number().int().nonnegative(),
305
306
  "not-before": z.number().int().nonnegative().optional(),
306
307
  "parent": z.instanceof(Uint8Array).optional(),
307
- "delegations-remaining": z.number().int().nonnegative().optional()
308
+ "delegations-remaining": z.number().int().nonnegative().optional(),
309
+ "valid-until": z.number().int().nonnegative().optional()
308
310
  }).catchall(z.unknown()));
309
311
  const pingFrameSchema = z.lazy(() => z.object({ "type": z.literal("ping") }));
310
312
  const closeFrameSchema = z.lazy(() => z.object({
@@ -1,4 +1,4 @@
1
- import { N as IdentityKey, b as DeviceId } from "./protocol-BwFGx9cg.mjs";
1
+ import { N as IdentityKey, b as DeviceId } from "./protocol-MnxTzpRP.mjs";
2
2
  //#region src/ports/identity.d.ts
3
3
  /**
4
4
  * Wraps the local node's own identity plus the signing/verification primitives capability-token handling needs -- never hardcoded to one crypto library's own API shape (Node's webcrypto, a WASM implementation, a hardware key, etc. can all satisfy this same contract).
@@ -1,4 +1,4 @@
1
- import { N as IdentityKey, b as DeviceId } from "./protocol-BwFGx9cg.cjs";
1
+ import { N as IdentityKey, b as DeviceId } from "./protocol-MnxTzpRP.cjs";
2
2
  //#region src/ports/identity.d.ts
3
3
  /**
4
4
  * Wraps the local node's own identity plus the signing/verification primitives capability-token handling needs -- never hardcoded to one crypto library's own API shape (Node's webcrypto, a WASM implementation, a hardware key, etc. can all satisfy this same contract).
@@ -1,2 +1,2 @@
1
- import { t as IdentityPort } from "../identity-ijL0IsUT.cjs";
1
+ import { t as IdentityPort } from "../identity-DkEe1465.cjs";
2
2
  export { IdentityPort };
@@ -1,2 +1,2 @@
1
- import { t as IdentityPort } from "../identity-DvBEkcS9.mjs";
1
+ import { t as IdentityPort } from "../identity-D8iJZRZZ.mjs";
2
2
  export { IdentityPort };
@@ -1,29 +1,2 @@
1
- import { E as Frame, b as DeviceId } from "../protocol-BwFGx9cg.cjs";
2
- //#region src/ports/transport.d.ts
3
- /**
4
- * An async, serialisable-data contract for exchanging frame values over some connection -- deliberately without baking in any specific transport's own primitives (no raw socket types, no WebSocket-specific options), so a TCP adapter, a WebSocket adapter, or an in-memory adapter for tests can all satisfy it.
5
- */
6
- export interface Connection {
7
- send: (frame: Frame) => Promise<void>;
8
- /** Frames received on this connection, in arrival order, until the connection closes. */
9
- receive: () => AsyncIterable<Frame>;
10
- close: () => Promise<void>;
11
- /** The peer's device-id, cryptographically authenticated by the adapter itself (never a value read off the wire) -- absent when the adapter has nothing to authenticate against (createTcpTransport) or the peer presented no credential to check (an accepting createTlsTransport connection whose peer sent no certificate). A caller that later receives an application-level claim of who the peer is (e.g. an `introduce`-style message) MUST treat a mismatch against this field as a spoofing attempt and refuse the claim, exactly the same "reject and destroy" obligation self-certifying claims elsewhere in this spec already carry. */
12
- readonly peerDeviceId?: DeviceId;
13
- /** Lets the event loop exit while this connection is still open and functioning -- a caller that wants I/O to keep working without keeping the process alive (matching Node's own `net.Socket.unref()`) calls this once. Adapters with no underlying handle to unref (an in-memory test double, a browser WebSocket) simply omit it. */
14
- unref?: () => void;
15
- }
16
- export interface Listener {
17
- /** Stops listening and closes the listener. */
18
- close: () => Promise<void>;
19
- /** The address actually bound, as "host:port". A caller may pass port 0 to take an OS-assigned port and needs it handed back to connect to (or advertise) -- tests rely on this to avoid fixed-port collisions. */
20
- address: string;
21
- /** Lets the event loop exit while this listener is still bound and accepting connections. See Connection.unref for the same rationale; adapters with nothing to unref omit it. */
22
- unref?: () => void;
23
- }
24
- export interface Transport {
25
- connect: (address: string) => Promise<Connection>;
26
- /** Starts listening; each accepted connection is handed to onConnection. Resolves once bound, with the address actually listening on. */
27
- listen: (address: string, onConnection: (connection: Readonly<Connection>) => void) => Promise<Listener>;
28
- }
29
- //#endregion
1
+ import { n as Listener, r as Transport, t as Connection } from "../transport-Da7GP9ya.cjs";
2
+ export { Connection, Listener, Transport };
@@ -1,29 +1,2 @@
1
- import { E as Frame, b as DeviceId } from "../protocol-BwFGx9cg.mjs";
2
- //#region src/ports/transport.d.ts
3
- /**
4
- * An async, serialisable-data contract for exchanging frame values over some connection -- deliberately without baking in any specific transport's own primitives (no raw socket types, no WebSocket-specific options), so a TCP adapter, a WebSocket adapter, or an in-memory adapter for tests can all satisfy it.
5
- */
6
- export interface Connection {
7
- send: (frame: Frame) => Promise<void>;
8
- /** Frames received on this connection, in arrival order, until the connection closes. */
9
- receive: () => AsyncIterable<Frame>;
10
- close: () => Promise<void>;
11
- /** The peer's device-id, cryptographically authenticated by the adapter itself (never a value read off the wire) -- absent when the adapter has nothing to authenticate against (createTcpTransport) or the peer presented no credential to check (an accepting createTlsTransport connection whose peer sent no certificate). A caller that later receives an application-level claim of who the peer is (e.g. an `introduce`-style message) MUST treat a mismatch against this field as a spoofing attempt and refuse the claim, exactly the same "reject and destroy" obligation self-certifying claims elsewhere in this spec already carry. */
12
- readonly peerDeviceId?: DeviceId;
13
- /** Lets the event loop exit while this connection is still open and functioning -- a caller that wants I/O to keep working without keeping the process alive (matching Node's own `net.Socket.unref()`) calls this once. Adapters with no underlying handle to unref (an in-memory test double, a browser WebSocket) simply omit it. */
14
- unref?: () => void;
15
- }
16
- export interface Listener {
17
- /** Stops listening and closes the listener. */
18
- close: () => Promise<void>;
19
- /** The address actually bound, as "host:port". A caller may pass port 0 to take an OS-assigned port and needs it handed back to connect to (or advertise) -- tests rely on this to avoid fixed-port collisions. */
20
- address: string;
21
- /** Lets the event loop exit while this listener is still bound and accepting connections. See Connection.unref for the same rationale; adapters with nothing to unref omit it. */
22
- unref?: () => void;
23
- }
24
- export interface Transport {
25
- connect: (address: string) => Promise<Connection>;
26
- /** Starts listening; each accepted connection is handed to onConnection. Resolves once bound, with the address actually listening on. */
27
- listen: (address: string, onConnection: (connection: Readonly<Connection>) => void) => Promise<Listener>;
28
- }
29
- //#endregion
1
+ import { n as Listener, r as Transport, t as Connection } from "../transport-ESMXRz3s.mjs";
2
+ export { Connection, Listener, Transport };
@@ -901,6 +901,7 @@ declare const roomNoticeClaimsSchema: z.ZodLazy<z.ZodObject<{
901
901
  id: z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>;
902
902
  relation: z.ZodString;
903
903
  }, z.core.$strip>>>>>;
904
+ "valid-until": z.ZodOptional<z.ZodNumber>;
904
905
  }, z.core.$catchall<z.ZodUnknown>>>;
905
906
  declare const streamSessionSchema: z.ZodLazy<z.ZodNumber>;
906
907
  declare const streamDataFrameSchema: z.ZodLazy<z.ZodObject<{
@@ -962,6 +963,7 @@ declare const tokenClaimsSchema: z.ZodLazy<z.ZodObject<{
962
963
  "not-before": z.ZodOptional<z.ZodNumber>;
963
964
  parent: z.ZodOptional<z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>>;
964
965
  "delegations-remaining": z.ZodOptional<z.ZodNumber>;
966
+ "valid-until": z.ZodOptional<z.ZodNumber>;
965
967
  }, z.core.$catchall<z.ZodUnknown>>>;
966
968
  declare const pingFrameSchema: z.ZodLazy<z.ZodObject<{
967
969
  type: z.ZodLiteral<"ping">;
@@ -901,6 +901,7 @@ declare const roomNoticeClaimsSchema: z.ZodLazy<z.ZodObject<{
901
901
  id: z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>;
902
902
  relation: z.ZodString;
903
903
  }, z.core.$strip>>>>>;
904
+ "valid-until": z.ZodOptional<z.ZodNumber>;
904
905
  }, z.core.$catchall<z.ZodUnknown>>>;
905
906
  declare const streamSessionSchema: z.ZodLazy<z.ZodNumber>;
906
907
  declare const streamDataFrameSchema: z.ZodLazy<z.ZodObject<{
@@ -962,6 +963,7 @@ declare const tokenClaimsSchema: z.ZodLazy<z.ZodObject<{
962
963
  "not-before": z.ZodOptional<z.ZodNumber>;
963
964
  parent: z.ZodOptional<z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>>;
964
965
  "delegations-remaining": z.ZodOptional<z.ZodNumber>;
966
+ "valid-until": z.ZodOptional<z.ZodNumber>;
965
967
  }, z.core.$catchall<z.ZodUnknown>>>;
966
968
  declare const pingFrameSchema: z.ZodLazy<z.ZodObject<{
967
969
  type: z.ZodLiteral<"ping">;
@@ -0,0 +1,30 @@
1
+ import { E as Frame, b as DeviceId } from "./protocol-MnxTzpRP.cjs";
2
+ //#region src/ports/transport.d.ts
3
+ /**
4
+ * An async, serialisable-data contract for exchanging frame values over some connection -- deliberately without baking in any specific transport's own primitives (no raw socket types, no WebSocket-specific options), so a TCP adapter, a WebSocket adapter, or an in-memory adapter for tests can all satisfy it.
5
+ */
6
+ interface Connection {
7
+ send: (frame: Frame) => Promise<void>;
8
+ /** Frames received on this connection, in arrival order, until the connection closes. */
9
+ receive: () => AsyncIterable<Frame>;
10
+ close: () => Promise<void>;
11
+ /** The peer's device-id, cryptographically authenticated by the adapter itself (never a value read off the wire) -- absent when the adapter has nothing to authenticate against (createTcpTransport) or the peer presented no credential to check (an accepting createTlsTransport connection whose peer sent no certificate). A caller that later receives an application-level claim of who the peer is (e.g. an `introduce`-style message) MUST treat a mismatch against this field as a spoofing attempt and refuse the claim, exactly the same "reject and destroy" obligation self-certifying claims elsewhere in this spec already carry. */
12
+ readonly peerDeviceId?: DeviceId;
13
+ /** Lets the event loop exit while this connection is still open and functioning -- a caller that wants I/O to keep working without keeping the process alive (matching Node's own `net.Socket.unref()`) calls this once. Adapters with no underlying handle to unref (an in-memory test double, a browser WebSocket) simply omit it. */
14
+ unref?: () => void;
15
+ }
16
+ interface Listener {
17
+ /** Stops listening and closes the listener. */
18
+ close: () => Promise<void>;
19
+ /** The address actually bound, as "host:port". A caller may pass port 0 to take an OS-assigned port and needs it handed back to connect to (or advertise) -- tests rely on this to avoid fixed-port collisions. */
20
+ address: string;
21
+ /** Lets the event loop exit while this listener is still bound and accepting connections. See Connection.unref for the same rationale; adapters with nothing to unref omit it. */
22
+ unref?: () => void;
23
+ }
24
+ interface Transport {
25
+ connect: (address: string) => Promise<Connection>;
26
+ /** Starts listening; each accepted connection is handed to onConnection. Resolves once bound, with the address actually listening on. */
27
+ listen: (address: string, onConnection: (connection: Readonly<Connection>) => void) => Promise<Listener>;
28
+ }
29
+ //#endregion
30
+ export { Listener as n, Transport as r, Connection as t };
@@ -0,0 +1,30 @@
1
+ import { E as Frame, b as DeviceId } from "./protocol-MnxTzpRP.mjs";
2
+ //#region src/ports/transport.d.ts
3
+ /**
4
+ * An async, serialisable-data contract for exchanging frame values over some connection -- deliberately without baking in any specific transport's own primitives (no raw socket types, no WebSocket-specific options), so a TCP adapter, a WebSocket adapter, or an in-memory adapter for tests can all satisfy it.
5
+ */
6
+ interface Connection {
7
+ send: (frame: Frame) => Promise<void>;
8
+ /** Frames received on this connection, in arrival order, until the connection closes. */
9
+ receive: () => AsyncIterable<Frame>;
10
+ close: () => Promise<void>;
11
+ /** The peer's device-id, cryptographically authenticated by the adapter itself (never a value read off the wire) -- absent when the adapter has nothing to authenticate against (createTcpTransport) or the peer presented no credential to check (an accepting createTlsTransport connection whose peer sent no certificate). A caller that later receives an application-level claim of who the peer is (e.g. an `introduce`-style message) MUST treat a mismatch against this field as a spoofing attempt and refuse the claim, exactly the same "reject and destroy" obligation self-certifying claims elsewhere in this spec already carry. */
12
+ readonly peerDeviceId?: DeviceId;
13
+ /** Lets the event loop exit while this connection is still open and functioning -- a caller that wants I/O to keep working without keeping the process alive (matching Node's own `net.Socket.unref()`) calls this once. Adapters with no underlying handle to unref (an in-memory test double, a browser WebSocket) simply omit it. */
14
+ unref?: () => void;
15
+ }
16
+ interface Listener {
17
+ /** Stops listening and closes the listener. */
18
+ close: () => Promise<void>;
19
+ /** The address actually bound, as "host:port". A caller may pass port 0 to take an OS-assigned port and needs it handed back to connect to (or advertise) -- tests rely on this to avoid fixed-port collisions. */
20
+ address: string;
21
+ /** Lets the event loop exit while this listener is still bound and accepting connections. See Connection.unref for the same rationale; adapters with nothing to unref omit it. */
22
+ unref?: () => void;
23
+ }
24
+ interface Transport {
25
+ connect: (address: string) => Promise<Connection>;
26
+ /** Starts listening; each accepted connection is handed to onConnection. Resolves once bound, with the address actually listening on. */
27
+ listen: (address: string, onConnection: (connection: Readonly<Connection>) => void) => Promise<Listener>;
28
+ }
29
+ //#endregion
30
+ export { Listener as n, Transport as r, Connection as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wire-mesh-core",
3
- "version": "1.13.4",
3
+ "version": "1.15.0",
4
4
  "type": "module",
5
5
  "packageManager": "pnpm@12.4.1+sha512.2e81e399d73fe8390dab25e06aa788ab7a5908248d2f5a370f82b481147a6a7a367bf8048f9a6fdb6460f21a66f0542dedb8b94ca2c8723596741920b1656d4c",
6
6
  "repository": {
@@ -85,6 +85,10 @@
85
85
  "import": "./dist/adapters/tls-transport.mjs",
86
86
  "require": "./dist/adapters/tls-transport.cjs"
87
87
  },
88
+ "./domain/capability-request": {
89
+ "import": "./dist/domain/capability-request.mjs",
90
+ "require": "./dist/domain/capability-request.cjs"
91
+ },
88
92
  "./domain/device-id": {
89
93
  "import": "./dist/domain/device-id.mjs",
90
94
  "require": "./dist/domain/device-id.cjs"