import { TheLink, Tunnel, type Deserialize, type Serialize, type Subscriber } from "@the-link/core"; import ClientSocket from "./client-socket.js"; import { ClientStreams } from "./streams.js"; /** * How long to wait before reconnecting after `failures` attempts in a row closed before the server * accepted them: the first delay after an accepted connection, doubling with each failure. */ export declare function reconnectDelay(failures: number): number; /** * Client adapter for TheLink over HTTP publishing and WebSocket subscriptions. * * For outbound events, HttpClient forwards the outbound tunnel to the server's * POST `/publish` endpoint. For subscriptions, it opens a WebSocket connection * to `/subscribe`, waits for the server's subscribe envelope, then exposes the * connection as a client-side Link. Recoverable WebSocket closures trigger * a delayed resubscribe with the original connection payload: one second * after an accepted connection closes, and twice as long after each attempt * in a row that closes before it is accepted, up to thirty seconds. * * The adapter uses UTF-8 JSON bytes by default, with hooks for custom codecs * that must match the corresponding HttpServer. * * @example * ```typescript * const client = new HttpClient("https://api.example.com/events") * * const socket = await client.subscribeAsync<{ userId: string }>({ token }) * * socket.$inbound.subscribe("server:event", handleServerEvent) * await client.$outbound.publish("client:event", payload) * ``` */ export declare class HttpClient extends TheLink { /** * Internal tunnel for client-side connection lifecycle events. * * Publishes `subscribe` when a WebSocket is accepted and `unsubscribe` when * a tracked socket closes. UUID-scoped `subscribe:` and * `unsubscribe:` events are also published so individual async * subscription calls can resolve or reject their own connection. */ readonly $internal: Tunnel; /** * Server base URL used to construct `/publish` and `/subscribe` endpoints. */ private readonly url; private serialize; private deserialize; /** * Active WebSocket-backed Links keyed by connection UUID. */ readonly sockets: Map; /** * Streams crossing this client's messages as references, with their chunks on their own requests. */ readonly streams: ClientStreams; /** * Initialize an HttpClient for an HttpServer base URL. * * @param url Server base URL that exposes `/publish` and `/subscribe` */ constructor(url: string); /** * Configure the serialization function used for HTTP and WebSocket payloads. * * @param serialize Custom function that converts values to bytes */ setSerialize(serialize: Serialize): void; /** * Configure the deserialization function used for HTTP and WebSocket payloads. * * @param deserialize Custom function that parses values from bytes */ setDeserialize(deserialize: Deserialize): void; /** * Register a handler for successful WebSocket subscriptions. * * @param subscriber Handler invoked with each accepted Link * @returns Function that removes this subscriber */ onSubscribe(subscriber: Subscriber<[ClientSocket]>): () => void; /** * Open a WebSocket subscription to the server. * * The connection payload is serialized and encoded into the `payload` query parameter. * When the server responds with a `subscribe` envelope, this client creates a * Link and publishes it on the internal `subscribe` event plus the * UUID-scoped `subscribe:` event. * * @param payload Optional connection payload sent to the server * @returns Connection UUID used for socket tracking and scoped lifecycle events */ subscribe(payload?: unknown): string; /** * Open one WebSocket subscription attempt. * * @param payload Connection payload sent to the server * @param failures Attempts in a row before this one that closed before they were accepted * @returns Connection UUID used for socket tracking and scoped lifecycle events */ private connect; /** * Open a WebSocket subscription and resolve with its Link. * * Resolves when this subscription's UUID-scoped `subscribe:` event is * published. Rejects if `unsubscribe:` is published before the * subscription succeeds. * * @param payload Optional connection payload sent to the server * @returns Link created from the server subscription response * @throws Error when the socket closes before subscription completes */ subscribeAsync(payload?: unknown): Promise>; /** * Publish an outbound event to the server through HTTP POST. * * Automatically invoked by outbound tunnel forwarding configured in the * constructor. * * @param event Event identifier routed on the server * @param values Event payload values sent to the server * @returns Deserialized server handler results * @throws Error when the server returns a non-successful response */ private publishHandler; /** * Handle the server's WebSocket subscribe envelope. * * A `subscribe` message creates the client-side Link for this * connection, configures matching serialization, and publishes the internal * `subscribe` event for application code. It also publishes * `subscribe:` for the specific subscribeAsync() call that opened this * socket. * * @param event WebSocket message containing the serialized subscribe envelope * @param socket Browser WebSocket instance for this connection * @param uuid Connection identifier used for socket tracking */ private webSocketMessageHandler; /** * Clean up a closed WebSocket subscription and reconnect when recoverable. * * Publishes the socket-level unsubscribe event before removing the Link * from the active map, then publishes `unsubscribe:` for callers * waiting on that specific subscription. Recoverable close codes open a new * subscription with the original payload: soon after an accepted connection * closes, and later after each attempt in a row that closed before it was accepted. * * @param event Browser WebSocket close event * @param payload Original connection payload used for reconnect attempts * @param uuid Connection identifier used to find the Link * @param failures Attempts in a row before this one that closed before they were accepted */ private webSocketCloseHandler; }