import { EventEmitter } from 'node:events'; import type { ClientToBroker } from '../runtime/broker-protocol.js'; import { type Transport } from './transport.js'; /** A resolved remote canvas target — see `core/view/remote-canvas-target.ts` for how * this is assembled from config (`relayTokenRef`) plus the 0600 secrets store * via `resolveRemoteCanvasTarget`. This transport itself never takes the * token from argv — `canvas config add --relay-token -` is the only accepted * form for writing a token to the store — stdin-only, never argv; that is a * one-time config-write path, not this call. */ export interface RelayTarget { /** The preview endpoint origin, e.g. `https://.preview.bl.run`. */ previewEndpoint: string; /** The raw relay/bearer token. NEVER logged, NEVER echoed. */ relayToken: string; } export declare class RelayTransport extends EventEmitter implements Transport { private readonly nodeId; private readonly target; private ws; private closeEmitted; constructor(nodeId: string, target: RelayTarget); private get url(); private dial; connect(): void; /** Re-dial the SAME `wss:///node/` — the preview * endpoint is the stable anchor remotely, as `view.sock` is locally. */ redial(): Promise; send(frame: ClientToBroker): void; destroy(): void; private onMessage; private onError; /** WS close codes mirror the SAME semantics the browser relay client * (`clients/web/web-client/broker-client.ts`'s `onclose` / `src/web/ * transport-stream.ts`'s `classifyClose`): 1008 invalid id, or a 1011 whose * REASON starts with "no running broker"/"no node " (the relay's exact * wording — `src/clients/web/server.ts`), are the terminal "gone" signals — * surfaced as BrokerUnavailableError so the reconnect supervisor's normal * give-up path applies uniformly across transports. `fault-classifier.ts`'s * `classify` is consulted only for the 1008/protocol case (parity with the * browser client), NOT for 1011 — `classifyWsClose`'s 1011 case answers "is * this reason connection-shaped", the OPPOSITE question from "is the * broker/node gone", so branching on its `kind` here previously inverted * the gone/not-gone decision (a real bug caught by the mock-relay test, see * `transport-relay.test.ts`). Everything else (1006 abnormal, 1000 normal, * or an unrecognized 1011 reason) is a transient/expected drop the caller * may redial. */ private onClose; /** Emit `error` only when a listener exists — a bare EventEmitter `error` * with no listener throws, and this transport must never throw uncaught. */ private emitError; }