import { TheLink, Tunnel, type Serialize } from "@the-link/core"; import { WSContext } from "hono/ws"; /** * Per-connection WebSocket adapter for TheLink server subscriptions. * * Wraps a single accepted WebSocket connection with TheLink-compatible inbound * and outbound tunnels. Server code can use each connection Link to publish events to * one client and receive events from that client. * * Outbound events are serialized into `{ type: "message", data: [...] }` * envelopes using a simple `[event, ...values]` event tuple. * * @example * ```typescript * server.onSubscribe((socket) => { * socket.autoJoin(server) * socket.$inbound.subscribe("client:event", handleClientEvent) * }) * ``` */ export default class ServerSocket extends TheLink { /** * Internal tunnel for this socket's lifecycle events. * * Currently used to coordinate cleanup when the socket unsubscribes. */ readonly $internal: Tunnel; /** * Accepted WebSocket connection used for bidirectional transport. */ private readonly socket; /** * Client payload supplied during subscription establishment. */ readonly payload: Payload; /** * The HTTP request that opened this connection, as the client sent it: its URL and headers. */ readonly request: Request; private serialize; /** * Initialize the Server Link for one accepted WebSocket connection. * * The constructor stores the connection payload and forwards all outbound * tunnel events to the WebSocket publish handler. * * @param socket Accepted WebSocket context * @param payload Client payload supplied during subscription * @param request HTTP request that opened the connection */ constructor(socket: WSContext, payload: Payload, request: Request); /** * Configure the serialization function used for WebSocket payloads. * * @param serialize Custom function that converts values to bytes */ setSerialize(serialize: Serialize): void; /** * Connect another TheLink instance to this socket until it unsubscribes. * * Creates a forwarding relationship from the source link to this socket, then * registers cleanup on this socket's internal `unsubscribe` event. * * @param theLink Source link whose events should be forwarded * @param fromPrefix Source event prefix to match * @param toPrefix Destination event prefix to apply * @returns Function that manually disconnects forwarding and cleanup */ autoJoin(theLink: TheLink, fromPrefix?: string, toPrefix?: string): () => void; /** * Close the WebSocket subscription from the server side. * * @param code WebSocket close code * @param reason Close reason sent to the client */ unsubscribe(code?: number, reason?: string): void; /** * Send an outbound tunnel event to the client. * * @param event Event identifier sent to the client * @param values Event payload values sent to the client */ private publishHandler; }