/** * Main-thread face of the transport worker. * * `WorkerMuxTransport` stands in for `MuxTransport` and `WorkerMuxChannel` for * `MuxChannel`, so callers see the shape they already use. What changes is * where the socket lives: in the worker, where a frame can arrive while this * thread is busy decoding and painting a half-megabyte surface frame. * * Channel ids are allocated here rather than in the worker. `createChannel` * has to hand a channel back synchronously, and the id prefixes every frame on * the wire, so it cannot wait for a round trip; the worker is told which id to * use and agrees by construction. */ import type { MuxWorkerOptions, MuxWorkerRequest } from "./mux-worker-protocol"; import type { BlitDebug, BlitTransport, BlitTransportMessage, ConnectionStatus } from "../types"; type MessageListener = (data: BlitTransportMessage) => void; type StatusListener = (status: ConnectionStatus) => void; /** A channel whose socket lives in the worker. */ declare class WorkerMuxChannel implements BlitTransport { private readonly owner; readonly channelId: number; readonly destName: string; private _status; private _authRejected; private _lastError; private readonly messageListeners; private readonly statusListeners; constructor(owner: WorkerMuxTransport, channelId: number, destName: string); get status(): ConnectionStatus; get authRejected(): boolean; get lastError(): string | null; connect(): void; reconnect(): void; send(data: Uint8Array): void; close(): void; suspend(): void; /** * Route this channel's audio frames straight to a decoder. * * Exposed on the channel so a consumer can opt in without knowing anything * about the worker behind it — `BlitConnection` owns the `AudioPlayer` and * feature-detects this, and a transport that has no worker simply does not * offer it. */ attachAudioPort(port: MessagePort): void; /** Send this channel's audio back through the main thread. */ detachAudioPort(): void; addEventListener(type: "message", listener: MessageListener): void; addEventListener(type: "statuschange", listener: StatusListener): void; removeEventListener(type: "message", listener: MessageListener): void; removeEventListener(type: "statuschange", listener: StatusListener): void; /** @internal */ _deliver(data: BlitTransportMessage): void; /** @internal */ _setStatus(status: ConnectionStatus, authRejected: boolean, lastError: string | null): void; } /** * Drop-in for `MuxTransport` that runs the real one in a worker. * * The surface is deliberately only what callers use — `connect`, * `createChannel`, `updateWtCertHash`, `close` — rather than a mirror of * every method, so there is no pretence of proxying behaviour that is not * exercised. */ export declare class WorkerMuxTransport { private readonly worker; private readonly debug?; private readonly channels; private nextChannelId; private closed; constructor(wsUrl: string, passphrase: string, options?: MuxWorkerOptions & { debug?: BlitDebug; }, /** Test seam: a worker environment is not available under jsdom, and the * routing this class exists for is worth testing without one. */ spawn?: () => Worker); /** * Hand the worker a port that reaches one channel's audio decoder directly. * * Without this an audio frame still waits for this thread to dispatch it, * which is the whole failure being fixed: the socket having moved does not * help audio if the last hop is still a main-thread callback. After this the * main thread sees only the six-byte header, which is all the AudioContext * lifecycle needs and cheap enough to arrive late. */ attachAudioPort(channelId: number, port: MessagePort): void; /** * Undo `attachAudioPort`: the decoder behind the port is gone, so the * worker must stop feeding it and let audio take the ordinary route. */ detachAudioPort(channelId: number): void; connect(): void; createChannel(destName: string): WorkerMuxChannel; updateWtCertHash(hexHash: string, wtUrl?: string): void; close(): void; /** @internal */ _send(request: MuxWorkerRequest, transfer?: Transferable[]): void; /** @internal */ _forget(channelId: number): void; private receive; } export type { WorkerMuxChannel }; //# sourceMappingURL=mux-proxy.d.ts.map