import { S as SockaContractBound, a as SockaWireFormat, p as SockaServerResponseFrame, n as SockaServerErrorFrame, o as SockaServerEventFrame, d as InferSockaSend, c as InferSockaPushPayload, b as InferSockaPushHandlers, m as SockaReportError } from '../socka-report-error-BALZPjd1.js';
export { B as reportSockaError } from '../socka-report-error-BALZPjd1.js';
import '@standard-schema/spec';

interface SockaWebSocketClientOptions<TContract extends SockaContractBound> {
    contract: TContract;
    /** Default `"json"` (text frames). Use `"msgpack"` for binary `ArrayBuffer` frames. */
    wireFormat?: SockaWireFormat;
    url?: string;
    webSocket?: WebSocket;
    /**
     * When `false`, the socket is not created until {@link SockaWebSocketClient.connect}
     * (or the first operation that implicitly opens, e.g. {@link SockaSession} `send`).
     * Default `true`.
     */
    autoConnect?: boolean;
    serializeJson?: (value: unknown) => string;
    deserializeJson?: (raw: string) => unknown;
    onOpen?: (event: Event) => void;
    onClose?: (event: CloseEvent) => void;
    onError?: (event: Event) => void;
    onResponse?: (frame: SockaServerResponseFrame) => void;
    onServerError?: (frame: SockaServerErrorFrame) => void;
    onEvent?: (frame: SockaServerEventFrame) => void;
    onValidationError?: (error: Error, rawMessage: unknown) => void;
    /**
     * Automatic reconnect after an abnormal close. **Disabled by default** when
     * {@link webSocket} is injected (tests); enabled when using {@link url}.
     * Pass `false` to disable.
     */
    reconnect?: false | SockaReconnectConfig;
    /** Fired before a reconnect attempt is scheduled (after delay is chosen). */
    onReconnecting?: (info: SockaReconnectingInfo) => void;
    /** Fired after a new socket reaches `open` following a reconnect. */
    onReconnected?: (info: SockaReconnectedInfo) => void;
}
/** Options for {@link SockaWebSocketClientOptions.reconnect}. */
type SockaReconnectConfig = {
    /** Default `1000`. */
    initialDelayMs?: number;
    /** Default `30000`. */
    maxDelayMs?: number;
    /** 0–1 fraction of delay to randomize. Default `0.2`. */
    jitter?: number;
    /** Omit for infinite attempts. */
    maxAttempts?: number;
    /**
     * When `true` (default), delay reconnect until `document` is visible again.
     */
    pauseWhenHidden?: boolean;
};
type SockaReconnectingInfo = {
    attempt: number;
    delayMs: number;
};
type SockaReconnectedInfo = {
    attempt: number;
};
/** High-level connection lifecycle for UI and telemetry. */
type SockaConnectionStatus = "idle" | "connecting" | "open" | "reconnecting" | "closed";
/**
 * Browser WebSocket client driven by a socka contract. Sends client request
 * frames and dispatches decoded server frames to callbacks.
 */
declare class SockaWebSocketClient<TContract extends SockaContractBound> {
    private ws;
    private readonly opts;
    private readonly wireFormat;
    private readonly serializeJson;
    private readonly deserializeJson;
    private readonly onResponseCb?;
    private readonly onServerErrorCb?;
    private readonly onEventCb?;
    private readonly onValidationError?;
    readonly contract: TContract;
    private manualClose;
    private reconnectAttempt;
    private reconnectTimer;
    private _status;
    private readonly statusListeners;
    constructor(options: SockaWebSocketClientOptions<TContract>);
    private setStatus;
    /** Current connection lifecycle state. */
    get status(): SockaConnectionStatus;
    /**
     * Subscribe to {@link status} changes. The listener is called immediately with the
     * current status, then on every transition. Returns an unsubscribe function.
     */
    onStatusChange(listener: (status: SockaConnectionStatus) => void): () => void;
    private createSocket;
    private attachSocket;
    private getReconnectEnabled;
    private resolveReconnectConfig;
    private computeReconnectDelayMs;
    private maybeScheduleReconnect;
    private openReplacementSocket;
    private handleMessageEvent;
    /**
     * Creates the WebSocket (when {@link SockaWebSocketClientOptions.autoConnect}
     * was `false`) and waits until the connection is open.
     */
    connect(): Promise<void>;
    sendRequest(id: string, rpc: string, body: Record<string, unknown>): void;
    close(code?: number, reason?: string): void;
    get readyState(): number;
    get socket(): WebSocket;
    waitForOpen(): Promise<void>;
}

type SockaSessionPushWaitOptions<TContract extends SockaContractBound, K extends keyof TContract["pushes"] & string> = {
    signal?: AbortSignal;
    timeoutMs?: number;
    predicate?: (payload: InferSockaPushPayload<TContract, K>) => boolean;
};
type SockaSessionSubscribeApi<TContract extends SockaContractBound> = {
    on<K extends keyof TContract["pushes"] & string>(name: K, handler: (payload: InferSockaPushPayload<TContract, K>) => void | Promise<void>): void;
    off<K extends keyof TContract["pushes"] & string>(name: K, handler: (payload: InferSockaPushPayload<TContract, K>) => void | Promise<void>): void;
    once<K extends keyof TContract["pushes"] & string>(name: K, handler: (payload: InferSockaPushPayload<TContract, K>) => void | Promise<void>): void;
    waitForPush<K extends keyof TContract["pushes"] & string>(name: K, options?: SockaSessionPushWaitOptions<TContract, K>): Promise<InferSockaPushPayload<TContract, K>>;
};
type SockaSessionOptions<TContract extends SockaContractBound> = Omit<SockaWebSocketClientOptions<TContract>, "onResponse" | "onServerError" | "onEvent"> & {
    onOpen?: (event: Event) => void;
    onClose?: (event: CloseEvent) => void;
    onError?: (event: Event) => void;
    pushHandlers?: Partial<InferSockaPushHandlers<TContract>>;
    /**
     * Optional sink for client-side push pipeline failures (listener throws,
     * push payload validation). Defaults to `console.error`; see
     * `SockaReportError` in `@firtoz/socka/core`.
     */
    reportError?: (event: SockaReportError) => void;
};
/**
 * Browser WebSocket session: **`session.send`** for contract calls, **`session.subscribe`**
 * for server pushes, **`session.client`** for low-level wire access.
 */
declare class SockaSessionBase<TContract extends SockaContractBound> {
    readonly client: SockaWebSocketClient<TContract>;
    readonly send: InferSockaSend<TContract>;
    readonly subscribe: SockaSessionSubscribeApi<TContract>;
    private readonly pending;
    private idSeq;
    private readonly pushListeners;
    private readonly reportError?;
    constructor(options: SockaSessionOptions<TContract>);
    private createSubscribeApi;
    private addPushListener;
    private removePushListener;
    private waitForPushImpl;
    private buildSendMethods;
    private call;
    private handleResponse;
    private handleServerError;
    private handleEvent;
    private dispatchValidatedPush;
    private nextId;
    rejectAllPending(reason: Error): void;
    close(code?: number, reason?: string): void;
    /** Opens the WebSocket when using {@link SockaWebSocketClientOptions.autoConnect} `false`. */
    connect(): Promise<void>;
    /** Same as {@link SockaWebSocketClient.status}. */
    get status(): SockaConnectionStatus;
    /** Same as {@link SockaWebSocketClient.onStatusChange}. */
    onStatusChange(listener: (status: SockaConnectionStatus) => void): () => void;
}
interface SockaSessionConstructor {
    new <TContract extends SockaContractBound>(options: SockaSessionOptions<TContract>): SockaSession<TContract>;
}
type SockaSession<TContract extends SockaContractBound> = SockaSessionBase<TContract>;
/**
 * WebSocket session: **`session.send`** for contract calls, **`session.subscribe`** for server pushes.
 */
declare const SockaSession: SockaSessionConstructor;

export { type SockaConnectionStatus, type SockaReconnectConfig, type SockaReconnectedInfo, type SockaReconnectingInfo, SockaReportError, SockaSession, type SockaSessionConstructor, type SockaSessionOptions, type SockaSessionPushWaitOptions, type SockaSessionSubscribeApi, SockaWebSocketClient, type SockaWebSocketClientOptions };
