@hediet/linkrpc 0.0.3-next.20261023.2 → 0.0.3-next.20261023.3
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.
- package/dist/chunks/{linkRpcConnection-Dz1FDKh-.js → linkRpcConnection-BLjQ5EjB.js} +2 -2
- package/dist/chunks/linkRpcConnection-BLjQ5EjB.js.map +1 -0
- package/dist/chunks/{protocol-CJ_b2cuh.js → protocol-qBm1sBa-.js} +2 -2
- package/dist/chunks/{protocol-CJ_b2cuh.js.map → protocol-qBm1sBa-.js.map} +1 -1
- package/dist/chunks/{src-BUin-ksi.js → src-CqdS6tWU.js} +2 -2
- package/dist/chunks/{src-BUin-ksi.js.map → src-CqdS6tWU.js.map} +1 -1
- package/dist/http/client.js +2 -2
- package/dist/http/server.js +2 -2
- package/dist/hub/client/index.js +2 -2
- package/dist/hub/common/index.js +2 -2
- package/dist/index.js +2 -2
- package/dist/node.js +2 -2
- package/dist/web.js +2 -2
- package/package.json +2 -2
- package/dist/chunks/linkRpcConnection-Dz1FDKh-.js.map +0 -1
|
@@ -299,7 +299,7 @@ const directoryInterface = defineInterface({
|
|
|
299
299
|
items: array(zServiceListing),
|
|
300
300
|
/** Omitted => no more pages. */
|
|
301
301
|
nextCursor: optional(string()),
|
|
302
|
-
/** True if
|
|
302
|
+
/** True if `timeoutMs` cut the page short before exhausting results. */
|
|
303
303
|
truncated: optional(boolean())
|
|
304
304
|
})),
|
|
305
305
|
/**
|
|
@@ -2602,4 +2602,4 @@ function notFound(reason, method) {
|
|
|
2602
2602
|
//#endregion
|
|
2603
2603
|
export { HUBRPC_SIGNATURE_KEY as A, withSignature as B, directoryInterface as C, requireObjectParams as D, zServiceIdPattern as E, getKeyId as F, NonCompliantServerError as G, parseMethodName as H, readSignature as I, signedHash as L, LINKRPC_META_KEY as M, LINKRPC_SIGNATURE_KEY as N, stripLinkRpcWireMeta as O, LINKRPC_UNSIGNED_KEY as P, signingDomainValue as R, defaultsInterface as S, schemasInterface as T, bareInterfaceTarget as U, methodNameToTarget as V, validateBarePrefix as W, serviceIdMatchesScopes as _, isInterfaceTarget as a, DEFAULT_RPC_TIMEOUT_MS as b, RpcError as c, fetchDirectory as d, fetchSchema as f, serviceIdMatchesPattern as g, normalizeServiceIdScopes as h, interfaceTarget as i, HUBRPC_UNSIGNED_KEY as j, HUBRPC_META_KEY as k, DEFAULT_WALK_DEPTH as l, intersectServiceIdScopes as m, ServiceHandle as n, JsonRpcChannel as o, findMethodInSchema as p, defaultInterfaceTarget as r, Channel as s, LinkRpcConnection as t, HubDirectoryExplorer as u, walkHub as v, directoryWatchNever as w, withRpcTimeout as x, walkHubDetailed as y, signingInput as z };
|
|
2604
2604
|
|
|
2605
|
-
//# sourceMappingURL=linkRpcConnection-
|
|
2605
|
+
//# sourceMappingURL=linkRpcConnection-BLjQ5EjB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linkRpcConnection-BLjQ5EjB.js","names":[],"sources":["../../src/connection/nonCompliantServerError.ts","../../src/connection/bareInterfaceTarget.ts","../../src/protocol/methodName.ts","../../src/protocol/signedObject.ts","../../src/protocol/linkRpcEnvelope.ts","../../src/hub/common/reflection.interfaces.ts","../../src/connection/requestTimeout.ts","../../src/hub/common/directoryWalk.ts","../../src/connection/channel.ts","../../src/connection/jsonRpcChannel.ts","../../src/connection/interfaceTarget.ts","../../src/connection/linkRpcConnection.ts"],"sourcesContent":["import type { JsonRpcError } from '../protocol/jsonRpc';\nimport type { JsonSchemaValidationIssue } from '../schema/validationIssue';\n\n/** JSON Pointer diagnostics relative to the original wire error. */\nexport type RpcValidationIssue = JsonSchemaValidationIssue;\n\nexport class NonCompliantServerError extends Error {\n readonly kind = 'nonCompliantServer' as const;\n\n constructor(\n public readonly original: JsonRpcError['error'],\n public readonly issues: readonly RpcValidationIssue[],\n ) {\n super(`Server error ${original.code} does not match its declared schema: ${\n issues.map((issue) => `${issue.path || '/'}: ${issue.message}`).join('; ')\n }`);\n this.name = 'NonCompliantServerError';\n }\n}\n","import type { InterfaceDefinition } from './interfaceDefinition';\n\n/** A metadata-free foreign-protocol interface and its wire-method prefix. */\nexport interface BareInterfaceTarget<TDef extends InterfaceDefinition<any>> {\n readonly mode: 'bare';\n readonly interface: TDef;\n readonly prefix: string;\n}\n\n/**\n * Bundle an interface definition with metadata-free foreign-protocol\n * addressing for use with `connection.get(target)` or\n * `connection.register(target, handlers)`.\n */\nexport function bareInterfaceTarget<TDef extends InterfaceDefinition<any>>(\n iface: TDef,\n options: { readonly prefix?: string } = {},\n): BareInterfaceTarget<TDef> {\n const prefix = options.prefix ?? '';\n validateBarePrefix(prefix);\n return Object.freeze({\n mode: 'bare' as const,\n interface: iface,\n prefix,\n });\n}\n\nexport function isBareInterfaceTarget<TDef extends InterfaceDefinition<any>>(\n value: TDef | BareInterfaceTarget<TDef>,\n): value is BareInterfaceTarget<TDef> {\n return typeof value === 'object'\n && value !== null\n && 'mode' in value\n && value.mode === 'bare'\n && 'interface' in value\n && 'prefix' in value;\n}\n\nexport function validateBarePrefix(\n prefix: string,\n): void {\n if (prefix.includes('::') || !/^[\\x20-\\x7e]*$/.test(prefix)) {\n throw new Error('Bare interface prefix must contain only printable ASCII and must not contain \"::\".');\n }\n}\n","import type { CallTarget } from \"./capability\";\n\n/**\n * Parsed JSON-RPC method string. The linkrpc dialect uses `::` to\n * separate up to three segments:\n *\n * - `\"member\"` — bare (preset-bound dispatch)\n * - `\"interfaceId::member\"` — interface form (root service)\n * - `\"::interfaceId::member\"` — explicit root form\n * - `\"serviceId::interfaceId::member\"` — fully-qualified form\n *\n * The hub does not accept the `bare` form (it has no interface context\n * to route on). Connection-level dispatch accepts all three.\n */\nexport type ParsedMethodName =\n | { kind: \"bare\"; member: string }\n | { kind: \"interface\"; interfaceId: string; member: string }\n | { kind: \"full\"; serviceId: string; interfaceId: string; member: string };\n\n/**\n * Parse a JSON-RPC method string. Returns `undefined` if any segment is\n * empty or the segment count is out of range.\n */\nexport function parseMethodName(method: string): ParsedMethodName | undefined {\n const parts = method.split(\"::\");\n if (parts.length === 3 && parts[0].length === 0 && parts[1].length > 0 && parts[2].length > 0) {\n return { kind: \"interface\", interfaceId: parts[1], member: parts[2] };\n }\n if (parts.some((p) => p.length === 0)) return undefined;\n if (parts.length === 1) return { kind: \"bare\", member: parts[0] };\n if (parts.length === 2) return { kind: \"interface\", interfaceId: parts[0], member: parts[1] };\n if (parts.length === 3) return { kind: \"full\", serviceId: parts[0], interfaceId: parts[1], member: parts[2] };\n return undefined;\n}\n\n/**\n * Convert a parsed method string to a {@link CallTarget} for capability\n * matching. Interface-form calls are addressed to the root service —\n * represented as an empty `serviceId`. Throws on `bare` form (no\n * interface context) and on malformed input.\n */\nexport function methodNameToTarget(method: string): CallTarget {\n const p = parseMethodName(method);\n if (!p) throw new Error(`linkrpc: malformed method: ${method}`);\n if (p.kind === \"bare\") {\n throw new Error(`linkrpc: bare method has no interface context: ${method}`);\n }\n if (p.kind === \"interface\") {\n return { serviceId: \"\", interfaceId: p.interfaceId, member: p.member };\n }\n return { serviceId: p.serviceId, interfaceId: p.interfaceId, member: p.member };\n}\n","/**\n * The HubRPC **signed-object** standard: one rule for committing a\n * signature (and a content hash) over any JSON object.\n *\n * > The signature `obj.$hubrpcSignature[domain]` covers\n * > `jcs({ [domainValue(domain)]: obj without $hubrpcSignature and $hubrpcUnsigned })`.\n *\n * Both reserved keys are stripped before canonicalization — on **every**\n * object, call or capability alike:\n *\n * - {@link HUBRPC_SIGNATURE_KEY} (`$hubrpcSignature`) holds the signature\n * itself (a domain-keyed map of `{ keyId, sig }` entries). It can't sign\n * itself, so it's excluded.\n * - {@link HUBRPC_UNSIGNED_KEY} (`$hubrpcUnsigned`) holds extrinsic\n * *attachments* (e.g. the presented capability bag) authored by someone\n * other than this signer, so it's excluded too.\n *\n * Domain separation is intrinsic: the per-domain {@link signingDomainValue}\n * is the sole key of the canonicalized wrapper object. A `\"call\"` signature\n * can therefore never verify as a `\"capability\"` (or vice-versa). The domain\n * is *supplied by context* by signer and verifier;\n * the on-wire `$hubrpcSignature` key is a convenience index, never a trust\n * claim.\n *\n * This module is pure (no private keys, no `crypto.verify`): it only defines\n * the canonical bytes. Signing/verifying live in `../identity/signedObject`.\n */\n\nimport { jcsCanonicalizeBytes } from \"./jcs\";\nimport { sha256 } from \"../crypto/sha256\";\nimport { bytesToBase64Url, type KeyId } from \"../crypto/cryptoProvider\";\n\n/** An open signature domain. Each gets a distinct {@link signingDomainValue}. */\nexport type SignDomain = string;\n\n/** Reserved wire-key: the signature map `{ [domain]: SignatureEnvelope }`. */\nexport const HUBRPC_SIGNATURE_KEY = \"$hubrpcSignature\";\n\n/** Reserved wire-key: extrinsic unsigned attachments (e.g. the capability bag). */\nexport const HUBRPC_UNSIGNED_KEY = \"$hubrpcUnsigned\";\n\n/** Reserved wire-key: signed call meta, present only on calls (dodges the JSON-RPC param namespace). */\nexport const HUBRPC_META_KEY = \"$hubrpc\";\n\n/** @deprecated Use {@link HUBRPC_SIGNATURE_KEY}. */\nexport const LINKRPC_SIGNATURE_KEY = HUBRPC_SIGNATURE_KEY;\n/** @deprecated Use {@link HUBRPC_UNSIGNED_KEY}. */\nexport const LINKRPC_UNSIGNED_KEY = HUBRPC_UNSIGNED_KEY;\n/** @deprecated Use {@link HUBRPC_META_KEY}. */\nexport const LINKRPC_META_KEY = HUBRPC_META_KEY;\n\n/**\n * One domain's signature on the wire: which key signed ({@link KeyId}, an\n * **unsigned** routing hint) plus the raw `base64url(sig)`. Lying about\n * `keyId` only makes verification fail (the resolver rejects or the key\n * mismatches), so it carries no integrity claim and is excluded from the\n * signed bytes along with the rest of `$hubrpcSignature`.\n */\nexport interface SignatureEnvelope {\n /** The key the signer used (`\"key:...\"`). Resolved against the principal. */\n readonly keyId: KeyId;\n /** `base64url` of the raw signature over {@link signingInput}. */\n readonly sig: string;\n}\n\n/** Per-domain signature map carried under {@link HUBRPC_SIGNATURE_KEY}. */\nexport type Signatures = { readonly [D in SignDomain]?: SignatureEnvelope };\n\n/** Documentary brand for `base64url(sha256(signingInput(domain, T)))`. */\nexport type Base64Sha256<T = unknown> = string & { readonly __sha256Of?: T };\n\n/**\n * The domain-separation key. It includes the frozen signature-suite version\n * and becomes the sole key of the object passed to JCS.\n */\nexport function signingDomainValue(domain: SignDomain): string {\n return `hubrpc-sig/v1/${domain}`;\n}\n\n/**\n * THE bytes a signature commits to (and a content hash hashes) for `obj` in\n * `domain`: `jcs({ [domainValue(domain)]: obj minus the two reserved keys })`.\n */\nexport function signingInput(domain: SignDomain, obj: object): Uint8Array {\n const signed = { ...(obj as Record<string, unknown>) };\n delete signed[HUBRPC_SIGNATURE_KEY];\n delete signed[HUBRPC_UNSIGNED_KEY];\n return jcsCanonicalizeBytes({ [signingDomainValue(domain)]: signed });\n}\n\n/**\n * Content identity of a signed object: `base64url(sha256(signingInput(...)))`.\n * The single operation behind both a capability's `callBind.payloadHash`\n * (domain `\"call\"`) and a child capability's `parentHash` (domain\n * `\"capability\"`).\n */\nexport function signedHash<T extends object>(domain: SignDomain, obj: T): Base64Sha256<T> {\n return bytesToBase64Url(sha256(signingInput(domain, obj))) as Base64Sha256<T>;\n}\n\n/** Read the signature envelope for `domain` off an object's `$hubrpcSignature` map. */\nexport function readSignature(obj: object, domain: SignDomain): SignatureEnvelope | undefined {\n const sigs = (obj as Record<string, unknown>)[HUBRPC_SIGNATURE_KEY] as Signatures | undefined;\n if (sigs === null || typeof sigs !== \"object\") return undefined;\n const entry = sigs[domain];\n if (entry === null || typeof entry !== \"object\") return undefined;\n const { keyId, sig } = entry as { keyId?: unknown; sig?: unknown };\n if (typeof keyId !== \"string\" || typeof sig !== \"string\") return undefined;\n return { keyId, sig };\n}\n\n/** The {@link KeyId} the signer used for `domain` (the unsigned routing hint), if any. */\nexport function getKeyId(obj: object, domain: SignDomain): KeyId | undefined {\n return readSignature(obj, domain)?.keyId;\n}\n\n/**\n * Return a copy of `obj` with `$hubrpcSignature[domain]` set to `envelope`,\n * preserving any sibling-domain signatures already present.\n */\nexport function withSignature<T extends object>(obj: T, domain: SignDomain, envelope: SignatureEnvelope): T & { $hubrpcSignature: Record<string, SignatureEnvelope> } {\n const prev = (obj as Record<string, unknown>)[HUBRPC_SIGNATURE_KEY] as Signatures | undefined;\n return { ...obj, [HUBRPC_SIGNATURE_KEY]: { ...prev, [domain]: envelope } } as T & { $hubrpcSignature: Record<string, SignatureEnvelope> };\n}\n","import type { JsonValue } from \"./jsonValue\";\nimport type { PrincipalId } from \"../crypto/cryptoProvider\";\nimport type { SignedCapability } from \"./capability\";\nimport type { JsonRpcNotification, JsonRpcRequest } from \"./jsonRpc\";\nimport {\n HUBRPC_META_KEY,\n HUBRPC_SIGNATURE_KEY,\n HUBRPC_UNSIGNED_KEY,\n type Signatures,\n} from \"./signedObject\";\n\nexport {\n HUBRPC_META_KEY,\n HUBRPC_SIGNATURE_KEY,\n HUBRPC_UNSIGNED_KEY,\n type Signatures,\n};\n\n/**\n * Signed call meta. Lives under `params.$hubrpc` so it can't collide with\n * the user's top-level param keys. Present on signed AND unsigned calls\n * (the latter omit {@link CallMeta.principal} and carry no `$hubrpcSignature`).\n *\n * Included verbatim in the bytes a call signature commits to — the\n * signature covers `signingInput(\"call\", { ...userParams, $hubrpc })`.\n */\nexport interface CallMeta {\n /** Fully-qualified wire method. The verifier asserts it equals the JSON-RPC `method`. */\n readonly method: string;\n /** Replay-protection nonce (base64url). The gate dedups on this. */\n readonly nonce: string;\n /** Unix milliseconds. Skew window enforced by the verifier. */\n readonly signedAtMs: number;\n /** Identity wielding the call. Present iff signed; equals the audience of every presented cap. */\n readonly principal?: PrincipalId;\n /** Optional schema hash assertion. Matched against `TargetPattern.interfaceHash`. */\n readonly interfaceHash?: string;\n}\n\n/**\n * Extrinsic, unsigned attachments carried under `params.$hubrpcUnsigned`.\n * Not covered by the call signature (they aren't authored by the signer).\n */\nexport interface LinkRpcUnsigned {\n /** Caller's presented capability bag. Parents are resolved out of this by hash. */\n readonly capabilities?: readonly SignedCapability[];\n}\n\n/** Reserved wire-key meta carried on a linkrpc call's params object. */\nexport interface LinkRpcWireMeta {\n readonly [HUBRPC_META_KEY]?: CallMeta;\n readonly [HUBRPC_SIGNATURE_KEY]?: Signatures;\n readonly [HUBRPC_UNSIGNED_KEY]?: LinkRpcUnsigned;\n}\n\n\n/**\n * Wire shape of `params` on a linkrpc JSON-RPC call.\n *\n * The user's params object (if any) is spread as-is, with the\n * {@link LinkRpcWireMeta} keys attached on top. `TUserParams` carries the\n * user-visible param shape; defaults to an open object. User params MUST be\n * a plain object — enforced at signing/verification via\n * {@link requireObjectParams}.\n */\nexport type LinkRpcWireParams<\n TUserParams extends { [key: string]: JsonValue | undefined } = { [key: string]: JsonValue | undefined },\n> = TUserParams & LinkRpcWireMeta;\n\n/** JSON-RPC request whose `params` carry the linkrpc wire meta. */\nexport type LinkRpcJsonRpcRequest<\n TUserParams extends { [key: string]: JsonValue | undefined } = { [key: string]: JsonValue | undefined },\n> = JsonRpcRequest<LinkRpcWireParams<TUserParams>>;\n\n/** JSON-RPC notification whose `params` carry the linkrpc wire meta. */\nexport type LinkRpcJsonRpcNotification<\n TUserParams extends { [key: string]: JsonValue | undefined } = { [key: string]: JsonValue | undefined },\n> = JsonRpcNotification<LinkRpcWireParams<TUserParams>>;\n\n/** Either of the two linkrpc-bearing JSON-RPC message shapes. */\nexport type LinkRpcJsonRpcMessage<\n TUserParams extends { [key: string]: JsonValue | undefined } = { [key: string]: JsonValue | undefined },\n> = LinkRpcJsonRpcRequest<TUserParams> | LinkRpcJsonRpcNotification<TUserParams>;\n\n/**\n * The linkrpc signing/cap system accepts only plain-object user params (or\n * none). Reject arrays/primitives at the boundary so \"strip `$hubrpc*`, the\n * rest is the signed user params\" stays unambiguous.\n */\nexport function requireObjectParams(\n userParams: JsonValue | undefined,\n): Record<string, JsonValue | undefined> {\n if (userParams === undefined) return {};\n if (userParams === null || typeof userParams !== \"object\" || Array.isArray(userParams)) {\n throw new Error(\"linkrpc: user params must be a plain JSON object or undefined\");\n }\n return userParams as Record<string, JsonValue | undefined>;\n}\n\n/**\n * Return the application-authored portion of a LinkRPC params value.\n *\n * Routing and gate layers must continue forwarding the original wire params so\n * every chained hub can independently verify the envelope. Terminal dispatch\n * may use this derived value for application-schema validation without mutating\n * or replacing the wire message.\n */\nexport function stripLinkRpcWireMeta(wireParams: unknown): JsonValue | undefined {\n if (wireParams === undefined) return undefined;\n if (wireParams === null || typeof wireParams !== \"object\" || Array.isArray(wireParams)) {\n return wireParams as JsonValue;\n }\n const object = wireParams as Record<string, unknown>;\n const reserved = [HUBRPC_META_KEY, HUBRPC_SIGNATURE_KEY, HUBRPC_UNSIGNED_KEY];\n if (!reserved.some((key) => key in object)) return object as JsonValue;\n\n const userParams: Record<string, unknown> = {};\n for (const key of Object.keys(object)) {\n if (reserved.includes(key)) continue;\n userParams[key] = object[key];\n }\n return userParams as JsonValue;\n}\n","import { array, boolean, int, nonnegative, number, object, optional, positive, string, union, unknown } from \"zod/mini\";\nimport type { output as zInfer } from \"zod/v4/core\";\nimport { defineInterface, type StreamApi } from \"../../connection/interfaceDefinition\";\nimport { requestType } from \"../../schema/memberTypes\";\n\nexport const defaultsInterface = defineInterface(\n {\n id: \"hubrpc.defaults\",\n description: \"Reflection: preset default service / interface on this connection.\",\n },\n {\n get: requestType(\n object({}),\n object({\n serviceId: optional(string()),\n interfaceId: optional(string()),\n /** Hash of the preset interface, if known. */\n interfaceHash: optional(string()),\n }),\n ),\n listBindings: requestType(\n object({}),\n object({\n bindings: array(object({\n prefix: string(),\n serviceId: optional(string()),\n interfaceId: string(),\n interfaceHash: string(),\n })),\n }),\n ),\n },\n);\n\n/**\n * A single root-principal requirement. `transitive: true` means the requirement\n * also applies to every service reachable *through* this one — i.e. when this\n * listing is a `hubrpc.directory` reference, everything it lists inherits the\n * requirement (also as transitive).\n */\nconst zRootPrincipalReq = object({\n principal: string(),\n transitive: optional(boolean()),\n});\n\n/** One OR-set. The set is satisfied by holding *any one* of its principals. */\nconst zRootPrincipalSet = array(zRootPrincipalReq);\n\nexport type RootPrincipalReq = zInfer<typeof zRootPrincipalReq>;\nexport type RootPrincipalSet = zInfer<typeof zRootPrincipalSet>;\n\nexport const zServiceIdPattern = union([\n object({ exact: string() }),\n object({ prefix: string() }),\n]);\n\nexport type ServiceIdPattern = zInfer<typeof zServiceIdPattern>;\n\nconst zServiceListing = object({\n serviceId: string(),\n interfaceId: string(),\n /** Hash of the interface as implemented by this service. */\n interfaceHash: string(),\n /** Optional, non-authoritative discovery labels of this implemented interface. */\n tags: optional(array(string())),\n /** Optional non-normative description of the owning service. */\n serviceDescription: optional(string()),\n /**\n * Root principals required to access this service, in CNF: the caller must\n * satisfy **every** set (AND), and a set is satisfied by **any one** of its\n * principals (OR). Omitted/empty => no root-principal requirement.\n */\n rootPrincipalSets: optional(array(zRootPrincipalSet)),\n /**\n * Service-id regions reachable through this referral. Meaningful only for\n * `hubrpc.directory` entries; omission defaults to the referral service-id\n * subtree.\n */\n reachableServiceIds: optional(array(zServiceIdPattern)),\n});\n\nexport const directoryInterface = defineInterface(\n {\n id: \"hubrpc.directory\",\n description:\n \"Reflection: list services exposed by this endpoint. Can also list other directory services that can be explored.\",\n },\n {\n list: requestType(\n object({\n /** Filter: only return services implementing this interface id. */\n interfaceId: optional(string()),\n /** Filter: only return services whose interface id starts with this prefix. */\n interfaceIdPrefix: optional(string()),\n /** Filter: only return entries for this service id. */\n serviceId: optional(string()),\n /** Union filter used to constrain a transitive directory walk. */\n serviceIdScopes: optional(array(zServiceIdPattern)),\n\n /** Paging: opaque continuation token from a previous response. */\n cursor: optional(string()),\n /** Paging: max items in this page. Server MAY return fewer. */\n limit: optional(number().check(int(), positive())),\n\n /** Soft cap on time the server spends gathering this page, in ms. */\n timeoutMs: optional(number().check(int(), nonnegative())),\n }),\n object({\n items: array(zServiceListing),\n /** Omitted => no more pages. */\n nextCursor: optional(string()),\n /** True if `timeoutMs` cut the page short before exhausting results. */\n truncated: optional(boolean()),\n }),\n ),\n /**\n * Coarse change tap on the directory.\n *\n * `watch` is a long-lived streaming request that emits an **empty tick**\n * whenever the (optionally filtered) directory *might* have changed. The\n * tick carries no delta and no payload — its only meaning is \"re-`list`\n * now\". The consumer reconciles against its own last snapshot.\n *\n * This keeps the server stateless: it never computes or replays\n * per-item deltas, never does an initial-sync replay. Over-emission is\n * allowed (the consumer re-lists and finds nothing new); under-emission\n * is not. Ticks are coalesced. The `interfaceId` / `serviceId` filters\n * mirror `list` and are a relevance hint, not a guarantee.\n *\n * The request resolves when the caller cancels (or the connection\n * drops); the runtime auto-detaches the stream when it settles.\n */\n watch: requestType(\n object({\n /** Relevance hint: changes touching this interface id. */\n interfaceId: optional(string()),\n /** Relevance hint: changes touching an interface id with this prefix. */\n interfaceIdPrefix: optional(string()),\n /** Relevance hint: changes touching this service id. */\n serviceId: optional(string()),\n /** Relevance hint: changes within any of these service-id regions. */\n serviceIdScopes: optional(array(zServiceIdPattern)),\n }),\n object({}),\n ).withStream({\n /** Empty tick: \"the directory may have changed; re-list.\" */\n server: object({}),\n }),\n },\n);\n\n/**\n * A `directoryInterface.watch` handler for a **static** directory. It opens the\n * stream, never ticks, and resolves when the caller cancels. Dynamic providers,\n * including {@link LinkRpcConnection.enableReflection}, use a change-emitting\n * implementation instead.\n */\nexport function directoryWatchNever(\n _params: {\n interfaceId?: string;\n interfaceIdPrefix?: string;\n serviceId?: string;\n serviceIdScopes?: ServiceIdPattern[];\n },\n _ctx: unknown,\n stream: StreamApi<unknown, Record<string, never>>,\n): Promise<Record<string, never>> {\n return new Promise((resolve) => {\n if (stream.signal.aborted) {\n resolve({});\n return;\n }\n stream.signal.addEventListener(\"abort\", () => resolve({}), { once: true });\n });\n}\n\nexport const schemasInterface = defineInterface(\n {\n id: \"hubrpc.schemas\",\n description:\n \"Reflection: fetch interface schemas by id (+ optional hash). Must serve the interfaces advertised in this endpoint's directory.\",\n },\n {\n get: requestType(\n object({\n interfaceId: string(),\n /** Omit => server picks the version it exposes. */\n hash: optional(string()),\n }),\n object({\n /** A full `SvcInterfaceSchema`. */\n schema: unknown(),\n }),\n ),\n },\n);\n","export const DEFAULT_RPC_TIMEOUT_MS = 5_000;\n\nexport interface CancellableRequest<T> extends Promise<T> {\n cancel(reason?: string): void | Promise<void>;\n dispose?(reason?: string): void;\n}\n\nexport async function withRpcTimeout<T>(\n request: CancellableRequest<T>,\n target: string,\n timeoutMs = DEFAULT_RPC_TIMEOUT_MS,\n): Promise<T> {\n if (timeoutMs <= 0) return request;\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n const reason = `${target} timed out after ${timeoutMs}ms`;\n try {\n Promise.resolve(request.cancel(reason)).catch(() => {\n // The timeout remains authoritative even if remote cancellation fails.\n });\n } finally {\n try {\n request.dispose?.(reason);\n } catch {\n // Local disposal must not replace the timeout result.\n }\n }\n reject(new Error(reason));\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([request, timeout]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n","import type { IRequestSender, RawStreamingCall } from '../../connection/channel';\nimport { DEFAULT_RPC_TIMEOUT_MS, withRpcTimeout } from '../../connection/requestTimeout';\nimport type { SigningCallCtx } from '../../identity/signingSender';\nimport type { JsonValue } from '../../protocol/jsonValue';\nimport { ErrorCode } from '../../protocol/jsonRpc';\nimport type { LinkRpcInterfaceSchema, MethodSchema } from '../../schema/linkRpcInterfaceSchema';\nimport {\n directoryInterface,\n type RootPrincipalSet,\n type ServiceIdPattern,\n} from './reflection.interfaces';\n\n/**\n * Portable reflection walk over the `hubrpc.directory` referral tree.\n *\n * A directory may explicitly list other `hubrpc.directory` services as\n * referrals. Flattening that graph into an interface inventory is the\n * consumer's job. Routing state is deliberately not part of this contract.\n */\n\n/**\n * The sender reflection helpers speak over: the signing decorator that wraps\n * the live channel. Decoupled from the concrete `JsonRpcChannel` so reconnect\n * can swap the underlying channel transparently.\n */\nexport type ReflectionChannel = IRequestSender<SigningCallCtx>;\n\nexport interface ServiceListing {\n readonly serviceId: string;\n readonly interfaceId: string;\n readonly hash: string;\n /** Non-authoritative discovery labels of the advertised interface. */\n readonly tags?: readonly string[];\n readonly path?: string;\n /** Optional non-normative description of the owning service. */\n readonly serviceDescription?: string;\n /**\n * Root node ids required to access the owning service, in CNF. Surfaced by\n * the directory; {@link walkHubDetailed} additionally folds transitive\n * requirements from ancestor directories onto descendants.\n */\n readonly rootPrincipalSets?: readonly RootPrincipalSet[];\n /** Scope carried by a directory referral; omitted means its service-id subtree. */\n readonly reachableServiceIds?: readonly ServiceIdPattern[];\n}\n\n/**\n * A {@link ServiceListing} enriched with the service id of the directory that\n * reported it. This is provenance only: every listing is asserted reachable by\n * sending to the endpoint that answered the directory.\n */\nexport interface DiscoveredListing extends ServiceListing {\n readonly discoveredFrom: string;\n}\n\nexport interface ListOptions {\n readonly interfaceId?: string;\n readonly interfaceIdPrefix?: string;\n readonly serviceId?: string;\n readonly serviceIdScopes?: readonly ServiceIdPattern[];\n readonly limit?: number;\n readonly timeoutMs?: number;\n /**\n * When set, send the reflection call to that service via form-3\n * (`<target>::hubrpc.directory::list`) instead of the implicit root\n * directory. Used when talking to a hub: the root directory is the hub\n * itself, but per-service reflection lives on each participant.\n */\n readonly target?: string;\n}\n\nexport async function fetchDirectory(\n channel: ReflectionChannel,\n opts: ListOptions = {},\n): Promise<ServiceListing[]> {\n const method = opts.target\n ? `${opts.target}::hubrpc.directory::list`\n : 'hubrpc.directory::list';\n const all: ServiceListing[] = [];\n let cursor: string | undefined;\n while (true) {\n const params: Record<string, JsonValue | undefined> = {};\n if (opts.interfaceId !== undefined) params.interfaceId = opts.interfaceId;\n if (opts.interfaceIdPrefix !== undefined) params.interfaceIdPrefix = opts.interfaceIdPrefix;\n if (opts.serviceId !== undefined) params.serviceId = opts.serviceId;\n if (opts.serviceIdScopes !== undefined) params.serviceIdScopes = [...opts.serviceIdScopes];\n if (opts.limit !== undefined) params.limit = opts.limit;\n if (opts.timeoutMs !== undefined) params.timeoutMs = opts.timeoutMs;\n if (cursor !== undefined) params.cursor = cursor;\n\n const call = channel.sendRequestWithStream(method, params, {\n interfaceHash: directoryInterface.schemaHash,\n });\n const target = opts.target ?? '<root>';\n const raw = await withRpcTimeout(\n Object.assign(call.result, {\n cancel: (reason?: string) => call.cancel(reason),\n dispose: (reason?: string) => call.dispose?.(reason),\n }),\n `hub directory service '${target}'`,\n opts.timeoutMs ?? DEFAULT_RPC_TIMEOUT_MS,\n );\n const page = raw as unknown as {\n items: {\n serviceId: string;\n interfaceId: string;\n interfaceHash: string;\n tags?: readonly string[];\n path?: string;\n serviceDescription?: string;\n rootPrincipalSets?: readonly RootPrincipalSet[];\n reachableServiceIds?: readonly ServiceIdPattern[];\n }[];\n nextCursor?: string;\n };\n for (const it of page.items) {\n if (it.tags !== undefined\n && (!Array.isArray(it.tags) || !it.tags.every(tag => typeof tag === 'string'))) {\n throw new Error(`Invalid directory tags for \"${it.serviceId}::${it.interfaceId}\"`);\n }\n all.push({\n serviceId: it.serviceId,\n interfaceId: it.interfaceId,\n hash: it.interfaceHash,\n ...(it.tags === undefined ? {} : { tags: [...it.tags] }),\n ...(it.path !== undefined ? { path: it.path } : {}),\n ...(it.serviceDescription !== undefined\n ? { serviceDescription: it.serviceDescription }\n : {}),\n ...(Array.isArray(it.rootPrincipalSets)\n ? { rootPrincipalSets: it.rootPrincipalSets }\n : {}),\n ...(Array.isArray(it.reachableServiceIds)\n ? { reachableServiceIds: it.reachableServiceIds }\n : {}),\n });\n }\n if (!page.nextCursor) break;\n cursor = page.nextCursor;\n }\n return all;\n}\n\nexport async function fetchSchema(\n channel: ReflectionChannel,\n interfaceId: string,\n hash: string | undefined,\n /**\n * Optional routing target. When set, the schema request is addressed to\n * `<target>::hubrpc.schemas::get` (form-3) so it reaches the service that\n * actually hosts this interface — needed when talking to a hub and the\n * interface lives behind a participant.\n */\n target?: string,\n /** Deadline for the schema request; cancels remote work and releases local tracking. */\n timeoutMs = DEFAULT_RPC_TIMEOUT_MS,\n): Promise<LinkRpcInterfaceSchema> {\n const method = target\n ? `${target}::hubrpc.schemas::get`\n : 'hubrpc.schemas::get';\n const params: Record<string, JsonValue | undefined> = { interfaceId };\n if (hash !== undefined) params.hash = hash;\n const call = channel.sendRequestWithStream(method, params);\n const raw = await withRpcTimeout(\n Object.assign(call.result, {\n cancel: (reason?: string) => call.cancel(reason),\n dispose: (reason?: string) => call.dispose?.(reason),\n }),\n `hub schema '${interfaceId}' at '${target ?? '<root>'}'`,\n timeoutMs,\n );\n const wrap = raw as unknown as { schema: LinkRpcInterfaceSchema; };\n return wrap.schema;\n}\n\nexport function findMethodInSchema(\n schema: LinkRpcInterfaceSchema,\n methodName: string,\n): MethodSchema | undefined {\n return schema.methods[methodName];\n}\n\n/** Default recursion depth when walking the bus. */\nexport const DEFAULT_WALK_DEPTH = 5;\nconst DIRECTORY_INTERFACE_ID = 'hubrpc.directory';\nconst ROOT_NODE_KEY = '\\u0000root';\n\n/** Segment-aware service-id pattern matching (`foo` includes `foo/bar`, not `foobar`). */\nexport function serviceIdMatchesPattern(serviceId: string, pattern: ServiceIdPattern): boolean {\n if ('exact' in pattern) return serviceId === pattern.exact;\n return pattern.prefix === ''\n || serviceId === pattern.prefix\n || serviceId.startsWith(`${pattern.prefix}/`);\n}\n\n/** Whether a service id is included by a union of patterns. `undefined` means unfiltered. */\nexport function serviceIdMatchesScopes(\n serviceId: string,\n scopes: readonly ServiceIdPattern[] | undefined,\n): boolean {\n return scopes === undefined || scopes.some((pattern) => serviceIdMatchesPattern(serviceId, pattern));\n}\n\n/** Canonicalize a pattern union by removing duplicates and contained patterns. */\nexport function normalizeServiceIdScopes(\n scopes: readonly ServiceIdPattern[],\n): ServiceIdPattern[] {\n const unique = new Map<string, ServiceIdPattern>();\n for (const pattern of scopes) {\n unique.set(patternKey(pattern), pattern);\n }\n const patterns = [...unique.values()];\n return patterns\n .filter((candidate, index) => !patterns.some((other, otherIndex) =>\n index !== otherIndex && patternContains(other, candidate)))\n .sort((a, b) => patternKey(a).localeCompare(patternKey(b)));\n}\n\n/** Pairwise intersection of two pattern unions. */\nexport function intersectServiceIdScopes(\n left: readonly ServiceIdPattern[],\n right: readonly ServiceIdPattern[],\n): ServiceIdPattern[] {\n const intersections: ServiceIdPattern[] = [];\n for (const a of left) {\n for (const b of right) {\n const intersection = intersectPattern(a, b);\n if (intersection !== undefined) intersections.push(intersection);\n }\n }\n return normalizeServiceIdScopes(intersections);\n}\n\nfunction intersectPattern(\n left: ServiceIdPattern,\n right: ServiceIdPattern,\n): ServiceIdPattern | undefined {\n if ('exact' in left) {\n if ('exact' in right) return left.exact === right.exact ? left : undefined;\n return serviceIdMatchesPattern(left.exact, right) ? left : undefined;\n }\n if ('exact' in right) {\n return serviceIdMatchesPattern(right.exact, left) ? right : undefined;\n }\n if (serviceIdMatchesPattern(left.prefix, right)) return left;\n if (serviceIdMatchesPattern(right.prefix, left)) return right;\n return undefined;\n}\n\nfunction patternContains(container: ServiceIdPattern, candidate: ServiceIdPattern): boolean {\n if ('exact' in container) {\n return 'exact' in candidate && container.exact === candidate.exact;\n }\n if ('exact' in candidate) return serviceIdMatchesPattern(candidate.exact, container);\n return serviceIdMatchesPattern(candidate.prefix, container);\n}\n\nfunction patternKey(pattern: ServiceIdPattern): string {\n return 'exact' in pattern ? `e:${pattern.exact}` : `p:${pattern.prefix}`;\n}\n\nfunction scopesKey(scopes: readonly ServiceIdPattern[]): string {\n return normalizeServiceIdScopes(scopes).map(patternKey).join('\\u0000');\n}\n\n/**\n * A sub-directory the walk surfaced but could not enumerate — typically because\n * it is capability-gated (e.g. the `hub` directory, reachable only once the\n * connection holds a capability for it). The services it would have listed are\n * therefore absent from the walk; callers can surface `reason` to explain the\n * gap rather than silently dropping the branch.\n */\nexport interface InaccessibleDirectory {\n /** The directory target (serviceId) that could not be enumerated. */\n readonly serviceId: string;\n /** The error message from the denied directory lookup. */\n readonly reason: string;\n}\n\nexport interface WalkHubResult {\n /** Every interface reachable from the directories the walk could read. */\n readonly listings: DiscoveredListing[];\n /**\n * Sub-directories that were referenced but could not be enumerated (e.g.\n * capability-gated). Their services are not present in `listings`.\n */\n readonly inaccessible: InaccessibleDirectory[];\n}\n\n/**\n * Recursive graph walk: list a directory, intersect the accumulated service-id\n * scope with every explicit `hubrpc.directory` referral, and recurse. Bounded\n * by `maxDepth`.\n *\n * Every listing is tagged with `discoveredFrom` — the serviceId of the\n * directory that produced it. When the same `(serviceId, interfaceId, hash)`\n * shows up via several directories (e.g. once forwarded by the hub, once\n * directly from the participant), we keep the one whose `discoveredFrom`\n * matches the item's `serviceId`, since that's the directory that\n * authoritatively knows about it.\n *\n * Transitive root-node-id requirements flow down the tree: when the walk\n * recurses into a directory whose own `rootPrincipalSets` include `transitive`\n * reqs, every interface discovered at or below that directory inherits them (as\n * singleton AND-sets, kept transitive so they keep flowing further down). This\n * replaces the hub-side `applyTransitiveReqs` fold that the v1 aggregating\n * directory performed.\n *\n * A sub-directory the walk cannot read is recorded in\n * {@link WalkHubResult.inaccessible} rather than silently dropped. A failure to\n * read the *root* directory is left silent — there is no sub-tree to explain —\n * and simply yields empty results.\n *\n * When {@link WalkHubOptions.unlockGatedDirectory} is supplied, each gated\n * sub-directory is offered to the hook; if it returns `true` (a capability was\n * granted), that directory is re-queued and the walk continues into it — a\n * fixpoint that keeps unlocking newly-revealed gated branches until nothing\n * more can be opened (still bounded by `maxDepth`).\n */\nexport interface WalkHubOptions {\n readonly maxDepth?: number;\n /** Hard deadline for each directory page request. Defaults to 5 seconds. */\n readonly timeoutMs?: number;\n /** Return only listings for this exact interface id after traversing directories. */\n readonly interfaceId?: string;\n /** Return only listings whose interface id starts with this prefix after traversal. */\n readonly interfaceIdPrefix?: string;\n /** Return only listings for this exact service id after traversal. */\n readonly serviceId?: string;\n /** Initial service-id scope. Defaults to the universal `{ prefix: \"\" }`. */\n readonly serviceIdScopes?: readonly ServiceIdPattern[];\n /**\n * The directory the walk starts from. Defaults to the implicit root\n * directory (form-2 `hubrpc.directory::list`). Pass a serviceId to start at\n * `<rootTarget>::hubrpc.directory::list` — e.g. the hub's own global\n * directory (`'hub'`) when walking from the hub's in-process connection.\n */\n readonly rootTarget?: string;\n /**\n * Invoked only after a permissionRequired error, never for timeouts or\n * transport errors. Return `true`\n * if a capability for its `hubrpc.directory::list` was granted and the\n * directory should be re-listed; `false` (or omitted hook) leaves it in\n * {@link WalkHubResult.inaccessible}. Called at most once per `serviceId`.\n */\n unlockGatedDirectory?: (serviceId: string) => Promise<boolean>;\n /** Optional diagnostic sink for inaccessible lists and ended watches. */\n readonly log?: (message: string) => void;\n}\n\nexport async function walkHubDetailed(\n channel: ReflectionChannel,\n opts: WalkHubOptions = {},\n): Promise<WalkHubResult> {\n return new HubDirectoryExplorer(channel, opts).explore();\n}\n\n/**\n * Backward-compatible wrapper over {@link walkHubDetailed} that returns only the\n * reachable listings, dropping the inaccessible-directory report.\n */\nexport async function walkHub(\n channel: ReflectionChannel,\n opts: WalkHubOptions = {},\n): Promise<DiscoveredListing[]> {\n return (await walkHubDetailed(channel, opts)).listings;\n}\n\nexport interface HubDirectoryChange {\n /** Directory that emitted the tick. `undefined` denotes the connection root. */\n readonly target: string | undefined;\n readonly result: WalkHubResult;\n}\n\nexport type HubDirectoryGraphTarget =\n | { readonly kind: 'root'; readonly serviceId?: string; }\n | { readonly kind: 'addressed'; readonly serviceId: string; };\n\nexport type HubDirectoryNodeState =\n | 'unexplored'\n | 'loading'\n | 'loaded'\n | 'inaccessible';\n\nexport interface HubDirectoryParentReport {\n readonly target: HubDirectoryGraphTarget;\n readonly scopes: readonly ServiceIdPattern[];\n /** Resulting depth for this incoming parent path. */\n readonly depth: number;\n}\n\n/** Stable public report for one native directory response. */\nexport interface HubDirectoryNodeReport {\n readonly target: HubDirectoryGraphTarget;\n readonly state: HubDirectoryNodeState;\n readonly effectiveScopes: readonly ServiceIdPattern[];\n readonly depth: number;\n readonly parents: readonly HubDirectoryParentReport[];\n /** Per-directory listings, normalized to `ServiceListing`, before inherited metadata is folded. */\n readonly nativeListings: readonly ServiceListing[];\n readonly inaccessibleReason?: string;\n readonly watching: boolean;\n}\n\n/**\n * Complete point-in-time graph document. `root` exists from construction in\n * the `unexplored` state, so consumers can render before exploration starts.\n */\nexport interface HubDirectoryGraphSnapshot {\n readonly revision: number;\n readonly complete: boolean;\n readonly root: HubDirectoryNodeReport;\n readonly directories: readonly HubDirectoryNodeReport[];\n readonly result: WalkHubResult;\n}\n\nexport type HubDirectoryGraphEvent =\n | {\n readonly type: 'snapshot';\n readonly reason: 'subscribed' | 'reconciliation-started' | 'reset';\n readonly snapshot: HubDirectoryGraphSnapshot;\n }\n | {\n readonly type: 'node-added';\n readonly reason: 'referral';\n readonly node: HubDirectoryNodeReport;\n readonly snapshot: HubDirectoryGraphSnapshot;\n }\n | {\n readonly type: 'node-updated';\n readonly reason:\n | 'loading'\n | 'loaded'\n | 'inaccessible'\n | 'referral'\n | 'watch-started'\n | 'watch-stopped'\n | 'watch-ended'\n | 'reset';\n readonly previous: HubDirectoryNodeReport;\n readonly node: HubDirectoryNodeReport;\n readonly snapshot: HubDirectoryGraphSnapshot;\n }\n | {\n readonly type: 'node-removed';\n readonly reason: 'unreachable' | 'reset';\n readonly previous: HubDirectoryNodeReport;\n readonly snapshot: HubDirectoryGraphSnapshot;\n }\n | {\n readonly type: 'settled';\n readonly snapshot: HubDirectoryGraphSnapshot;\n };\n\n/**\n * Reusable directory graph explorer and watcher.\n *\n * The class keeps one native snapshot per directory target. A watch tick\n * re-lists only its source target; outgoing referral changes then propagate\n * through affected descendants. Unchanged siblings retain both their snapshot\n * and watch. Multi-parent targets are queried with the normalized union of all\n * incoming path scopes.\n *\n * While watching, every node's watch is `active` or in `backoff` after a\n * failure (see {@link DirectoryWatch}). A failed or ended watch is retried\n * with exponential backoff, and each retry re-lists the directory after the\n * new watch is opened. A directory whose watch keeps failing — for example a\n * provider that does not implement `watch`, or one the caller may list but not\n * watch — is therefore polled at the backoff interval instead of hammered.\n */\nexport class HubDirectoryExplorer {\n private readonly _maxDepth: number;\n private readonly _initialScopes: ServiceIdPattern[];\n private readonly _nodes = new Map<string, DirectoryNode>();\n private readonly _unlockAttempted = new Set<string>();\n private readonly _listeners = new Set<(change: HubDirectoryChange) => void>();\n private readonly _graphListeners = new Set<(event: HubDirectoryGraphEvent) => void>();\n private readonly _pendingTicks = new Set<string>();\n private _initialized = false;\n private _disposed = false;\n private _watching = false;\n private _complete = false;\n private _revision = 0;\n private _work: Promise<void> = Promise.resolve();\n private _explorePromise: Promise<WalkHubResult> | undefined;\n\n public constructor(\n private readonly _channel: ReflectionChannel,\n private readonly _options: WalkHubOptions = {},\n ) {\n this._maxDepth = _options.maxDepth ?? DEFAULT_WALK_DEPTH;\n this._initialScopes = normalizeServiceIdScopes(\n _options.serviceIdScopes ?? [{ prefix: '' }],\n );\n this._nodes.set(ROOT_NODE_KEY, this._createRootNode());\n }\n\n /** Perform a fresh bounded exploration without starting watches. */\n public explore(): Promise<WalkHubResult> {\n this._throwIfDisposed();\n if (this._explorePromise !== undefined) return this._explorePromise;\n const promise = this._explore();\n this._explorePromise = promise;\n const clear = () => {\n if (this._explorePromise === promise) this._explorePromise = undefined;\n };\n void promise.then(clear, clear);\n return promise;\n }\n\n private async _explore(): Promise<WalkHubResult> {\n if (this._initialized || this._nodes.get(ROOT_NODE_KEY)?.state !== 'unexplored') {\n this._resetForExplore();\n }\n const root = this._nodes.get(ROOT_NODE_KEY)!;\n await this._loadNode(root);\n if (this._disposed) return { listings: [], inaccessible: [] };\n await this._reconcileScopesFromRoot();\n await this._pruneUnreachable();\n this._initialized = true;\n if (this._watching) await this._synchronizeWatches();\n this._settle();\n return this.result;\n }\n\n /** Current deduplicated graph snapshot. */\n public get result(): WalkHubResult {\n const best = new Map<string, DiscoveredListing>();\n for (const node of this._nodes.values()) {\n if (!node.loaded) continue;\n for (const item of node.listings) {\n const effective = mergePrincipalSets(item.rootPrincipalSets, node.inherited);\n const tagged: DiscoveredListing = {\n ...item,\n ...(effective.length > 0 ? { rootPrincipalSets: effective } : {}),\n discoveredFrom: node.target ?? '',\n };\n const key = listingKey(item);\n const existing = best.get(key);\n if (!existing || _isAuthoritative(tagged, existing)) best.set(key, tagged);\n }\n }\n const listings = [...best.values()]\n .filter((item) => this._options.interfaceId === undefined\n || item.interfaceId === this._options.interfaceId)\n .filter((item) => this._options.interfaceIdPrefix === undefined\n || item.interfaceId.startsWith(this._options.interfaceIdPrefix))\n .filter((item) => this._options.serviceId === undefined\n || item.serviceId === this._options.serviceId);\n const inaccessible = [...this._nodes.values()]\n .filter((node) => node.inaccessibleReason !== undefined)\n .map((node) => ({\n serviceId: node.target ?? '',\n reason: node.inaccessibleReason!,\n }));\n return { listings, inaccessible };\n }\n\n /** Current complete-or-progressive directory graph report. */\n public get graphSnapshot(): HubDirectoryGraphSnapshot {\n const root = this._nodes.get(ROOT_NODE_KEY) ?? this._createRootNode();\n const directories = [...this._nodes.values()]\n .filter((node) => node.key !== ROOT_NODE_KEY)\n .sort((a, b) => (a.target ?? '').localeCompare(b.target ?? ''))\n .map((node) => this._nodeReport(node));\n return {\n revision: this._revision,\n complete: this._complete,\n root: this._nodeReport(root),\n directories,\n result: this.result,\n };\n }\n\n /**\n * Subscribe to progressive graph reports. The listener is registered before\n * receiving a synchronous current snapshot, avoiding the subscribe/explore\n * race for both idle and already-running explorers.\n */\n public subscribe(listener: (event: HubDirectoryGraphEvent) => void): () => void {\n this._throwIfDisposed();\n this._graphListeners.add(listener);\n this._deliverGraphEvent(listener, {\n type: 'snapshot',\n reason: 'subscribed',\n snapshot: this.graphSnapshot,\n });\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n this._graphListeners.delete(listener);\n };\n }\n\n /**\n * Explore once, then watch every reachable directory. Resolves after the\n * initial graph and watches are established.\n */\n public async watch(\n listener: (change: HubDirectoryChange) => void,\n ): Promise<() => void> {\n this._throwIfDisposed();\n this._listeners.add(listener);\n this._watching = true;\n if (!this._initialized) {\n await this.explore();\n } else {\n this._startReconciliation();\n await this._synchronizeWatches();\n this._settle();\n }\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n this._listeners.delete(listener);\n if (this._listeners.size === 0) {\n this._watching = false;\n this._stopAllWatches();\n }\n };\n }\n\n /** Wait until all currently queued watch reconciliation has settled. */\n public async whenIdle(): Promise<void> {\n await this._work;\n }\n\n public dispose(): void {\n if (this._disposed) return;\n this._disposed = true;\n this._listeners.clear();\n this._pendingTicks.clear();\n this._stopAllWatches(false);\n this._graphListeners.clear();\n this._clearNodes();\n }\n\n private async _loadNode(node: DirectoryNode, reconcileOutgoing = true): Promise<void> {\n if (node.loading) {\n node.reloadRequested = true;\n return;\n }\n node.loading = true;\n this._updateNode(node, 'loading', () => {\n node.state = 'loading';\n });\n try {\n do {\n node.reloadRequested = false;\n const scopesAtRequest = node.scopes;\n let listings: ServiceListing[];\n try {\n listings = await fetchDirectory(this._channel, {\n target: node.target,\n serviceIdScopes: scopesAtRequest,\n timeoutMs: this._options.timeoutMs ?? DEFAULT_RPC_TIMEOUT_MS,\n });\n if (this._disposed) break;\n } catch (error) {\n if (this._disposed) break;\n if (await this._tryUnlock(node, error)) {\n node.reloadRequested = true;\n continue;\n }\n const previous = this._nodeReport(node);\n node.inaccessibleReason = errorMessage(error);\n this._options.log?.(\n `hub directory list(${node.target ?? '<root>'}) failed: ${node.inaccessibleReason}`,\n );\n // A watcher retains the last good branch while it is\n // temporarily inaccessible. A never-loaded node contributes\n // no entries but remains in the inaccessible report.\n if (node.loaded) {\n node.listings = node.listings.filter((item) =>\n serviceIdMatchesScopes(item.serviceId, node.scopes));\n }\n node.state = 'inaccessible';\n this._emitNodeUpdated(node, previous, 'inaccessible');\n if (node.loaded && reconcileOutgoing) await this._reconcileOutgoing(node);\n break;\n }\n if (scopesKey(scopesAtRequest) !== scopesKey(node.scopes)) {\n node.reloadRequested = true;\n continue;\n }\n const previous = this._nodeReport(node);\n node.inaccessibleReason = undefined;\n node.loaded = true;\n node.listings = listings.filter((item) =>\n serviceIdMatchesScopes(item.serviceId, node.scopes));\n node.state = 'loaded';\n this._emitNodeUpdated(node, previous, 'loaded');\n if (reconcileOutgoing) await this._reconcileOutgoing(node);\n } while (node.reloadRequested && !this._disposed);\n } finally {\n node.loading = false;\n }\n }\n\n private async _tryUnlock(node: DirectoryNode, error: unknown): Promise<boolean> {\n if (\n typeof error !== 'object' || error === null || !('code' in error)\n || error.code !== ErrorCode.permissionRequired\n || node.target === undefined\n || this._options.unlockGatedDirectory === undefined\n || this._unlockAttempted.has(node.target)\n ) {\n return false;\n }\n this._unlockAttempted.add(node.target);\n try {\n return await this._options.unlockGatedDirectory(node.target);\n } catch (approvalError) {\n this._options.log?.(\n `hub directory access request(${node.target}) failed: ${errorMessage(approvalError)}`,\n );\n return false;\n }\n }\n\n private async _reconcileOutgoing(node: DirectoryNode): Promise<void> {\n const next = this._outgoingFor(node.scopes, node.inherited, node.depth, node.listings);\n\n const affected = new Set<string>([...node.outgoing.keys(), ...next.keys()]);\n node.outgoing = next;\n for (const childKey of affected) {\n if (this._disposed) return;\n const contribution = next.get(childKey);\n let child = this._nodes.get(childKey);\n let previous: HubDirectoryNodeReport | undefined;\n if (contribution === undefined) {\n if (child === undefined) continue;\n previous = this._nodeReport(child);\n child.parents.delete(node.key);\n } else {\n if (child === undefined) {\n child = this._createNode(childKey);\n child.parents.set(node.key, contribution);\n this._deriveNodeFromParents(child);\n this._nodes.set(childKey, child);\n this._emitNodeAdded(child);\n await this._loadNode(child);\n continue;\n }\n previous = this._nodeReport(child);\n child.parents.set(node.key, contribution);\n }\n await this._updateNodeFromParents(child, previous);\n }\n }\n\n private _outgoingFor(\n scopes: readonly ServiceIdPattern[],\n inherited: readonly RootPrincipalSet[],\n depth: number,\n listings: readonly ServiceListing[],\n ): Map<string, ParentContribution> {\n const outgoing = new Map<string, ParentContribution>();\n if (depth >= this._maxDepth) return outgoing;\n for (const item of listings) {\n if (\n item.interfaceId !== DIRECTORY_INTERFACE_ID\n || !serviceIdMatchesScopes(item.serviceId, scopes)\n ) {\n continue;\n }\n const referralScopes = item.reachableServiceIds\n ?? [{ prefix: item.serviceId }];\n const childScopes = intersectServiceIdScopes(scopes, referralScopes);\n if (childScopes.length === 0) continue;\n const childKey = this._nodeKeyForTarget(item.serviceId);\n if (childKey === ROOT_NODE_KEY) continue;\n const contribution: ParentContribution = {\n scopes: childScopes,\n inherited: mergePrincipalSets(\n inherited,\n transitiveReqsOf(item.rootPrincipalSets),\n ),\n depth: depth + 1,\n };\n const previous = outgoing.get(childKey);\n outgoing.set(childKey, previous === undefined\n ? contribution\n : mergeContributions(previous, contribution));\n }\n return outgoing;\n }\n\n private _createRootNode(): DirectoryNode {\n return {\n key: ROOT_NODE_KEY,\n target: this._options.rootTarget,\n parents: new Map(),\n scopes: [...this._initialScopes],\n inherited: [],\n depth: 0,\n listings: [],\n outgoing: new Map(),\n loaded: false,\n loading: false,\n reloadRequested: false,\n state: 'unexplored',\n watch: { kind: 'idle' },\n watchFailures: 0,\n };\n }\n\n private _createNode(key: string): DirectoryNode {\n return {\n key,\n target: key.slice(2),\n parents: new Map(),\n scopes: [],\n inherited: [],\n depth: Number.POSITIVE_INFINITY,\n listings: [],\n outgoing: new Map(),\n loaded: false,\n loading: false,\n reloadRequested: false,\n state: 'unexplored',\n watch: { kind: 'idle' },\n watchFailures: 0,\n };\n }\n\n private async _updateNodeFromParents(\n node: DirectoryNode,\n previous = this._nodeReport(node),\n ): Promise<void> {\n if (node.key === ROOT_NODE_KEY || node.parents.size === 0) return;\n const { scopes, inherited, depth } = this._derivedNodeState(node);\n const changed = scopesKey(scopes) !== scopesKey(node.scopes)\n || principalSetsKey(inherited) !== principalSetsKey(node.inherited)\n || depth !== node.depth;\n if (!changed) return;\n node.scopes = scopes;\n node.inherited = inherited;\n node.depth = depth;\n this._emitNodeUpdated(node, previous, 'referral');\n await this._loadNode(node);\n }\n\n private _deriveNodeFromParents(node: DirectoryNode): void {\n const derived = this._derivedNodeState(node);\n node.scopes = derived.scopes;\n node.inherited = derived.inherited;\n node.depth = derived.depth;\n }\n\n private _derivedNodeState(node: DirectoryNode): {\n scopes: ServiceIdPattern[];\n inherited: RootPrincipalSet[];\n depth: number;\n } {\n const contributions = [...node.parents.values()];\n return {\n scopes: normalizeServiceIdScopes(contributions.flatMap((value) => value.scopes)),\n inherited: mergePrincipalSets(\n ...contributions.map((value) => value.inherited),\n ),\n depth: Math.min(...contributions.map((value) => value.depth)),\n };\n }\n\n /**\n * Rebuild incoming contributions from the root seed. Starting with no\n * non-root contributions computes the least fixed point, so a disconnected\n * or narrowed cycle cannot keep scopes contributed by its previous state.\n */\n private async _reconcileScopesFromRoot(): Promise<void> {\n const maxRounds = Math.max(\n 16,\n (this._nodes.size + (Number.isFinite(this._maxDepth) ? this._maxDepth : 256)) * 4,\n );\n for (let round = 0; round < maxRounds; round++) {\n const computed = this._computeScopeFixedPoint();\n let relisted = false;\n const ordered = [...computed.states.entries()]\n .sort(([, left], [, right]) => left.depth - right.depth);\n\n for (const [key, state] of ordered) {\n if (key === ROOT_NODE_KEY) {\n const root = this._nodes.get(ROOT_NODE_KEY)!;\n root.outgoing = computed.outgoing.get(key) ?? new Map();\n continue;\n }\n let node = this._nodes.get(key);\n if (node === undefined) {\n node = this._createNode(key);\n node.parents = computed.parents.get(key) ?? new Map();\n node.scopes = state.scopes;\n node.inherited = state.inherited;\n node.depth = state.depth;\n node.outgoing = computed.outgoing.get(key) ?? new Map();\n this._nodes.set(key, node);\n this._emitNodeAdded(node);\n await this._loadNode(node, false);\n relisted = true;\n continue;\n }\n\n const parents = computed.parents.get(key) ?? new Map();\n const scopesChanged = scopesKey(node.scopes) !== scopesKey(state.scopes);\n const inheritedChanged =\n principalSetsKey(node.inherited) !== principalSetsKey(state.inherited);\n const depthChanged = node.depth !== state.depth;\n const parentsChanged =\n parentContributionsKey(node.parents) !== parentContributionsKey(parents);\n const previous = scopesChanged || inheritedChanged || depthChanged || parentsChanged\n ? this._nodeReport(node)\n : undefined;\n node.parents = parents;\n node.scopes = state.scopes;\n node.inherited = state.inherited;\n node.depth = state.depth;\n node.outgoing = computed.outgoing.get(key) ?? new Map();\n if (previous !== undefined) this._emitNodeUpdated(node, previous, 'referral');\n if (scopesChanged) {\n await this._loadNode(node, false);\n relisted = true;\n }\n }\n\n const unreachable = [...this._nodes.values()]\n .filter((node) => !computed.states.has(node.key))\n .sort((a, b) => b.depth - a.depth || a.key.localeCompare(b.key));\n for (const node of unreachable) {\n const previous = this._nodeReport(node);\n this._stopWatch(node, false);\n this._nodes.delete(node.key);\n this._emitNodeRemoved(previous);\n }\n\n if (!relisted) return;\n }\n throw new Error('Hub directory scope reconciliation did not converge');\n }\n\n private _computeScopeFixedPoint(): ComputedDirectoryGraph {\n const states = new Map<string, DerivedNodeState>();\n const parents = new Map<string, Map<string, ParentContribution>>();\n const outgoing = new Map<string, Map<string, ParentContribution>>();\n states.set(ROOT_NODE_KEY, {\n scopes: [...this._initialScopes],\n inherited: [],\n depth: 0,\n });\n parents.set(ROOT_NODE_KEY, new Map());\n const queue = [ROOT_NODE_KEY];\n const processed = new Map<string, string>();\n\n while (queue.length > 0) {\n const key = queue.shift()!;\n const state = states.get(key);\n if (state === undefined) continue;\n const stateKey = derivedStateKey(state);\n if (processed.get(key) === stateKey) continue;\n processed.set(key, stateKey);\n\n const node = this._nodes.get(key);\n const next = node === undefined\n ? new Map<string, ParentContribution>()\n : this._outgoingFor(\n state.scopes,\n state.inherited,\n state.depth,\n node.listings,\n );\n outgoing.set(key, next);\n for (const [childKey, contribution] of next) {\n const childParents = parents.get(childKey) ?? new Map<string, ParentContribution>();\n childParents.set(key, contribution);\n parents.set(childKey, childParents);\n const childState = derivedStateFromParents(childParents);\n const oldState = states.get(childKey);\n if (oldState === undefined || derivedStateKey(oldState) !== derivedStateKey(childState)) {\n states.set(childKey, childState);\n queue.push(childKey);\n }\n }\n }\n return { states, parents, outgoing };\n }\n\n private async _pruneUnreachable(): Promise<void> {\n const reachable = new Set<string>();\n const queue = [ROOT_NODE_KEY];\n while (queue.length > 0) {\n const key = queue.shift()!;\n if (reachable.has(key)) continue;\n reachable.add(key);\n const node = this._nodes.get(key);\n if (node === undefined) continue;\n for (const childKey of node.outgoing.keys()) queue.push(childKey);\n }\n const removedNodes = [...this._nodes.values()]\n .filter((node) => !reachable.has(node.key))\n .sort((a, b) => b.depth - a.depth || a.key.localeCompare(b.key));\n if (removedNodes.length === 0) return;\n const removed = new Set(removedNodes.map((node) => node.key));\n for (const node of removedNodes) {\n const previous = this._nodeReport(node);\n this._stopWatch(node, false);\n this._nodes.delete(node.key);\n this._emitNodeRemoved(previous);\n }\n for (const node of this._nodes.values()) {\n const previous = this._nodeReport(node);\n let changed = false;\n for (const parentKey of removed) changed = node.parents.delete(parentKey) || changed;\n if (changed) await this._updateNodeFromParents(node, previous);\n }\n }\n\n /**\n * Opens a watch for every node that {@link _needsWatch}, each followed by\n * a verification list (list/watch/list): callers reach this method only\n * after a list under the current scope, then the watch is opened before the\n * verification list, so either the list sees a handoff mutation or the\n * watch ticks for it. Verification can reveal new nodes, so this repeats\n * until no node needs a watch. Nodes in backoff are skipped; their timer\n * resumes them.\n */\n private async _synchronizeWatches(): Promise<void> {\n const maxPasses = Math.max(8, this._nodes.size * 4);\n for (let pass = 0; pass < maxPasses && !this._disposed; pass++) {\n const pending = [...this._nodes.values()]\n .filter((node) => this._needsWatch(node))\n .sort((a, b) => a.depth - b.depth || a.key.localeCompare(b.key));\n if (pending.length === 0) return;\n for (const node of pending) {\n if (this._nodes.get(node.key) !== node || !this._needsWatch(node)) continue;\n if (!this._startWatch(node)) continue;\n await this._loadNode(node);\n await this._reconcileScopesFromRoot();\n await this._pruneUnreachable();\n }\n }\n throw new Error('Hub directory watch synchronization did not converge');\n }\n\n /** Whether the node lacks a watch for its current scopes and is not backing off. */\n private _needsWatch(node: DirectoryNode): boolean {\n if (!this._watching || this._disposed) return false;\n const watch = node.watch;\n return watch.kind === 'idle'\n || (watch.kind === 'active' && watch.scopesKey !== scopesKey(node.scopes));\n }\n\n /** Opens a watch for the node's current scopes, replacing an active one. */\n private _startWatch(node: DirectoryNode): boolean {\n const method = node.target === undefined\n ? 'hubrpc.directory::watch'\n : `${node.target}::hubrpc.directory::watch`;\n const params: Record<string, JsonValue | undefined> = {\n serviceIdScopes: [...node.scopes],\n };\n let call: RawStreamingCall;\n try {\n call = this._channel.sendRequestWithStream(method, params, {\n onStreamMessage: () => this._queueTick(node.key),\n });\n } catch (error) {\n this._watchFailed(node, `failed: ${errorMessage(error)}`);\n return false;\n }\n const previous = this._nodeReport(node);\n const replaced = node.watch;\n node.watch = { kind: 'active', call, scopesKey: scopesKey(node.scopes) };\n this._emitNodeUpdated(node, previous, 'watch-started');\n if (replaced.kind === 'active') {\n cancelWatch(replaced.call, 'directory explorer watch scope replaced');\n }\n void call.result.then(\n () => this._onWatchEnded(node, call, 'ended'),\n (error) => this._onWatchEnded(node, call, `ended: ${errorMessage(error)}`),\n );\n return true;\n }\n\n private _onWatchEnded(node: DirectoryNode, call: RawStreamingCall, outcome: string): void {\n if (\n this._disposed\n || this._nodes.get(node.key) !== node\n || node.watch.kind !== 'active'\n || node.watch.call !== call\n ) {\n return;\n }\n this._watchFailed(node, outcome);\n }\n\n /**\n * Puts the node into backoff. Its current watch, if any, is cancelled: a\n * replacement for new scopes failed, so the old one is stale.\n */\n private _watchFailed(node: DirectoryNode, outcome: string): void {\n this._options.log?.(`hub directory watch(${node.target ?? '<root>'}) ${outcome}`);\n if (!this._watching || this._disposed || this._nodes.get(node.key) !== node) return;\n const previous = this._nodeReport(node);\n const watch = node.watch;\n if (watch.kind === 'active') cancelWatch(watch.call, 'directory explorer watch failed');\n if (watch.kind === 'backoff') clearTimeout(watch.timer);\n node.watchFailures++;\n const timer = setTimeout(\n () => this._retryWatch(node),\n watchRetryDelayMs(node.watchFailures),\n );\n node.watch = { kind: 'backoff', timer };\n if (watch.kind === 'active') this._emitNodeUpdated(node, previous, 'watch-ended');\n }\n\n private _retryWatch(node: DirectoryNode): void {\n if (\n this._disposed\n || this._nodes.get(node.key) !== node\n || node.watch.kind !== 'backoff'\n ) {\n return;\n }\n node.watch = { kind: 'idle' };\n if (!this._watching) return;\n this._startReconciliation();\n this._work = this._work.then(async () => {\n await this._synchronizeWatches();\n this._settle();\n }).catch((error) => this._reconciliationFailed('watch retry', error));\n }\n\n /**\n * A failed reconciliation may leave nodes without a watch. Backing them\n * off keeps the invariant that, while watching, every node is either\n * watched or scheduled to retry.\n */\n private _reconciliationFailed(context: string, error: unknown): void {\n this._options.log?.(`hub directory ${context} failed: ${errorMessage(error)}`);\n for (const node of [...this._nodes.values()]) {\n if (this._needsWatch(node)) this._watchFailed(node, 'not resynchronized');\n }\n this._settle();\n }\n\n private _queueTick(key: string): void {\n const ticked = this._nodes.get(key);\n if (this._disposed || ticked === undefined) return;\n ticked.watchFailures = 0;\n this._pendingTicks.add(key);\n this._startReconciliation();\n this._work = this._work.then(async () => {\n while (this._pendingTicks.size > 0 && !this._disposed) {\n const nextKey = this._pendingTicks.values().next().value as string;\n this._pendingTicks.delete(nextKey);\n const node = this._nodes.get(nextKey);\n if (node === undefined) continue;\n await this._loadNode(node);\n await this._reconcileScopesFromRoot();\n await this._pruneUnreachable();\n await this._synchronizeWatches();\n const change = { target: node.target, result: this.result };\n for (const listener of [...this._listeners]) {\n try {\n listener(change);\n } catch (error) {\n this._options.log?.(\n `hub directory change listener failed: ${errorMessage(error)}`,\n );\n }\n }\n }\n this._settle();\n }).catch((error) => this._reconciliationFailed('reconciliation', error));\n }\n\n private _stopWatch(node: DirectoryNode, emit = true): void {\n const watch = node.watch;\n if (watch.kind === 'backoff') clearTimeout(watch.timer);\n const previous = emit && watch.kind === 'active' ? this._nodeReport(node) : undefined;\n node.watch = { kind: 'idle' };\n node.watchFailures = 0;\n if (watch.kind !== 'active') return;\n cancelWatch(watch.call, 'directory explorer watch stopped');\n if (previous !== undefined) this._emitNodeUpdated(node, previous, 'watch-stopped');\n }\n\n private _stopAllWatches(emit = true): void {\n for (const node of this._nodes.values()) this._stopWatch(node, emit);\n }\n\n private _clearNodes(): void {\n this._stopAllWatches(false);\n this._nodes.clear();\n this._unlockAttempted.clear();\n this._pendingTicks.clear();\n this._initialized = false;\n }\n\n private _resetForExplore(): void {\n this._complete = false;\n this._emitSnapshot('reset');\n this._stopAllWatches(false);\n const addressed = [...this._nodes.values()]\n .filter((node) => node.key !== ROOT_NODE_KEY)\n .sort((a, b) => b.depth - a.depth || a.key.localeCompare(b.key));\n for (const node of addressed) {\n const previous = this._nodeReport(node);\n this._nodes.delete(node.key);\n this._emitNodeRemoved(previous, 'reset');\n }\n const previousRoot = this._nodes.get(ROOT_NODE_KEY);\n const root = this._createRootNode();\n this._nodes.set(ROOT_NODE_KEY, root);\n if (previousRoot !== undefined) {\n this._emitNodeUpdated(root, this._nodeReport(previousRoot), 'reset');\n }\n this._unlockAttempted.clear();\n this._pendingTicks.clear();\n this._initialized = false;\n }\n\n private _updateNode(\n node: DirectoryNode,\n reason: Extract<HubDirectoryGraphEvent, { type: 'node-updated' }>['reason'],\n update: () => void,\n ): void {\n const previous = this._nodeReport(node);\n update();\n this._emitNodeUpdated(node, previous, reason);\n }\n\n private _nodeReport(node: DirectoryNode): HubDirectoryNodeReport {\n const parents = [...node.parents.entries()]\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([parentKey, contribution]) => ({\n target: this._targetForKey(parentKey),\n scopes: cloneScopes(contribution.scopes),\n depth: contribution.depth,\n }));\n return {\n target: this._targetForKey(node.key),\n state: node.state,\n effectiveScopes: cloneScopes(node.scopes),\n depth: node.depth,\n parents,\n nativeListings: node.listings.map(cloneListing),\n ...(node.inaccessibleReason === undefined\n ? {}\n : { inaccessibleReason: node.inaccessibleReason }),\n watching: node.watch.kind === 'active',\n };\n }\n\n private _targetForKey(key: string): HubDirectoryGraphTarget {\n if (key === ROOT_NODE_KEY) {\n return this._options.rootTarget === undefined\n ? { kind: 'root' }\n : { kind: 'root', serviceId: this._options.rootTarget };\n }\n return { kind: 'addressed', serviceId: key.slice(2) };\n }\n\n private _emitNodeAdded(node: DirectoryNode): void {\n this._revision++;\n this._emitGraphEvent({\n type: 'node-added',\n reason: 'referral',\n node: this._nodeReport(node),\n snapshot: this.graphSnapshot,\n });\n }\n\n private _emitNodeUpdated(\n node: DirectoryNode,\n previous: HubDirectoryNodeReport,\n reason: Extract<HubDirectoryGraphEvent, { type: 'node-updated' }>['reason'],\n ): void {\n this._revision++;\n this._emitGraphEvent({\n type: 'node-updated',\n reason,\n previous,\n node: this._nodeReport(node),\n snapshot: this.graphSnapshot,\n });\n }\n\n private _emitNodeRemoved(\n previous: HubDirectoryNodeReport,\n reason: Extract<HubDirectoryGraphEvent, { type: 'node-removed' }>['reason'] = 'unreachable',\n ): void {\n this._revision++;\n this._emitGraphEvent({\n type: 'node-removed',\n reason,\n previous,\n snapshot: this.graphSnapshot,\n });\n }\n\n private _startReconciliation(): void {\n if (!this._complete) return;\n this._complete = false;\n this._emitSnapshot('reconciliation-started');\n }\n\n private _settle(): void {\n if (this._complete || this._disposed) return;\n this._complete = true;\n this._revision++;\n this._emitGraphEvent({ type: 'settled', snapshot: this.graphSnapshot });\n }\n\n private _emitSnapshot(\n reason: Extract<HubDirectoryGraphEvent, { type: 'snapshot' }>['reason'],\n ): void {\n this._revision++;\n this._emitGraphEvent({ type: 'snapshot', reason, snapshot: this.graphSnapshot });\n }\n\n private _emitGraphEvent(event: HubDirectoryGraphEvent): void {\n for (const listener of this._graphListeners) this._deliverGraphEvent(listener, event);\n }\n\n private _deliverGraphEvent(\n listener: (event: HubDirectoryGraphEvent) => void,\n event: HubDirectoryGraphEvent,\n ): void {\n try {\n listener(event);\n } catch (error) {\n this._options.log?.(`hub directory graph listener failed: ${errorMessage(error)}`);\n }\n }\n\n private _nodeKeyForTarget(target: string): string {\n const isImplicitRoot = this._options.rootTarget === undefined && target === '';\n return target === this._options.rootTarget || isImplicitRoot\n ? ROOT_NODE_KEY\n : `s:${target}`;\n }\n\n private _throwIfDisposed(): void {\n if (this._disposed) throw new Error('HubDirectoryExplorer is disposed');\n }\n}\n\ninterface ParentContribution {\n readonly scopes: readonly ServiceIdPattern[];\n readonly inherited: readonly RootPrincipalSet[];\n readonly depth: number;\n}\n\ninterface DirectoryNode {\n readonly key: string;\n readonly target: string | undefined;\n parents: Map<string, ParentContribution>;\n scopes: ServiceIdPattern[];\n inherited: RootPrincipalSet[];\n depth: number;\n listings: ServiceListing[];\n outgoing: Map<string, ParentContribution>;\n loaded: boolean;\n loading: boolean;\n reloadRequested: boolean;\n state: HubDirectoryNodeState;\n inaccessibleReason?: string;\n watch: DirectoryWatch;\n /** Consecutive watch failures since the last tick; selects the retry delay. */\n watchFailures: number;\n}\n\n/**\n * Lifecycle of one node's `hubrpc.directory::watch`. This is the single source\n * of truth for whether a node needs a watch: a node in `backoff` is unwatched\n * on purpose and must not be re-watched (and re-listed) before its timer fires.\n */\ntype DirectoryWatch =\n /** No watch open or scheduled; the next synchronization opens one. */\n | { readonly kind: 'idle' }\n /** A watch is open for the scopes identified by `scopesKey`. */\n | { readonly kind: 'active'; readonly call: RawStreamingCall; readonly scopesKey: string }\n /** The last watch failed or ended; `timer` returns the node to `idle`. */\n | { readonly kind: 'backoff'; readonly timer: ReturnType<typeof setTimeout> };\n\nconst WATCH_RETRY_INITIAL_DELAY_MS = 200;\nconst WATCH_RETRY_MAX_DELAY_MS = 30_000;\n\nfunction watchRetryDelayMs(consecutiveFailures: number): number {\n return Math.min(\n WATCH_RETRY_MAX_DELAY_MS,\n WATCH_RETRY_INITIAL_DELAY_MS * 2 ** Math.max(0, consecutiveFailures - 1),\n );\n}\n\nfunction cancelWatch(call: RawStreamingCall, reason: string): void {\n try {\n call.cancel(reason);\n } catch {\n // Best-effort teardown.\n }\n}\n\ninterface DerivedNodeState {\n readonly scopes: ServiceIdPattern[];\n readonly inherited: RootPrincipalSet[];\n readonly depth: number;\n}\n\ninterface ComputedDirectoryGraph {\n readonly states: Map<string, DerivedNodeState>;\n readonly parents: Map<string, Map<string, ParentContribution>>;\n readonly outgoing: Map<string, Map<string, ParentContribution>>;\n}\n\nfunction mergeContributions(\n left: ParentContribution,\n right: ParentContribution,\n): ParentContribution {\n return {\n scopes: normalizeServiceIdScopes([...left.scopes, ...right.scopes]),\n inherited: mergePrincipalSets(left.inherited, right.inherited),\n depth: Math.min(left.depth, right.depth),\n };\n}\n\nfunction derivedStateFromParents(\n parents: ReadonlyMap<string, ParentContribution>,\n): DerivedNodeState {\n const contributions = [...parents.values()];\n return {\n scopes: normalizeServiceIdScopes(contributions.flatMap((value) => value.scopes)),\n inherited: mergePrincipalSets(\n ...contributions.map((value) => value.inherited),\n ),\n depth: Math.min(...contributions.map((value) => value.depth)),\n };\n}\n\nfunction derivedStateKey(state: {\n readonly scopes: readonly ServiceIdPattern[];\n readonly inherited: readonly RootPrincipalSet[];\n readonly depth: number;\n}): string {\n return `${scopesKey(state.scopes)}\\u0001${principalSetsKey(state.inherited)}\\u0001${state.depth}`;\n}\n\nfunction parentContributionsKey(\n parents: ReadonlyMap<string, ParentContribution>,\n): string {\n return [...parents.entries()]\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, contribution]) =>\n `${key}\\u0002${derivedStateKey(contribution)}`)\n .join('\\u0003');\n}\n\nfunction mergePrincipalSets(\n ...groups: readonly (readonly RootPrincipalSet[] | undefined)[]\n): RootPrincipalSet[] {\n const unique = new Map<string, RootPrincipalSet>();\n for (const group of groups) {\n for (const set of group ?? []) {\n const copy = set.map((requirement) => ({ ...requirement }));\n const key = JSON.stringify(copy);\n if (!unique.has(key)) unique.set(key, copy);\n }\n }\n return [...unique.values()];\n}\n\nfunction principalSetsKey(sets: readonly RootPrincipalSet[]): string {\n return JSON.stringify(sets);\n}\n\nfunction listingKey(item: ServiceListing): string {\n return `${item.serviceId}\\u0000${item.interfaceId}\\u0000${item.hash}`;\n}\n\nfunction cloneScopes(scopes: readonly ServiceIdPattern[]): ServiceIdPattern[] {\n return scopes.map((scope) => ({ ...scope }));\n}\n\nfunction cloneListing(item: ServiceListing): ServiceListing {\n return {\n ...item,\n ...(item.tags === undefined ? {} : { tags: [...item.tags] }),\n ...(item.rootPrincipalSets === undefined\n ? {}\n : {\n rootPrincipalSets: item.rootPrincipalSets.map((set) =>\n set.map((requirement) => ({ ...requirement }))),\n }),\n ...(item.reachableServiceIds === undefined\n ? {}\n : { reachableServiceIds: cloneScopes(item.reachableServiceIds) }),\n };\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Extract the `transitive` requirements of a CNF requirement collection as\n * singleton AND-sets (kept transitive), so they keep flowing down further hops.\n */\nfunction transitiveReqsOf(sets: readonly RootPrincipalSet[] | undefined): RootPrincipalSet[] {\n return (sets ?? [])\n .flatMap((set) => set.filter((req) => req.transitive === true))\n .map((req) => [req] as RootPrincipalSet);\n}\n\n/**\n * Prefer a listing whose reporter (`discoveredFrom`) equals its own `serviceId`\n * — that's the participant speaking about itself, and is more authoritative\n * than an aggregator forwarding it.\n */\nfunction _isAuthoritative(candidate: DiscoveredListing, current: DiscoveredListing): boolean {\n const candidateDirect = candidate.discoveredFrom === candidate.serviceId;\n const currentDirect = current.discoveredFrom === current.serviceId;\n return candidateDirect && !currentDirect;\n}\n","import type { JsonRpcMessage, JsonValue } from '../protocol/jsonRpc';\nimport type { IMessageTransport } from '../transport/messageTransport';\n\nexport class Channel<TInCtx = undefined, TOutCtx = undefined> {\n constructor(\n public readonly sender: IRequestSender<TOutCtx>,\n private readonly _setHandler: (h: IRequestHandler<TInCtx> | undefined) => void,\n private readonly _setWireObserver?: (observer: WireMessageObserver | undefined) => void,\n ) { }\n\n /** Bind the inbound request/notification handler. May be called before or after construction of {@link LinkRpcConnection}. */\n public setRequestHandler(handler: IRequestHandler<TInCtx> | undefined): void {\n this._setHandler(handler);\n }\n\n /**\n * Install the endpoint inspection observer at the JSON-RPC wire boundary.\n * Intended for {@link LinkRpcConnection}; ordinary consumers should use the\n * public `hubrpc.traffic` service instead.\n */\n public setWireMessageObserver(observer: WireMessageObserver | undefined): void {\n this._setWireObserver?.(observer);\n }\n\n /**\n * Compose this channel with a sender-side decorator (typically the\n * signing layer). The decorator wraps {@link sender} only; the\n * {@link setRequestHandler} binding is shared with the original channel\n * so the receive side is bound exactly once regardless of decoration depth.\n */\n public withSender<TNewOutCtx>(\n decorate: (raw: IRequestSender<TOutCtx>) => IRequestSender<TNewOutCtx>,\n ): Channel<TInCtx, TNewOutCtx> {\n return new Channel<TInCtx, TNewOutCtx>(\n decorate(this.sender),\n this._setHandler,\n this._setWireObserver,\n );\n }\n}\n\nexport type WireMessageDirection = 'inbound' | 'outbound';\nexport type WireMessageObserver = (\n direction: WireMessageDirection,\n message: JsonRpcMessage,\n) => void;\n\nexport interface IRequestHandler<TInCtx = undefined> {\n handleRequest(call: IncomingCall<TInCtx>): Promise<Result>;\n handleNotification(call: IncomingCall<TInCtx>): void;\n}\n\n/**\n * Inbound call observed by an {@link IRequestHandler}. `TInCtx` is the\n * per-call out-of-band context the transport attached on the receiving\n * side (e.g. the hub stamps `Participant` on overlay-bound messages).\n * For wire transports it's `undefined`.\n */\nexport interface IncomingCall<TInCtx = undefined> {\n method: string;\n params: JsonValue | undefined;\n /** Out-of-band context attached by the transport, if any. */\n context: TInCtx;\n /**\n * Per-call streaming handle. Both directions live on this object,\n * scoped to the request's lifetime. The inbound listener is auto-\n * detached when the handler's response settles. For notifications\n * (no request id) the handle is a no-op stub.\n */\n stream: IncomingStream;\n /**\n * Aborts when the caller cancels this in-flight request (a\n * `toCallee` `cancel` control), or when the hub cancels it on the\n * caller's behalf (caller disconnect / idle timeout). The handler\n * should observe this and settle promptly — typically by throwing,\n * which surfaces as a `cancelled` error response. For notifications\n * this never aborts.\n */\n signal: AbortSignal;\n}\n\n/**\n * Per-call streaming handle attached to {@link IncomingCall.stream}.\n * Scoped to a single in-flight request; the channel automatically\n * detaches the inbound listener when the handler's response settles.\n *\n * For notifications (which have no request id), `requestId` is\n * `undefined`, `send` is a no-op, and `onMessage` is a no-op.\n */\nexport interface IncomingStream {\n /** Emit a server→client stream notification correlated with this call. */\n send(payload: JsonValue): Promise<void>;\n /**\n * Register a listener for client→server stream messages correlated\n * with this call. Pass `undefined` to detach. Replaces any prior\n * listener. The channel detaches the listener automatically when\n * the handler's response settles.\n */\n onMessage(listener: ((payload: JsonValue) => void) | undefined): void;\n /**\n * Liveness probe toward the caller: emit a `toCaller` ping and\n * resolve once the caller's `pong` (matching nonce) returns. Rejects\n * if the request settles first. Independent of the channel's\n * automatic keepalive ping.\n */\n ping(): Promise<void>;\n}\n\nexport type Result =\n | { result: JsonValue; }\n | { error: { code: number; message: string; data?: JsonValue; }; };\n\n/**\n * What callers use to send. The {@link Channel} factory binds an\n * {@link IRequestHandler} at construction (immutable for the channel's\n * lifetime) and hands the caller back an `IRequestSender`.\n *\n * `TOutCtx` is the per-call context bag this sender understands. For\n * the base {@link JsonRpcChannel} it's `undefined` (the channel\n * doesn't read any overrides). Decorators like `SigningSender`\n * parametrise it on their own ctx shape.\n */\nexport interface IRequestSender<TOutCtx = undefined> {\n sendRequest(method: string, params: JsonValue | undefined, opts?: SendOpts<TOutCtx>): Promise<JsonValue>;\n sendNotification(method: string, params: JsonValue | undefined, opts?: SendOpts<TOutCtx>): Promise<void>;\n /**\n * Issue a request that participates in the streaming sub-protocol.\n * Returns synchronously with the wire request id, the result\n * promise, and a `send` for emitting client→server stream messages.\n */\n sendRequestWithStream(method: string, params: JsonValue | undefined, opts?: StreamSendOpts<TOutCtx>): RawStreamingCall;\n close(): void;\n}\n\n/**\n * Handle for a request issued via\n * {@link IRequestSender.sendRequestWithStream}. `send` emits\n * client→server stream messages correlated with this call. `result`\n * resolves with the call's response.\n */\nexport interface RawStreamingCall {\n readonly result: Promise<JsonValue>;\n /** Emit a client→server (`toCallee`) stream message correlated with this call. */\n send(payload: JsonValue): void | Promise<void>;\n /**\n * Ask the callee to abort this in-flight request (a `toCallee`\n * `cancel` control). Advisory: the request settles via its normal\n * response (typically a `cancelled` error). `reason` is an open-set\n * diagnostic string (see `StreamControlReason`).\n */\n cancel(reason?: string): void | Promise<void>;\n /**\n * Stop tracking this request locally and reject {@link result}. This does\n * not notify the callee; call {@link cancel} first when remote work should\n * also be cancelled. Safe to call after the request has already settled.\n */\n dispose?(reason?: string): void;\n /**\n * Liveness probe toward the callee: emit a `toCallee` ping and\n * resolve once the callee's `pong` (matching nonce) returns. Rejects\n * if the request settles first. Independent of the channel's\n * automatic keepalive ping.\n */\n ping(): Promise<void>;\n}\n\n/**\n * Per-send options.\n *\n * `interfaceHash` is interface-level call metadata: the schema hash of\n * the interface a typed proxy is calling. It is independent of\n * `TOutCtx` — the connection stamps it from the interface definition,\n * the base {@link JsonRpcChannel} ignores it, and signing decorators\n * bake it into the `$hubrpc` envelope.\n *\n * `ctx` is the sender's `TOutCtx`-typed override / extension bag for\n * per-call decorator overrides (e.g. `signerOverride`, `capsOverride`).\n * The base {@link JsonRpcChannel} ignores `ctx` entirely; decorators\n * like `SigningSender` interpret it.\n */\nexport interface SendOpts<TOutCtx = undefined> {\n readonly ctx?: TOutCtx;\n /** Interface schema hash for this call (interface-level metadata). */\n readonly interfaceHash?: string;\n}\n\nexport interface StreamSendOpts<TOutCtx = undefined> extends SendOpts<TOutCtx> {\n readonly onStreamMessage?: (payload: JsonValue) => void;\n}\n\n/**\n * Convenience: the transport type a {@link JsonRpcChannel} expects.\n * Outbound is plain `JsonRpcMessage` — the base channel does not\n * attach context to outgoing wire messages.\n */\nexport type ChannelTransport<TInCtx = undefined> = IMessageTransport<MessageWithCtx<TInCtx>>;\n\n/**\n * Type of incoming messages on the channel's transport. With\n * `TInCtx = undefined` (default) this is just `JsonRpcMessage`. With a\n * concrete `TInCtx`, the transport carries a `context` field alongside\n * the message — out-of-band, never sent over a wire, set by the\n * in-process producer.\n */\nexport type MessageWithCtx<TInCtx> = [TInCtx] extends [undefined] ? JsonRpcMessage :\n JsonRpcMessage & { context: TInCtx; };\n\nexport class RpcError extends Error {\n public readonly data?: JsonValue;\n public readonly hasData: boolean;\n\n constructor(\n message: string,\n public readonly code: number,\n data?: JsonValue,\n /** Whether this error was decoded from a peer response. */\n public readonly origin: 'local' | 'remote' | 'transport' = 'local',\n hasData = data !== undefined,\n ) {\n super(message);\n // Preserve invalid wire messages for schema diagnostics instead of Error's string coercion.\n this.message = message;\n this.name = 'RpcError';\n this.hasData = hasData;\n if (hasData) this.data = data;\n }\n}\n","import {\n ErrorCode,\n isNotification,\n isRequest,\n isResponse,\n type JsonRpcError,\n type JsonRpcMessage,\n type JsonRpcNotification,\n type JsonRpcRequest,\n type JsonValue,\n type RequestId,\n} from '../protocol/jsonRpc';\nimport {\n STREAM_METHOD,\n StreamControlType,\n StreamDir,\n type StreamSendParams,\n} from './streaming';\nimport {\n Channel,\n type MessageWithCtx,\n type ChannelTransport,\n type IncomingStream,\n type IRequestHandler,\n type IRequestSender,\n type RawStreamingCall,\n type Result,\n RpcError,\n type SendOpts,\n type StreamSendOpts,\n type WireMessageObserver,\n} from './channel';\n\n/**\n * How often a streaming-enabled call emits a `toCallee` keepalive ping so a\n * routing hub's per-request idle timer never reaps the in-flight request.\n * Must stay comfortably below the hub's idle timeout (default 30 min).\n */\nconst KEEPALIVE_PING_INTERVAL_MS = 10 * 60_000;\n\n/**\n * Minimal JSON-RPC 2.0 channel: correlates requests with responses,\n * dispatches incoming requests/notifications to a handler.\n *\n * Construct via {@link JsonRpcChannel.create}: it returns a\n * {@link Channel} factory which materialises the live channel once a\n * handler is supplied via `.connect(handler)`. The handler is fixed for\n * the channel's lifetime — no setter, no mid-flight swap.\n *\n * The outbound `TOutCtx` of the produced sender is `unknown` — this\n * channel ignores per-call ctx entirely. Decorators (e.g.\n * `SigningSender`) lift it to a concrete shape.\n */\nexport class JsonRpcChannel<TInCtx = undefined> implements IRequestSender<unknown> {\n /**\n * Wrap a transport in a {@link Channel}. The channel's sender is live\n * immediately; call {@link Channel.setRequestHandler} (or pass the channel\n * to {@link LinkRpcConnection}) to bind the inbound handler.\n */\n public static create<TInCtx = undefined>(transport: ChannelTransport<TInCtx>): Channel<TInCtx, unknown> {\n return this.createWithClose(transport).channel;\n }\n\n /**\n * Wrap a transport with lifecycle hooks. deferRequests queues requests,\n * notifications, and their input streams until resumeRequests is called.\n * Responses and output streams remain live for setup-time outbound calls.\n * Passing method names to resumeRequests releases only those non-streaming\n * requests, leaving notifications and input streams deferred.\n */\n public static createWithClose<TInCtx = undefined>(\n transport: ChannelTransport<TInCtx>,\n options: { readonly deferRequests?: boolean } = {},\n ): { channel: Channel<TInCtx, unknown>; close: (error?: Error) => void; resumeRequests: (methods?: readonly string[]) => void; } {\n const jrc = new JsonRpcChannel<TInCtx>(transport, options.deferRequests === true);\n const channel = new Channel<TInCtx, unknown>(\n jrc,\n (h) => jrc.setRequestHandler(h),\n (observer) => jrc.setWireMessageObserver(observer),\n );\n return { channel, close: error => jrc.close(error), resumeRequests: methods => jrc.resumeRequests(methods) };\n }\n\n private _nextId = 1;\n private readonly _pending = new Map<string, {\n resolve: (v: JsonValue) => void;\n reject: (err: Error) => void;\n }>();\n /**\n * Per-request callbacks invoked when a {@link STREAM_METHOD}\n * notification arrives with a matching `requestId`. Used in both\n * directions: outgoing-request callers register here keyed by the\n * id they sent; per-call incoming-request stream handles register\n * keyed by the id they observed. Entries are removed when the\n * corresponding request completes (response received for outgoing,\n * response sent for incoming).\n */\n private readonly _streamListeners = new Map<string, (payload: JsonValue) => void>();\n\n /**\n * Per-incoming-request handlers for reserved `control` messages\n * (cancel / ping / pong) arriving as stream notifications. Keyed\n * by the id observed; removed when the request settles.\n */\n private readonly _streamControl = new Map<\n string,\n (control: { type: string; reason?: string; nonce?: string; }) => void\n >();\n private readonly _incomingAborts = new Map<string, AbortController>();\n\n private _handler: IRequestHandler<TInCtx> | undefined;\n private _wireObserver: WireMessageObserver | undefined;\n private _closeError: Error | undefined;\n private readonly _deferredMessages: MessageWithCtx<TInCtx>[] = [];\n private readonly _resumedMethods = new Set<string>();\n\n public setRequestHandler(handler: IRequestHandler<TInCtx> | undefined): void {\n this._handler = handler;\n }\n\n public setWireMessageObserver(\n observer: WireMessageObserver | undefined,\n ): void {\n this._wireObserver = observer;\n }\n\n private constructor(\n private readonly _transport: ChannelTransport<TInCtx>,\n private _requestsDeferred: boolean,\n ) {\n this._transport.setListener((m) => this._onMessage(m));\n }\n\n public resumeRequests(methods?: readonly string[]): void {\n if (methods === undefined) {\n while (this._deferredMessages.length > 0) {\n this._dispatchMessage(this._deferredMessages.shift()!);\n }\n this._requestsDeferred = false;\n } else {\n for (const method of methods) this._resumedMethods.add(method);\n for (let i = 0; i < this._deferredMessages.length;) {\n const message = this._deferredMessages[i];\n if (isRequest(message) && this._resumedMethods.has(message.method)) {\n this._deferredMessages.splice(i, 1);\n this._dispatchMessage(message);\n } else {\n i++;\n }\n }\n }\n }\n\n public async sendRequest(\n method: string,\n params: JsonValue | undefined,\n opts?: SendOpts<unknown>,\n ): Promise<JsonValue> {\n this._throwIfClosed();\n const id = this._nextId++;\n const req: JsonRpcRequest = { jsonrpc: '2.0', id, method };\n if (params !== undefined) req.params = params;\n const promise = new Promise<JsonValue>((resolve, reject) => {\n this._pending.set(String(id), { resolve, reject });\n });\n this._observeOutbound(req, opts);\n void (async () => {\n try {\n await this._transport.send(req);\n } catch (error) {\n const pending = this._pending.get(String(id));\n this._pending.delete(String(id));\n this._observeSendFailure(id, error);\n pending?.reject(error instanceof Error ? error : new Error(String(error)));\n }\n })();\n return promise;\n }\n\n public async sendNotification(\n method: string,\n params: JsonValue | undefined,\n opts?: SendOpts<unknown>,\n ): Promise<void> {\n this._throwIfClosed();\n const n: JsonRpcNotification = { jsonrpc: '2.0', method };\n if (params !== undefined) n.params = params;\n this._observeOutbound(n, opts);\n await this._transport.send(n);\n }\n\n public sendRequestWithStream(\n method: string,\n params: JsonValue | undefined,\n opts?: StreamSendOpts<unknown>,\n ): RawStreamingCall {\n this._throwIfClosed();\n const id = this._nextId++;\n const key = String(id);\n let resolveResult!: (v: JsonValue) => void;\n let rejectResult!: (err: Error) => void;\n const result = new Promise<JsonValue>((resolve, reject) => {\n resolveResult = resolve;\n rejectResult = reject;\n });\n this._pending.set(key, { resolve: resolveResult, reject: rejectResult });\n if (opts?.onStreamMessage) {\n this._streamListeners.set(key, opts.onStreamMessage);\n }\n // Symmetric ping/pong for this call. We emit controls `toCallee`,\n // so an inbound ping is answered with a `toCallee` pong.\n const pinger = this._makePinger(id, StreamDir.toCallee);\n this._streamControl.set(key, pinger.onControl);\n // Keepalive: a streaming-enabled call emits a periodic `toCallee`\n // ping so the hub's per-request idle timer never reaps it. Cleared\n // once the call settles (in either direction). Fire-and-forget: the\n // peer's pong (no matching nonce) is ignored.\n const ping = setInterval(() => {\n void this._sendStream(id, StreamDir.toCallee, {\n control: { type: StreamControlType.ping },\n }).catch(error => this.close(error));\n }, KEEPALIVE_PING_INTERVAL_MS);\n (ping as { unref?: () => void; }).unref?.();\n const stopPing = (): void => {\n clearInterval(ping);\n pinger.dispose();\n this._streamControl.delete(key);\n };\n const dispose = (reason = 'streaming request disposed'): void => {\n if (!this._pending.delete(key)) return;\n this._streamListeners.delete(key);\n stopPing();\n rejectResult(new RpcError(reason, ErrorCode.cancelled));\n };\n result.then(stopPing, stopPing);\n (async () => {\n const req: JsonRpcRequest = { jsonrpc: '2.0', id, method };\n if (params !== undefined) req.params = params;\n this._observeOutbound(req, opts);\n await this._transport.send(req);\n })().catch((err) => {\n // Send-time failure: clear bookkeeping and surface on result.\n this._pending.delete(key);\n this._streamListeners.delete(key);\n this._observeSendFailure(id, err);\n stopPing();\n rejectResult(err instanceof Error ? err : new Error(String(err)));\n });\n return {\n result,\n send: (payload) => this._sendStream(id, StreamDir.toCallee, { payload }),\n cancel: (reason) =>\n this._sendStream(id, StreamDir.toCallee, {\n control: reason !== undefined ?\n { type: StreamControlType.cancel, reason } :\n { type: StreamControlType.cancel },\n }),\n dispose,\n ping: pinger.ping,\n };\n }\n\n /**\n * Build the symmetric ping/pong machinery for one in-flight request.\n *\n * `outboundDir` is the direction *this* side emits controls in\n * (`toCallee` for the caller, `toCaller` for the callee). A received\n * ping is answered with a pong in that same direction, echoing the\n * ping's nonce; a received pong resolves the matching outstanding\n * {@link ping} probe.\n */\n private _makePinger(requestId: RequestId, outboundDir: StreamDir): {\n ping: () => Promise<void>;\n onControl: (control: { type: string; nonce?: string; }) => void;\n dispose: () => void;\n } {\n const pending = new Map<string, { resolve: () => void; reject: (e: Error) => void; }>();\n let nextNonce = 1;\n const ping = (): Promise<void> => {\n const nonce = `${requestId}:${nextNonce++}`;\n const p = new Promise<void>((resolve, reject) => pending.set(nonce, { resolve, reject }));\n void this._sendStream(requestId, outboundDir, {\n control: { type: StreamControlType.ping, nonce },\n }).catch(error => this.close(error));\n return p;\n };\n const onControl = (control: { type: string; nonce?: string; }): void => {\n if (control.type === StreamControlType.ping) {\n // Auto-answer: echo the nonce back the way our controls travel.\n void this._sendStream(requestId, outboundDir, {\n control: { type: StreamControlType.pong, nonce: control.nonce },\n }).catch(error => this.close(error));\n } else if (control.type === StreamControlType.pong && control.nonce !== undefined) {\n const waiter = pending.get(control.nonce);\n if (waiter) {\n pending.delete(control.nonce);\n waiter.resolve();\n }\n }\n };\n const dispose = (): void => {\n const err = new RpcError('Request settled before pong', ErrorCode.cancelled);\n for (const w of pending.values()) w.reject(err);\n pending.clear();\n };\n return { ping, onControl, dispose };\n }\n\n /**\n * Emit a stream notification ({@link STREAM_METHOD}) associated with\n * an in-flight request. Internal: outgoing-side callers reach this\n * via {@link RawStreamingCall.send} / `cancel`; incoming-side handlers\n * reach it via {@link IncomingStream.send}.\n */\n private async _sendStream(\n requestId: RequestId,\n dir: StreamDir,\n fields: {\n payload?: JsonValue;\n control?: { type: StreamControlType; reason?: string; nonce?: string; };\n },\n ): Promise<void> {\n this._throwIfClosed();\n const params: StreamSendParams = { requestId, dir, ...fields };\n const n: JsonRpcNotification = {\n jsonrpc: '2.0',\n method: STREAM_METHOD,\n params: params as unknown as JsonValue,\n };\n this._observeOutbound(n);\n await this._transport.send(n);\n }\n\n public close(error: Error = new RpcError('Connection closed', ErrorCode.peerDisconnected)): void {\n if (this._closeError) return;\n this._closeError = error;\n this._deferredMessages.length = 0;\n for (const abort of this._incomingAborts.values()) abort.abort(error);\n this._incomingAborts.clear();\n this._transport.dispose();\n for (const p of this._pending.values()) p.reject(error);\n this._pending.clear();\n this._streamListeners.clear();\n this._streamControl.clear();\n }\n\n private _throwIfClosed(): void {\n if (this._closeError) throw this._closeError;\n }\n\n private _onMessage(m: MessageWithCtx<TInCtx>): void {\n this._observeInbound(m);\n if (\n this._requestsDeferred\n && !isResponse(m)\n && !(isRequest(m) && this._resumedMethods.has(m.method))\n && !(isNotification(m) && m.method === STREAM_METHOD\n && (m.params as StreamSendParams | undefined)?.dir === StreamDir.toCaller)\n ) {\n this._deferredMessages.push(m);\n return;\n }\n this._dispatchMessage(m);\n }\n\n private _dispatchMessage(m: MessageWithCtx<TInCtx>): void {\n // `context` is present iff TInCtx ≠ undefined; the channel itself\n // doesn't care which case we're in and just forwards whatever the\n // transport delivered.\n const ctx = (m as { context?: TInCtx; }).context as TInCtx;\n if (isResponse(m)) {\n if (m.id === null) return;\n const key = String(m.id);\n const pending = this._pending.get(key);\n if (!pending) return;\n this._pending.delete(key);\n // Outgoing-request stream listener (if any) is scoped to the\n // request's lifetime; drop it when the response arrives.\n this._streamListeners.delete(key);\n if ('error' in m) {\n const e = m.error;\n const err = new RpcError(\n e.message,\n e.code,\n e.data,\n 'remote',\n Object.hasOwn(e, 'data'),\n );\n pending.reject(err);\n } else {\n pending.resolve(m.result);\n }\n return;\n }\n if (isRequest(m)) {\n void this._handleRequest(m, ctx).catch(() => {\n // A response can lose its transport after the request handler\n // has completed; there is no caller left to receive that error.\n });\n return;\n }\n if (isNotification(m)) {\n if (m.method === STREAM_METHOD) {\n this._handleStreamNotification(m);\n return;\n }\n this._handleNotification(m, ctx);\n return;\n }\n }\n\n private _handleStreamNotification(m: JsonRpcNotification): void {\n const params = m.params as StreamSendParams | undefined;\n if (!params) return;\n const requestId = params.requestId;\n if (requestId === undefined) return;\n const key = String(requestId);\n // Reserved control (cancel / ping): routed to the per-request\n // control handler, never to the app payload listener.\n if (params.control) {\n this._streamControl.get(key)?.(params.control);\n return;\n }\n const listener = this._streamListeners.get(key);\n if (!listener) return;\n listener(params.payload as JsonValue);\n }\n\n private async _handleRequest(m: JsonRpcRequest, context: TInCtx): Promise<void> {\n const key = String(m.id);\n // Symmetric ping/pong for this call. The handler emits controls\n // `toCaller`, so an inbound ping is answered with a `toCaller` pong.\n const pinger = this._makePinger(m.id, StreamDir.toCaller);\n const stream: IncomingStream = {\n send: (payload) => this._sendStream(m.id, StreamDir.toCaller, { payload }),\n onMessage: (listener) => {\n if (listener) this._streamListeners.set(key, listener);\n else this._streamListeners.delete(key);\n },\n ping: pinger.ping,\n };\n // A `toCallee` cancel control trips the handler's AbortSignal;\n // ping/pong are liveness only and handled by the pinger.\n const abort = new AbortController();\n this._incomingAborts.set(key, abort);\n this._streamControl.set(key, (control) => {\n if (control.type === StreamControlType.cancel) {\n abort.abort(new RpcError(control.reason ?? 'cancelled', ErrorCode.cancelled));\n } else {\n pinger.onControl(control);\n }\n });\n\n let result: Result;\n try {\n if (!this._handler) {\n result = {\n error: {\n code: ErrorCode.methodNotFound,\n message: `No handler registered on this endpoint (method: ${m.method}).`,\n },\n };\n } else {\n try {\n result = await this._handler.handleRequest({\n method: m.method,\n params: m.params,\n context,\n stream,\n signal: abort.signal,\n });\n } catch (e) {\n result = {\n error: {\n code: ErrorCode.internalError,\n message: e instanceof Error ? e.message : String(e),\n },\n };\n }\n }\n } finally {\n // Auto-detach the inbound stream listener + control: the handler is done.\n this._streamListeners.delete(key);\n this._streamControl.delete(key);\n this._incomingAborts.delete(key);\n pinger.dispose();\n }\n if ('result' in result) {\n const response = {\n jsonrpc: '2.0',\n id: m.id,\n result: result.result,\n } as const;\n this._observeOutbound(response);\n await this._transport.send(response);\n } else {\n const resp: JsonRpcError = {\n jsonrpc: '2.0',\n id: m.id,\n error: result.error,\n };\n this._observeOutbound(resp);\n await this._transport.send(resp);\n }\n }\n\n private _handleNotification(m: JsonRpcNotification, context: TInCtx): void {\n if (!this._handler) return;\n try {\n this._handler.handleNotification({\n method: m.method,\n params: m.params,\n context,\n stream: _NOOP_STREAM,\n signal: _NEVER_ABORT,\n });\n } catch {\n // Notifications have no response; swallow exceptions to avoid\n // killing the transport.\n }\n }\n\n private _observeInbound(message: JsonRpcMessage): void {\n const observer = this._wireObserver;\n if (observer === undefined) return;\n observer('inbound', message);\n }\n\n private _observeOutbound(\n message: JsonRpcMessage,\n opts?: SendOpts<unknown>,\n ): void {\n const observer = this._wireObserver;\n if (observer === undefined) return;\n observer('outbound', message);\n }\n\n private _observeSendFailure(requestId: RequestId, error: unknown): void {\n if (this._wireObserver === undefined) return;\n this._observeInbound({\n jsonrpc: '2.0',\n id: requestId,\n error: {\n code: ErrorCode.peerDisconnected,\n message: error instanceof Error ? error.message : String(error),\n },\n });\n }\n\n}\n\n/** Stub stream handle for notifications, which carry no request id. */\nconst _NOOP_STREAM: IncomingStream = {\n send: () => Promise.resolve(),\n onMessage: () => { },\n ping: () => Promise.resolve(),\n};\n\n/** A signal that never aborts — handed to notification handlers. */\nconst _NEVER_ABORT: AbortSignal = new AbortController().signal;\n","import type { InterfaceDefinition } from './interfaceDefinition';\nimport type { BareInterfaceTarget } from './bareInterfaceTarget';\n\n/** A qualified LinkRPC route. An empty serviceId addresses the root interface. */\nexport interface QualifiedInterfaceTarget<TDef extends InterfaceDefinition<any>> {\n readonly mode: 'qualified';\n readonly interface: TDef;\n readonly serviceId: string;\n}\n\n/** The peer's preset form-1 route, retaining LinkRPC metadata and streaming. */\nexport interface DefaultInterfaceTarget<TDef extends InterfaceDefinition<any>> {\n readonly mode: 'default';\n readonly interface: TDef;\n}\n\nexport type InterfaceTarget<TDef extends InterfaceDefinition<any>> =\n | QualifiedInterfaceTarget<TDef>\n | DefaultInterfaceTarget<TDef>\n | BareInterfaceTarget<TDef>;\n\nexport function interfaceTarget<TDef extends InterfaceDefinition<any>>(\n iface: TDef,\n options: { readonly serviceId?: string } = {},\n): QualifiedInterfaceTarget<TDef> {\n const serviceId = options.serviceId ?? '';\n if (serviceId.includes('::') || !/^[\\x20-\\x7e]*$/.test(serviceId)) {\n throw new Error('Service id must contain only printable ASCII and must not contain \"::\".');\n }\n return Object.freeze({ mode: 'qualified', interface: iface, serviceId });\n}\n\nexport function defaultInterfaceTarget<TDef extends InterfaceDefinition<any>>(\n iface: TDef,\n): DefaultInterfaceTarget<TDef> {\n return Object.freeze({ mode: 'default', interface: iface });\n}\n\nexport function isInterfaceTarget<TDef extends InterfaceDefinition<any>>(\n value: TDef | InterfaceTarget<TDef>,\n): value is InterfaceTarget<TDef> {\n return typeof value === 'object' && value !== null\n && 'interface' in value && 'mode' in value\n && (value.mode === 'qualified' || value.mode === 'default' || value.mode === 'bare');\n}\n","import { ErrorCode, type JsonRpcMessage, type JsonValue } from '../protocol/jsonRpc';\nimport { parseMethodName } from '../protocol/methodName';\nimport { stripLinkRpcWireMeta } from '../protocol/linkRpcEnvelope';\nimport {\n defaultsInterface,\n directoryInterface,\n schemasInterface,\n type RootPrincipalSet,\n type ServiceIdPattern,\n} from '../hub/common/reflection.interfaces';\nimport { serviceIdMatchesScopes } from '../hub/common/directoryWalk';\nimport { nodeInterface, type NodeInfo, type TopologyIdGenerator } from '../inspection/node.interfaces';\nimport {\n topologyInterface,\n trafficInterface,\n type ParticipantDescriptorSource,\n type TrafficTransitEvent,\n} from '../inspection/inspection.interfaces';\nimport type {\n CheckedCallResult,\n InterfaceClient,\n InterfaceResultClient,\n GenericRpcError,\n InterfaceDefinition,\n InterfaceHandlers,\n StreamApi,\n} from './interfaceDefinition';\nimport { RpcFailure } from './rpcFailure';\nimport { preferRicherInterfaceSchema } from '../schema/interfaceTemplates';\nimport { NonCompliantServerError } from './nonCompliantServerError';\nimport { jsonIssues, parseDeclaredErrorBody } from '../schema/errorValidation';\nimport { brandApplicationError } from '../schema/applicationErrorBrand';\nimport {\n type ApplicationErrorDescriptorBase,\n type RpcErrorBody,\n isApplicationErrorValue,\n type MemberType,\n type RequestType,\n type Schema,\n} from '../schema/memberTypes';\nimport { safeParse } from 'zod/v4/core';\nimport type { IMessageTransport } from '../transport/messageTransport';\nimport {\n Channel,\n type MessageWithCtx,\n type IncomingCall,\n type IncomingStream,\n type IRequestSender, type Result,\n RpcError,\n type StreamSendOpts,\n type WireMessageObserver,\n} from './channel';\nimport { JsonRpcChannel } from './jsonRpcChannel';\nimport { bytesToBase64Url } from '../crypto/cryptoProvider';\nimport { InspectionHost } from '../inspection/inspectionHost';\nimport {\n validateBarePrefix,\n type BareInterfaceTarget,\n} from './bareInterfaceTarget';\nimport { isInterfaceTarget, type InterfaceTarget } from './interfaceTarget';\n\nexport interface LinkRpcConnectionOptions {\n /** Topology node/port ID generator. Defaults to cryptographic randomness. */\n readonly generateTopologyId?: TopologyIdGenerator;\n /**\n * Validate parameters passed through typed interface clients before sending\n * them. Enabled by default. Disable only when interoperating with a peer\n * whose accepted wire shape intentionally differs from the local schema.\n */\n readonly validateOutboundParams?: boolean;\n}\n\n/**\n * High-level linkrpc connection. Layers method-name routing and zod-driven\n * validation on top of a plain JSON-RPC channel.\n *\n * Typed proxies built by this class merely forward each call's\n * `interfaceHash` hint to the channel so the signer stamps it into the\n * `$hubrpc` envelope.\n *\n * `TInCtx` is the per-call out-of-band context the connection's transport\n * carries. Default `undefined` covers cross-process and ordinary in-process\n * transports. The hub's self/overlay connections instantiate with a\n * concrete `TInCtx` (e.g. `Participant`) so handlers can see who originated\n * the call.\n *\n * `TOutCtx` is the per-call override / extension bag the outbound sender\n * understands (see {@link SendOpts.ctx}). It only ever flows into the\n * sender as input, so it is a contravariant type parameter. Default `any`\n * keeps the bare `LinkRpcConnection` a valid supertype for holders that do\n * not care about the outbound ctx; pass a concrete shape (e.g.\n * `SigningCallCtx`) to get precise {@link get} typing. The connection\n * itself is agnostic to its contents — it merely forwards the `ctx`\n * defaults supplied to {@link get}.\n */\nexport class LinkRpcConnection<TInCtx = any, TOutCtx = any> {\n /**\n * Convenience: build a {@link JsonRpcChannel} `Channel` from the\n * given transport and wrap it in an `LinkRpcConnection`. Use this\n * when you have a transport at hand and don't need a decorator\n * stack (e.g. signing).\n */\n public static fromTransport<TInCtx = undefined>(\n transport: IMessageTransport<MessageWithCtx<TInCtx>, JsonRpcMessage>,\n options: LinkRpcConnectionOptions = {},\n ): LinkRpcConnection<TInCtx> {\n return new LinkRpcConnection<TInCtx>(JsonRpcChannel.create<TInCtx>(transport), options);\n }\n\n /** Underlying JSON-RPC sender — useful for callers that need raw access (e.g. to call hub-served methods that bypass the interface registry). */\n public readonly channel: IRequestSender<TOutCtx>;\n\n /** key = `${serviceId ?? \"\"}::${interfaceId}` */\n private readonly _registry = new Map<string, RegisteredInterface>();\n\n /** Descriptions for services that have been registered with a `serviceDescription`. */\n private readonly _serviceDescriptions = new Map<string, string>();\n\n /** Root-node-id requirement sets recorded per serviceId. */\n private readonly _serviceRootPrincipalSets = new Map<string, readonly RootPrincipalSet[]>();\n\n private readonly _directoryWatchers = new Set<DirectoryWatcher>();\n private readonly _directoryListeners = new Set<() => void>();\n\n private _inspection: InspectionRegistration | undefined;\n private _inspectionHost: InspectionHost | undefined;\n private readonly _serviceInspectionRegistrations = new Map<string, InterfaceRegistration[]>();\n private readonly _wireObservers = new Set<WireMessageObserver>();\n private readonly _closeListeners = new Set<() => void>();\n private _closed = false;\n private readonly _wireChannel: Channel<TInCtx, TOutCtx> | undefined;\n private readonly _validateOutboundParams: boolean;\n /** Bare-method bindings, keyed by their exact wire prefix. */\n private readonly _bareBindings = new Map<string, BareBinding>();\n private readonly _generateTopologyId: TopologyIdGenerator;\n\n /**\n * Construct from a {@link Channel} (binds the inbound handler and uses\n * `channel.sender` for outbound calls) or from a bare\n * {@link IRequestSender} (send-only — no inbound handler is registered,\n * useful for bootstrap flows like `createManagedIdentity`).\n */\n constructor(\n channel: Channel<TInCtx, TOutCtx> | IRequestSender<TOutCtx>,\n options: LinkRpcConnectionOptions = {},\n ) {\n this._validateOutboundParams = options.validateOutboundParams !== false;\n this._generateTopologyId = options.generateTopologyId ?? createInspectionId;\n if ('sender' in channel) {\n this._wireChannel = channel;\n this.channel = channel.sender;\n channel.setRequestHandler({\n handleRequest: (c) => this._handleRequest(c),\n handleNotification: (c) => this._handleNotification(c),\n });\n } else {\n this._wireChannel = undefined;\n this.channel = channel;\n }\n }\n\n /** Get a typed client using a bundled qualified, default, or bare route. */\n public get<TDef extends InterfaceDefinition<any>>(\n target: InterfaceTarget<TDef>,\n ): InterfaceClient<TDef>;\n\n /** Get a typed client for `iface`, routed to the implicit (root) service. */\n public get<TDef extends InterfaceDefinition<any>>(\n iface: TDef,\n opts?: GetOptions<TOutCtx>,\n ): InterfaceClient<TDef>;\n\n public get<TDef extends InterfaceDefinition<any>>(\n ifaceOrTarget: TDef | InterfaceTarget<TDef>,\n opts?: GetOptions<TOutCtx>,\n ): InterfaceClient<TDef> {\n return this._getClient(ifaceOrTarget, opts, false) as InterfaceClient<TDef>;\n }\n\n private _getClient(\n ifaceOrTarget: InterfaceDefinition<any> | InterfaceTarget<InterfaceDefinition<any>>,\n opts: GetOptions<TOutCtx> | undefined,\n allFailuresAsValues: boolean,\n ): Record<string, unknown> {\n if (isInterfaceTarget(ifaceOrTarget)) {\n if (opts !== undefined) {\n const api = allFailuresAsValues ? 'getResultClient' : 'get';\n throw new Error(`${api}: ${ifaceOrTarget.mode === 'bare' ? 'bare ' : ''}interface targets do not accept service or call options.`);\n }\n if (ifaceOrTarget.mode === 'bare') {\n return this._buildBareClient(ifaceOrTarget.interface, ifaceOrTarget.prefix, allFailuresAsValues);\n }\n return this._buildClient(ifaceOrTarget.interface,\n (ifaceOrTarget.mode === 'qualified' ? { serviceId: ifaceOrTarget.serviceId } : {}) as GetOptions<TOutCtx>,\n undefined, ifaceOrTarget.mode === 'default', allFailuresAsValues);\n }\n return this._buildClient(ifaceOrTarget, opts ?? {}, undefined, false, allFailuresAsValues);\n }\n\n /**\n * Get a typed client that emits foreign-protocol bare method names.\n * Unlike {@link get}, these calls carry no LinkRPC interface metadata.\n */\n public getBare<TDef extends InterfaceDefinition<any>>(\n iface: TDef,\n opts: BareGetOptions = {},\n ): InterfaceClient<TDef> {\n return this._buildBareClient(iface, opts.prefix ?? '', false) as InterfaceClient<TDef>;\n }\n\n private _buildBareClient(\n iface: InterfaceDefinition<any>,\n prefix: string,\n allFailuresAsValues: boolean,\n ): Record<string, unknown> {\n validateBarePrefix(prefix);\n for (const [name, member] of Object.entries(iface.members) as [string, MemberType][]) {\n if (\n member.kind === 'request'\n && (member.clientStreamSchema !== undefined || member.serverStreamSchema !== undefined)\n ) {\n throw new Error(`getBare: streaming method \"${name}\" is not supported on foreign wires.`);\n }\n }\n return this._buildClient(iface, {}, prefix, false, allFailuresAsValues);\n }\n\n /** Return request failures as values for a bundled qualified, default, or bare route. */\n public getResultClient<TDef extends InterfaceDefinition<any>>(\n target: InterfaceTarget<TDef>,\n ): InterfaceResultClient<TDef>;\n\n /** Return application and generic request failures as values instead of throwing. */\n public getResultClient<TDef extends InterfaceDefinition<any>>(\n iface: TDef,\n opts?: GetOptions<TOutCtx>,\n ): InterfaceResultClient<TDef>;\n\n public getResultClient<TDef extends InterfaceDefinition<any>>(\n ifaceOrTarget: TDef | InterfaceTarget<TDef>,\n opts?: GetOptions<TOutCtx>,\n ): InterfaceResultClient<TDef> {\n return this._getClient(ifaceOrTarget, opts, true) as InterfaceResultClient<TDef>;\n }\n\n /** Get a service-scoped handle; all interfaces obtained from it route via `serviceId` (form 3). */\n public service(serviceId: string): ServiceHandle<TInCtx, TOutCtx> {\n return new ServiceHandle<TInCtx, TOutCtx>(this, serviceId);\n }\n\n /** Register handlers, adding preset routing when passed a default or bare target. */\n public register<TDef extends InterfaceDefinition<any>>(\n ifaceOrTarget: TDef | InterfaceTarget<TDef>,\n handlers: InterfaceHandlers<TDef, TInCtx>,\n opts: RegisterOptions = {},\n ): InterfaceRegistration {\n if (isInterfaceTarget(ifaceOrTarget)) {\n if (ifaceOrTarget.mode === 'qualified') {\n if (opts.serviceId !== undefined && opts.serviceId !== ifaceOrTarget.serviceId) {\n throw new Error('register: serviceId conflicts with interface target.');\n }\n return this._register(ifaceOrTarget.interface, handlers,\n { ...opts, serviceId: ifaceOrTarget.serviceId || undefined }, false);\n }\n const prefix = ifaceOrTarget.mode === 'bare' ? ifaceOrTarget.prefix : '';\n validateBarePrefix(prefix);\n return this._register(\n ifaceOrTarget.interface,\n handlers,\n opts,\n false,\n prefix,\n );\n }\n return this._register(ifaceOrTarget, handlers, opts, false);\n }\n\n /** Register inspection contracts without recursively enabling service inspection. */\n public registerInspection<TDef extends InterfaceDefinition<any>>(\n iface: TDef,\n handlers: InterfaceHandlers<TDef, TInCtx>,\n opts: RegisterOptions = {},\n ): InterfaceRegistration {\n return this._register(iface, handlers, opts, true);\n }\n\n /** Observe this connection without replacing another inspection scope's observer. */\n public observeWireMessages(observer: WireMessageObserver): InterfaceRegistration {\n if (this._closed) throw new Error('Connection is closed');\n if (this._wireChannel === undefined) throw new Error('Connection has no observable wire channel');\n this._wireObservers.add(observer);\n this._wireChannel.setWireMessageObserver((direction, message) => {\n for (const listener of [...this._wireObservers]) {\n try {\n listener(direction, message);\n } catch {\n // Diagnostic observers cannot interrupt transport delivery.\n }\n }\n });\n return { dispose: () => {\n this._wireObservers.delete(observer);\n if (this._wireObservers.size === 0) this._wireChannel?.setWireMessageObserver(undefined);\n } };\n }\n\n public onDidClose(listener: () => void): InterfaceRegistration {\n if (this._closed) throw new Error('Connection is closed');\n this._closeListeners.add(listener);\n return { dispose: () => { this._closeListeners.delete(listener); } };\n }\n\n private _register<TDef extends InterfaceDefinition<any>>(\n iface: TDef,\n handlers: InterfaceHandlers<TDef, TInCtx>,\n opts: RegisterOptions,\n internalInspection: boolean,\n barePrefix?: string,\n ): InterfaceRegistration {\n const serviceId = opts.serviceId;\n const key = `${serviceId ?? ''}::${iface.info.id}`;\n if (this._registry.has(key)) {\n throw new Error(\n `Interface \"${iface.info.id}\" already registered${serviceId ? ` under service \"${serviceId}\"` : ''}.`,\n );\n }\n if (barePrefix !== undefined && this._bareBindings.has(barePrefix)) {\n throw new Error(`Bare interface prefix \"${barePrefix}\" is already registered.`);\n }\n\n let descriptionWasAdded = false;\n if (opts.serviceDescription !== undefined) {\n if (serviceId === undefined) {\n throw new Error('register: `serviceDescription` requires `serviceId`.');\n }\n const existing = this._serviceDescriptions.get(serviceId);\n if (existing !== undefined && existing !== opts.serviceDescription) {\n throw new Error(\n `register: conflicting descriptions for service \"${serviceId}\".`,\n );\n }\n descriptionWasAdded = existing === undefined;\n }\n\n let rootPrincipalSetsWereAdded = false;\n if (opts.rootPrincipalSets !== undefined) {\n if (serviceId === undefined) {\n throw new Error('register: `rootPrincipalSets` requires `serviceId`.');\n }\n const existing = this._serviceRootPrincipalSets.get(serviceId);\n if (existing !== undefined && !rootPrincipalSetsEqual(existing, opts.rootPrincipalSets)) {\n throw new Error(\n `register: conflicting rootPrincipalSets for service \"${serviceId}\".`,\n );\n }\n rootPrincipalSetsWereAdded = existing === undefined;\n }\n\n const entry: RegisteredInterface = {\n iface,\n handlers: iface.flattenHandlers(handlers) as Record<string, (p: any, c: any) => any>,\n serviceId,\n internalInspection,\n };\n if (descriptionWasAdded) {\n this._serviceDescriptions.set(serviceId!, opts.serviceDescription!);\n }\n if (rootPrincipalSetsWereAdded) {\n this._serviceRootPrincipalSets.set(serviceId!, opts.rootPrincipalSets!);\n }\n this._registry.set(key, entry);\n if (barePrefix !== undefined) {\n this._bareBindings.set(barePrefix, { prefix: barePrefix, entry });\n }\n this._notifyDirectoryWatchers(entry, descriptionWasAdded || rootPrincipalSetsWereAdded);\n\n if (\n !internalInspection\n && serviceId !== undefined\n && this._inspection !== undefined\n && !this._serviceInspectionRegistrations.has(serviceId)\n ) {\n try {\n this._installServiceInspection(serviceId);\n } catch (error) {\n this._registry.delete(key);\n if (barePrefix !== undefined) this._bareBindings.delete(barePrefix);\n if (descriptionWasAdded) this._serviceDescriptions.delete(serviceId);\n if (rootPrincipalSetsWereAdded) this._serviceRootPrincipalSets.delete(serviceId);\n this._notifyDirectoryWatchers(entry);\n throw error;\n }\n }\n\n let disposed = false;\n return {\n dispose: () => {\n if (disposed) return;\n disposed = true;\n if (this._registry.get(key) !== entry) return;\n\n this._registry.delete(key);\n for (const [prefix, binding] of this._bareBindings) {\n if (binding.entry === entry) this._bareBindings.delete(prefix);\n }\n this._notifyDirectoryWatchers(entry);\n if (\n serviceId !== undefined\n && !this._hasBusinessServiceRegistration(serviceId)\n ) {\n this._removeServiceInspection(serviceId);\n this._serviceDescriptions.delete(serviceId);\n this._serviceRootPrincipalSets.delete(serviceId);\n }\n },\n };\n }\n\n /** Wire methods currently accepted by this connection, including preset bindings. */\n public listRegisteredMethods(): readonly { readonly method: string; readonly definition: MemberType }[] {\n const methods: { method: string; definition: MemberType }[] = [];\n for (const entry of this._registry.values()) {\n const prefix = entry.serviceId ? `${entry.serviceId}::${entry.iface.info.id}::` : `${entry.iface.info.id}::`;\n for (const [name, definition] of Object.entries(entry.iface.members) as [string, MemberType][]) {\n methods.push({ method: `${prefix}${name}`, definition });\n }\n }\n for (const { prefix, entry } of this._bareBindings.values()) {\n for (const [name, definition] of Object.entries(entry.iface.members) as [string, MemberType][]) {\n methods.push({ method: `${prefix}${name}`, definition });\n }\n }\n return methods;\n }\n\n /** Snapshot of every interface currently registered on this connection. */\n public listRegisteredInterfaces(): readonly {\n readonly serviceId: string;\n readonly interfaceId: string;\n readonly interfaceHash: string;\n readonly tags?: readonly string[];\n readonly serviceDescription?: string;\n readonly rootPrincipalSets?: readonly RootPrincipalSet[];\n }[] {\n return Array.from(this._registry.values()).map((r) => {\n const sid = r.serviceId ?? '';\n const item: {\n serviceId: string;\n interfaceId: string;\n interfaceHash: string;\n tags?: readonly string[];\n serviceDescription?: string;\n rootPrincipalSets?: readonly RootPrincipalSet[];\n } = {\n serviceId: sid,\n interfaceId: r.iface.info.id,\n interfaceHash: r.iface.schemaHash,\n };\n if (r.iface.info.tags !== undefined) item.tags = r.iface.info.tags;\n const desc = sid === '' ? undefined : this._serviceDescriptions.get(sid);\n if (desc !== undefined) item.serviceDescription = desc;\n const sets = sid === '' ? undefined : this._serviceRootPrincipalSets.get(sid);\n if (sets !== undefined) item.rootPrincipalSets = sets;\n return item;\n });\n }\n\n /** Subscribe to coarse local directory changes; listeners must re-list. */\n public onDidChangeDirectory(listener: () => void): () => void {\n this._directoryListeners.add(listener);\n return () => this._directoryListeners.delete(listener);\n }\n\n /**\n * Look up a registered interface definition by id (and optional content\n * hash). Returns `undefined` if no registered interface matches.\n */\n public findRegisteredInterface(\n interfaceId: string,\n hash?: string,\n ): InterfaceDefinition<any> | undefined {\n let selected: InterfaceDefinition<any> | undefined;\n for (const r of this._registry.values()) {\n if (r.iface.info.id !== interfaceId) continue;\n if (hash !== undefined && r.iface.schemaHash !== hash) continue;\n if (selected === undefined\n || preferRicherInterfaceSchema(selected.toSchema(), r.iface.toSchema()) === r.iface.toSchema()) {\n selected = r.iface;\n }\n }\n return selected;\n }\n\n /**\n * Register the three linkrpc reflection interfaces (`defaults`,\n * `directory`, `schemas`), backed by this connection's live registry.\n *\n * By default they live under the root service (form-2 reachable as\n * `hubrpc.directory::list`). Pass `serviceId` to additionally mount\n * them under a specific service — useful for participants that live\n * behind a hub, so callers can reach reflection via form-3\n * `<serviceId>::hubrpc.directory::list`.\n *\n * Idempotent: re-registering the same `(serviceId, interfaceId)` pair\n * is a no-op.\n */\n public enableReflection(opts: { serviceId?: string; } = {}): InterfaceRegistration {\n const key = `${opts.serviceId ?? ''}::${defaultsInterface.info.id}`;\n if (this._registry.has(key)) return { dispose() { } };\n const prefix = `${opts.serviceId ?? ''}::`;\n for (const iface of [directoryInterface, schemasInterface]) {\n if (this._registry.has(`${prefix}${iface.info.id}`)) {\n throw new Error(\n `enableReflection: partial reflection registration for service \"${opts.serviceId ?? ''}\".`,\n );\n }\n }\n\n const regOpts: RegisterOptions = opts.serviceId !== undefined ?\n { serviceId: opts.serviceId } :\n {};\n const registrations: InterfaceRegistration[] = [];\n\n registrations.push(this.register(defaultsInterface, {\n get: () => {\n const binding = this._bareBindings.get('');\n if (!binding) return {};\n return {\n serviceId: binding.entry.serviceId,\n interfaceId: binding.entry.iface.info.id,\n interfaceHash: binding.entry.iface.schemaHash,\n };\n },\n listBindings: () => ({\n bindings: Array.from(this._bareBindings.values())\n .sort((a, b) => a.prefix < b.prefix ? -1 : a.prefix > b.prefix ? 1 : 0)\n .map((binding) => ({\n prefix: binding.prefix,\n serviceId: binding.entry.serviceId,\n interfaceId: binding.entry.iface.info.id,\n interfaceHash: binding.entry.iface.schemaHash,\n })),\n }),\n }, regOpts));\n\n registrations.push(this.register(directoryInterface, {\n list: ({ interfaceId, interfaceIdPrefix, serviceId, serviceIdScopes, cursor, limit }) => {\n const all = this.listRegisteredInterfaces()\n .filter((r) => opts.serviceId === undefined || r.serviceId === opts.serviceId)\n .filter((r) => interfaceId === undefined || r.interfaceId === interfaceId)\n .filter((r) => interfaceIdPrefix === undefined || r.interfaceId.startsWith(interfaceIdPrefix))\n .filter((r) => serviceId === undefined || r.serviceId === serviceId)\n .filter((r) => serviceIdMatchesScopes(r.serviceId, serviceIdScopes));\n const start = cursor === undefined ? 0 : Number.parseInt(cursor, 10) || 0;\n const end = limit === undefined ? all.length : Math.min(all.length, start + limit);\n const page = all.slice(start, end).map((r) => ({\n serviceId: r.serviceId,\n interfaceId: r.interfaceId,\n interfaceHash: r.interfaceHash,\n tags: r.tags === undefined ? undefined : [...r.tags],\n serviceDescription: r.serviceDescription,\n rootPrincipalSets: r.rootPrincipalSets?.map((set) => set.map((p) => ({ ...p }))),\n }));\n return end < all.length ?\n { items: page, nextCursor: String(end) } :\n { items: page };\n },\n watch: (params, _ctx, stream) => new Promise((resolve) => {\n const watcher: DirectoryWatcher = {\n interfaceId: params.interfaceId,\n interfaceIdPrefix: params.interfaceIdPrefix,\n serviceId: params.serviceId,\n serviceIdScopes: params.serviceIdScopes,\n send: () => stream.send({}),\n };\n this._directoryWatchers.add(watcher);\n const finish = () => {\n this._directoryWatchers.delete(watcher);\n resolve({});\n };\n if (stream.signal.aborted) {\n finish();\n return;\n }\n stream.signal.addEventListener('abort', finish, { once: true });\n }),\n }, regOpts));\n\n registrations.push(this.register(schemasInterface, {\n get: ({ interfaceId, hash }) => {\n const iface = this.findRegisteredInterface(interfaceId, hash);\n if (!iface) {\n throw new RpcError(\n 'Interface not found',\n ErrorCode.methodNotFound,\n { reason: 'unknown-interface', interfaceId, hash },\n );\n }\n return { schema: iface.toSchema() as unknown };\n },\n }, regOpts));\n\n // A service-scoped reflection set is *also* surfaced at the connection\n // root, so a hub that reads this connection's root directory\n // (`H·root → P`) discovers its `<serviceId>::hubrpc.directory` referral\n // without reaching the (capability-gated) service directory. Keyed\n // separately and guarded above, so the recursive root call is a no-op\n // once root reflection exists.\n if (opts.serviceId !== undefined) {\n try {\n this.enableReflection();\n } catch (error) {\n for (const registration of registrations.reverse()) {\n registration.dispose();\n }\n throw error;\n }\n }\n\n let disposed = false;\n return {\n dispose: () => {\n if (disposed) return;\n disposed = true;\n for (const registration of registrations.reverse()) {\n registration.dispose();\n }\n },\n };\n }\n\n private _notifyDirectoryWatchers(\n entry: RegisteredInterface,\n serviceMetadataChanged = false,\n ): void {\n for (const listener of this._directoryListeners) {\n try {\n listener();\n } catch {\n // Directory invalidation observers cannot interrupt registry mutations.\n }\n }\n for (const watcher of this._directoryWatchers) {\n if (watcher.pending) continue;\n const directlyMatches = directoryWatcherMatchesEntry(watcher, entry);\n const metadataMatches = serviceMetadataChanged\n && entry.serviceId !== undefined\n && [...this._registry.values()].some((candidate) =>\n candidate.serviceId === entry.serviceId\n && directoryWatcherMatchesEntry(watcher, candidate));\n if (!directlyMatches && !metadataMatches) continue;\n watcher.pending = true;\n queueMicrotask(() => {\n watcher.pending = false;\n if (this._directoryWatchers.has(watcher)) watcher.send();\n });\n }\n }\n\n /**\n * Enable the root `hubrpc.node::getNodeId` topology-bootstrap service.\n *\n * The generated ids are stable while this registration is active. They are\n * unauthenticated correlation labels only; callers must not use them for\n * identity, capability, or authorization decisions.\n */\n public enableInspection(\n descriptors?: readonly ParticipantDescriptorSource[],\n ): InspectionRegistration {\n if (this._inspection !== undefined) return this._inspection;\n\n const info: NodeInfo = {\n nodeId: this._generateTopologyId('node'),\n portId: this._generateTopologyId('port'),\n ...(descriptors !== undefined ? { descriptors: [...descriptors] } : {}),\n };\n const registration = this._register(nodeInterface, {\n getNodeId: () => info,\n }, {}, true);\n\n const host = new InspectionHost({ nodeId: info.nodeId, descriptors });\n try {\n if (this._wireChannel !== undefined) host.trackConnection(this, { portId: info.portId });\n } catch (error) {\n host.dispose();\n registration.dispose();\n throw error;\n }\n this._inspectionHost = host;\n\n let disposed = false;\n const result: InspectionRegistration = {\n ...info,\n observeTraffic: (observer) => host.observeTraffic(observer),\n dispose: () => {\n if (disposed) return;\n disposed = true;\n for (const serviceId of [...this._serviceInspectionRegistrations.keys()]) {\n this._removeServiceInspection(serviceId);\n }\n host.dispose();\n if (this._inspectionHost === host) {\n this._inspectionHost = undefined;\n }\n registration.dispose();\n if (this._inspection === result) {\n this._inspection = undefined;\n }\n },\n };\n this._inspection = result;\n try {\n const services = new Set(\n Array.from(this._registry.values())\n .filter((entry) =>\n entry.serviceId !== undefined && !entry.internalInspection)\n .map((entry) => entry.serviceId!),\n );\n for (const serviceId of services) this._installServiceInspection(serviceId);\n } catch (error) {\n result.dispose();\n throw error;\n }\n return result;\n }\n\n /** Number of active endpoint traffic stream subscribers. */\n public get trafficObserverCount(): number {\n return this._inspectionHost?.observerCount ?? 0;\n }\n\n public close(): void {\n if (this._closed) return;\n this._closed = true;\n for (const listener of [...this._closeListeners]) listener();\n this._closeListeners.clear();\n this._inspection?.dispose();\n this._wireObservers.clear();\n this._wireChannel?.setWireMessageObserver(undefined);\n this.channel.close();\n }\n\n // ---- client side ----\n\n private _buildClient(\n iface: InterfaceDefinition<any>,\n opts: GetOptions<TOutCtx>,\n barePrefix?: string,\n defaultRoute = false,\n allFailuresAsValues = false,\n ): Record<string, unknown> {\n const { serviceId, ...ctxRest } = opts;\n const sendOpts = barePrefix === undefined\n ? { ctx: ctxRest as unknown as TOutCtx, interfaceHash: iface.schemaHash }\n : undefined;\n const prefix = barePrefix ?? (defaultRoute ? '' : serviceId ? `${serviceId}::${iface.info.id}::` : `${iface.info.id}::`);\n const proxy: Record<string, (p: any) => any> = Object.create(null);\n for (const [name, member] of Object.entries(iface.members) as [string, MemberType][]) {\n const wireMethod = `${prefix}${name}`;\n\n if (member.kind === 'request') {\n const hasStream = member.clientStreamSchema !== undefined ||\n member.serverStreamSchema !== undefined;\n\n if (hasStream) {\n // Streaming-enabled call. Returns a Promise<R> augmented\n // with `send`. `requestId` resolves once the request has\n // been allocated by the channel; `send` defers until\n // then so callers can emit client-stream messages\n // synchronously after the call returns.\n const serverStreamSchema = member.serverStreamSchema;\n proxy[name] = (\n params: unknown,\n callOpts?: { onMessage?: (m: unknown) => void; },\n ) => {\n const userListener = callOpts?.onMessage;\n // Symmetric with the server-side handler: parse\n // inbound stream payloads against the declared\n // schema and drop anything that doesn't match.\n // The handler always sees validated data.\n const onStreamMessage = userListener !== undefined ?\n (raw: JsonValue) => {\n if (serverStreamSchema !== undefined) {\n const r = safeParse(serverStreamSchema, raw);\n if (!r.success) return;\n userListener(r.data);\n return;\n }\n userListener(raw);\n } :\n undefined;\n\n const channelOpts: StreamSendOpts<TOutCtx> | undefined = onStreamMessage !== undefined ?\n { ...sendOpts, onStreamMessage } :\n sendOpts;\n let call: import('./channel').RawStreamingCall;\n try {\n this._validateOutboundParamsFor(member, wireMethod, params);\n call = this.channel.sendRequestWithStream(\n wireMethod,\n params as JsonValue | undefined,\n channelOpts,\n );\n } catch (cause) {\n if (!allFailuresAsValues) throw cause;\n call = {\n result: Promise.reject(cause),\n send: () => { throw cause; },\n cancel: () => { throw cause; },\n ping: async () => { throw cause; },\n };\n }\n const result = call.result.then((raw) =>\n validateWireResult(member.resultSchema, raw, wireMethod));\n const checked = addCheckedResult(result, member, allFailuresAsValues);\n\n return Object.assign(checked, {\n send: async (payload: unknown) => call.send(payload as JsonValue),\n cancel: async (reason?: string) => call.cancel(reason),\n dispose: (reason?: string) => call.dispose?.(reason),\n ping: () => call.ping(),\n });\n };\n } else {\n proxy[name] = (params: unknown) => {\n const result = (async () => {\n this._validateOutboundParamsFor(member, wireMethod, params);\n const raw = await this.channel.sendRequest(\n wireMethod,\n params as JsonValue | undefined,\n sendOpts,\n );\n return validateWireResult(member.resultSchema, raw, wireMethod);\n })();\n return addCheckedResult(result, member, allFailuresAsValues);\n };\n }\n } else {\n const notify = (params: unknown) => {\n this._validateOutboundParamsFor(member, wireMethod, params);\n return this.channel.sendNotification(\n wireMethod,\n params as JsonValue | undefined,\n sendOpts,\n );\n };\n // Preserve native notifications' async rejection and bare\n // notifications' synchronous validation errors.\n proxy[name] = barePrefix === undefined ? async (params: unknown) => notify(params)\n : (params: unknown) => { void notify(params); };\n }\n }\n return iface.nestClient(proxy);\n }\n\n private _validateOutboundParamsFor(\n member: MemberType,\n wireMethod: string,\n params: unknown,\n ): void {\n if (!this._validateOutboundParams) return;\n validateValue(\n member.paramsSchema,\n params,\n `Invalid params for ${wireMethod}`,\n ErrorCode.invalidParams,\n );\n }\n\n // ---- server side ----\n\n private async _handleRequest(call: IncomingCall<TInCtx>): Promise<Result> {\n const parsed = this._parseRouted(call.method);\n if (!parsed.ok) return notFound(parsed.reason, call.method);\n\n const { entry, memberName } = parsed;\n const member = entry.iface.members[memberName];\n if (!member) return notFound('unknown-method', call.method);\n\n const handler = entry.handlers[memberName] as\n | ((params: unknown, ctx: TInCtx, stream: StreamApi<unknown, unknown>) => unknown)\n | undefined;\n if (!handler) return notFound('unknown-method', call.method);\n\n // Keep call.params intact for chained-hub verification and transport\n // middleware; only the terminal application-schema view is stripped.\n const userParams = stripLinkRpcWireMeta(call.params);\n const parsedParams = safeParse((member as MemberType).paramsSchema, userParams);\n if (!parsedParams.success) {\n return {\n error: {\n code: ErrorCode.invalidParams,\n message: 'Invalid params',\n data: { issues: parsedParams.error.issues as unknown as JsonValue },\n },\n };\n }\n\n if (member.kind !== 'request') {\n // Caller used request semantics on a notification-only method.\n return notFound('unknown-method', call.method);\n }\n\n const stream = this._buildStreamApi(call.stream, call.signal, member);\n try {\n const pendingResult = handler(parsedParams.data, call.context, stream);\n const result = await pendingResult;\n const encodedError = encodeApplicationError(member, result);\n if (encodedError !== undefined) return { error: encodedError };\n validateValue(\n member.resultSchema,\n result,\n `Invalid result for ${call.method}`,\n ErrorCode.internalError,\n );\n return { result: result === undefined ? null : (result as JsonValue) };\n } catch (e) {\n if (e instanceof RpcError) {\n return { error: { code: e.code, message: e.message, data: e.data } };\n }\n return {\n error: {\n code: ErrorCode.internalError,\n message: e instanceof Error ? e.message : String(e),\n },\n };\n }\n // Inbound stream listener is auto-detached by JsonRpcChannel when\n // the handler's response settles — no manual unregister needed.\n }\n\n private _buildStreamApi(\n callStream: IncomingStream,\n signal: AbortSignal,\n member: RequestType<unknown, unknown, unknown, unknown, unknown, any, any>,\n ): StreamApi<unknown, unknown> {\n return {\n send: (payload: unknown) => {\n if (member.serverStreamSchema) {\n const r = safeParse(member.serverStreamSchema, payload);\n if (!r.success) {\n throw new Error(\n `Server stream payload failed schema validation: ${r.error.message}`,\n );\n }\n }\n return callStream.send(payload as JsonValue);\n },\n onMessage: (listener: (payload: unknown) => void) => {\n callStream.onMessage((raw) => {\n if (member.clientStreamSchema) {\n const r = safeParse(member.clientStreamSchema, raw);\n if (!r.success) return; // drop invalid client stream payload\n listener(r.data);\n return;\n }\n // No declared client stream schema => the method does\n // not accept client-emitted stream messages. Drop.\n });\n },\n ping: () => callStream.ping(),\n signal,\n };\n }\n\n private _handleNotification(call: IncomingCall<TInCtx>): void {\n const parsed = this._parseRouted(call.method);\n if (!parsed.ok) return;\n const { entry, memberName } = parsed;\n const member = entry.iface.members[memberName];\n if (member?.kind !== 'notification') return;\n const handler = entry.handlers[memberName] as\n | ((params: unknown, ctx: TInCtx) => unknown)\n | undefined;\n if (!handler) return;\n\n const userParams = stripLinkRpcWireMeta(call.params);\n const parsedParams = safeParse(member.paramsSchema, userParams);\n if (!parsedParams.success) return;\n void handler(parsedParams.data, call.context);\n }\n\n private _parseRouted(method: string):\n | { ok: true; entry: RegisteredInterface; memberName: string; }\n | { ok: false; reason: string; } {\n const parsed = parseMethodName(method);\n if (!parsed) return { ok: false, reason: 'bad-method-grammar' };\n\n if (parsed.kind === 'bare') {\n let selected: BareBinding | undefined;\n for (const binding of this._bareBindings.values()) {\n if (\n parsed.member.startsWith(binding.prefix)\n && (selected === undefined || binding.prefix.length > selected.prefix.length)\n ) {\n selected = binding;\n }\n }\n if (!selected) return { ok: false, reason: 'no-preset' };\n return {\n ok: true,\n entry: selected.entry,\n memberName: parsed.member.slice(selected.prefix.length),\n };\n }\n\n const serviceId = parsed.kind === 'full' ? parsed.serviceId : undefined;\n const key = `${serviceId ?? ''}::${parsed.interfaceId}`;\n const entry = this._registry.get(key);\n if (!entry) {\n return {\n ok: false,\n reason: serviceId ? 'unknown-service' : 'unknown-interface',\n };\n }\n return { ok: true, entry, memberName: parsed.member };\n }\n\n private _installServiceInspection(serviceId: string): void {\n if (this._serviceInspectionRegistrations.has(serviceId)) return;\n const info = this._inspection;\n const host = this._inspectionHost;\n if (info === undefined || host === undefined) return;\n this._serviceInspectionRegistrations.set(serviceId, [\n host.expose(this, { serviceId, portId: info.portId }),\n ]);\n }\n\n private _removeServiceInspection(serviceId: string): void {\n const registrations = this._serviceInspectionRegistrations.get(serviceId);\n if (registrations === undefined) return;\n this._serviceInspectionRegistrations.delete(serviceId);\n for (const registration of registrations.reverse()) registration.dispose();\n }\n\n private _hasBusinessServiceRegistration(serviceId: string): boolean {\n return Array.from(this._registry.values()).some((entry) =>\n entry.serviceId === serviceId && !entry.internalInspection);\n }\n\n}\n\n\n/**\n * Options when obtaining a typed client for an interface.\n *\n * - `serviceId`: route to a specific service (form 3). Omit for form 2\n * (implicit / root service on the connection).\n * - any `TOutCtx` property: a per-client default merged into the `ctx`\n * of every call issued through the returned proxy (e.g.\n * `signerOverride`, `capsOverride` for a signing channel). The\n * connection forwards these verbatim; it does not interpret them.\n *\n * Schema-version pinning travels as interface-level call metadata\n * ({@link SendOpts.interfaceHash}); the typed proxy stamps\n * `iface.schemaHash` automatically, independent of `TOutCtx`.\n */\nexport type GetOptions<TOutCtx = undefined> = {\n serviceId?: string;\n} & Partial<TOutCtx>;\n\n/** Options for a metadata-free, bare-method typed client. */\nexport interface BareGetOptions {\n prefix?: string;\n}\n\nexport interface RegisterOptions {\n /**\n * If set, this interface is mounted under this service id (form 3).\n */\n serviceId?: string;\n /**\n * Optional human description recorded for `serviceId` and surfaced\n * through `hubrpc.directory::list`. Requires `serviceId`. The first\n * registration's description wins; any later registration that\n * supplies a *different* non-undefined description throws.\n */\n serviceDescription?: string;\n /**\n * Root node ids required to access `serviceId`, in CNF (AND of OR-sets):\n * the caller must satisfy **every** set, and a set is satisfied by **any\n * one** of its node ids. Surfaced through `hubrpc.directory::list`.\n * Requires `serviceId`. Recorded per service; a later registration that\n * supplies a *different* value for the same `serviceId` throws.\n */\n rootPrincipalSets?: readonly RootPrincipalSet[];\n}\n\n/** A live interface registration. Disposing it removes dispatch and reflection state. */\nexport interface InterfaceRegistration {\n /** Remove this exact registration. Idempotent. */\n dispose(): void;\n}\n\n/** Generated topology identity and its live root-interface registration. */\nexport interface InspectionRegistration extends InterfaceRegistration, NodeInfo {\n /**\n * Observe this endpoint's full-payload traffic in-process. Watch-control\n * flows are tracked even when no public observations are active.\n */\n observeTraffic(observer: (transit: TrafficTransitEvent) => void): InterfaceRegistration;\n}\n\nfunction createInspectionId(kind: 'node' | 'port'): string {\n const bytes = new Uint8Array(16);\n globalThis.crypto.getRandomValues(bytes);\n return `${kind}:${bytesToBase64Url(bytes)}`;\n}\n\n/** Structural equality for two CNF root-node-id requirement collections. */\nfunction rootPrincipalSetsEqual(\n a: readonly RootPrincipalSet[],\n b: readonly RootPrincipalSet[],\n): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const sa = a[i];\n const sb = b[i];\n if (sa.length !== sb.length) return false;\n for (let j = 0; j < sa.length; j++) {\n if (sa[j].principal !== sb[j].principal) return false;\n if ((sa[j].transitive === true) !== (sb[j].transitive === true)) return false;\n }\n }\n return true;\n}\n\ninterface RegisteredInterface {\n iface: InterfaceDefinition<any>;\n handlers: Record<string, (params: any, ctx: any) => any>;\n serviceId: string | undefined;\n internalInspection: boolean;\n}\n\ninterface DirectoryWatcher {\n readonly interfaceId: string | undefined;\n readonly interfaceIdPrefix: string | undefined;\n readonly serviceId: string | undefined;\n readonly serviceIdScopes: readonly ServiceIdPattern[] | undefined;\n readonly send: () => void;\n pending?: boolean;\n}\n\nfunction directoryWatcherMatchesEntry(\n watcher: DirectoryWatcher,\n entry: RegisteredInterface,\n): boolean {\n const serviceId = entry.serviceId ?? '';\n return (watcher.interfaceId === undefined || watcher.interfaceId === entry.iface.info.id)\n && (watcher.interfaceIdPrefix === undefined\n || entry.iface.info.id.startsWith(watcher.interfaceIdPrefix))\n && (watcher.serviceId === undefined || watcher.serviceId === serviceId)\n && serviceIdMatchesScopes(serviceId, watcher.serviceIdScopes);\n}\n\ninterface BareBinding {\n readonly prefix: string;\n readonly entry: RegisteredInterface;\n}\n\ntype DecodedApplicationError = RpcErrorBody & {\n readonly kind: 'application';\n readonly code: number;\n readonly type?: string;\n};\n\nfunction addCheckedResult<TResult>(\n promise: Promise<TResult>,\n member: RequestType<any, any, any, any, any, any, any>,\n allFailuresAsValues = false,\n) {\n const settled = promise.then(\n (value) => ({ ok: true as const, value }),\n (cause) => ({ ok: false as const, error: decodeCheckedError(cause, member.applicationErrors), cause }),\n );\n const result = settled.then((outcome) => {\n if (outcome.ok) return outcome.value;\n if (allFailuresAsValues) {\n return new RpcFailure(outcome.error.kind === 'application'\n ? { kind: 'application' as const, error: outcome.error }\n : { kind: 'generic' as const, error: outcome.error });\n }\n if (outcome.error.kind === 'application') return new RpcFailure(outcome.error);\n throw outcome.error.kind === 'nonCompliantServer' ? outcome.error : outcome.cause;\n });\n return Object.assign(result, {\n result: async (): Promise<CheckedCallResult<TResult, DecodedApplicationError>> => {\n // Only suppress the default view's rejection when its compatibility\n // view is actually consumed.\n void result.catch(() => {});\n const outcome = await settled;\n return outcome.ok ? outcome : { ok: false, error: outcome.error };\n },\n });\n}\n\nfunction decodeCheckedError(\n cause: unknown,\n descriptors: readonly ApplicationErrorDescriptorBase[],\n): DecodedApplicationError | GenericRpcError {\n if (cause instanceof NonCompliantServerError) return cause;\n if (!(cause instanceof RpcError) || cause.origin !== 'remote') {\n return { kind: cause instanceof RpcError && cause.origin === 'transport' ? 'transport' : 'local', cause };\n }\n\n const original = {\n code: cause.code, message: cause.message,\n ...(cause.hasData ? { data: cause.data } : {}),\n };\n const candidates = descriptors.filter((candidate) => candidate.code === cause.code)\n .sort((a, b) => Number(b.type !== undefined) - Number(a.type !== undefined));\n const body = { message: cause.message, ...(cause.hasData ? { data: cause.data } : {}) };\n const issues = [];\n for (const descriptor of candidates) {\n const parsed = parseDeclaredErrorBody(descriptor, body);\n if (!parsed.success) {\n issues.push(...parsed.issues);\n continue;\n }\n if (descriptor.type === undefined) {\n return brandApplicationError({\n ...parsed.data, kind: 'application' as const, code: descriptor.code,\n });\n }\n const envelope = parsed.data.data;\n return brandApplicationError({\n kind: 'application' as const, code: descriptor.code, message: parsed.data.message,\n type: descriptor.type,\n ...(typeof envelope === 'object' && envelope !== null && 'data' in envelope\n ? { data: envelope.data } : {}),\n });\n }\n if (candidates.length > 0) return new NonCompliantServerError(original, issues);\n\n return {\n kind: 'remote',\n ...original,\n };\n}\n\nfunction encodeApplicationError(\n member: RequestType<any, any, any, any, any, any, any>,\n value: unknown,\n): { code: number; message: string; data?: JsonValue; } | undefined {\n if (!isApplicationErrorValue(value)) return undefined;\n const candidate = value as {\n code?: unknown;\n message?: unknown;\n data?: unknown;\n type?: unknown;\n };\n const descriptor = member.applicationErrors.find(\n (error: ApplicationErrorDescriptorBase) =>\n error.code === candidate.code && error.type === candidate.type\n && (error.bodySchema !== undefined || error.type !== undefined || error.message === candidate.message),\n );\n if (descriptor === undefined) {\n throw new RpcError(\n `Undeclared application error ${String(candidate.code)}`,\n ErrorCode.internalError,\n );\n }\n\n const data = Object.hasOwn(value, 'data') ? { data: value.data } : {};\n const body = {\n message: value.message,\n ...(descriptor.type === undefined ? data : { data: { type: descriptor.type, ...data } }),\n };\n const parsed = parseDeclaredErrorBody(descriptor, body);\n const issues = parsed.success ? jsonIssues(body) : parsed.issues;\n if (issues.length > 0) {\n throw new RpcError(`Invalid data for application error ${descriptor.code}`,\n ErrorCode.internalError, { issues: issues.map((issue) => ({ ...issue })) });\n }\n return { code: descriptor.code, ...body } as { code: number; message: string; data?: JsonValue };\n}\n\nfunction validateWireResult(schema: Schema, raw: JsonValue, wireMethod: string): JsonValue | undefined {\n const value = normalizeWireResult(schema, raw);\n validateValue(schema, value, `Invalid result for ${wireMethod}`, ErrorCode.internalError);\n return value;\n}\n\n/** Validate at both ends without stripping extra keys or applying schema transforms. */\nfunction validateValue(schema: Schema, value: unknown, message: string, code: number): void {\n const checked = safeParse(schema, value);\n if (!checked.success) {\n throw new RpcError(\n message,\n code,\n { issues: checked.error.issues as unknown as JsonValue },\n );\n }\n}\n\n/** Undo the server's undefined → null convention only when the schema rejects null. */\nfunction normalizeWireResult(schema: Schema, raw: JsonValue): JsonValue | undefined {\n if (raw !== null) return raw;\n if (safeParse(schema, null).success) return null;\n if (safeParse(schema, undefined).success) return undefined;\n return null;\n}\n\n\n/** Service-scoped handle returned by `connection.service(id)`. */\nexport class ServiceHandle<TInCtx = undefined, TOutCtx = undefined> {\n constructor(\n private readonly _connection: LinkRpcConnection<TInCtx, TOutCtx>,\n private readonly _serviceId: string,\n ) { }\n\n public getResultClient<TDef extends InterfaceDefinition<any>>(\n iface: TDef,\n opts: Partial<TOutCtx> = {},\n ): InterfaceResultClient<TDef> {\n return this._connection.getResultClient(iface, { ...opts, serviceId: this._serviceId } as GetOptions<TOutCtx>);\n }\n\n public get<TDef extends InterfaceDefinition<any>>(\n iface: TDef,\n opts: Partial<TOutCtx> = {},\n ): InterfaceClient<TDef> {\n return this._connection.get(iface, { ...opts, serviceId: this._serviceId } as GetOptions<TOutCtx>);\n }\n\n public register<TDef extends InterfaceDefinition<any>>(\n ifaceOrTarget: TDef | BareInterfaceTarget<TDef>,\n handlers: InterfaceHandlers<TDef, TInCtx>,\n opts: Omit<RegisterOptions, 'serviceId'> = {},\n ): InterfaceRegistration {\n return this._connection.register<TDef>(\n ifaceOrTarget,\n handlers,\n { ...opts, serviceId: this._serviceId },\n );\n }\n}\n\nfunction notFound(reason: string, method: string): Result {\n return {\n error: {\n code: ErrorCode.methodNotFound,\n message: `Method not found: ${method}`,\n data: { reason, method },\n },\n };\n}\n\nfunction isInspectionInterface(iface: InterfaceDefinition<any>): boolean {\n return iface === nodeInterface\n || iface === topologyInterface\n || iface === trafficInterface;\n}\n"],"mappings":"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"}
|