import WebSocket from 'isomorphic-ws';
import { type ISocketClient, type MethodHandler, type MethodHandlers, type RequestContextBase, type SocketTimeouts, type GenericMiddleware } from './types.js';
interface SocketRequest<Payload = unknown> {
    method: string;
    payload: Payload;
    id: number;
    setAuthorization?: string;
    traceparent?: string;
    tracestate?: string;
}
interface SocketResponse<Payload = unknown> {
    id: number;
    payload: Payload;
    error: SocketError | null;
}
export interface SocketMessage<RequestPayload = unknown, ResponsePayload = unknown> {
    request?: SocketRequest<RequestPayload>;
    response?: SocketResponse<ResponsePayload>;
}
export interface SocketError {
    message: string;
    code: number;
    stack?: string;
}
export declare const INTENTIONAL_CLOSE_CODE = 4001;
/**
 * ISocket is a class that wraps a WebSocket connection and provides a simple interface for sending and receiving messages.
 * ISocket is initialized by both server and client and request/response is called symmetrically.
 *
 * ISocket handles has two timeout actions:
 * 1. Connection timeout: If the connection is not closed after a certain time, the connection is closed.
 *  - This is useful to prevent a connection from being open indefinitely. This is mainly used in the server side since
 *    the client side manages connection lifecycle manually.
 * 2. No response timeout: If the response is not received after a certain time, the request is timed out.
 *  - This is mainly used by CLI to handle the case where the server is not responding.
 *
 * It is expected that timeouts should be relatively sorted in the order of connection timeout > request timeout > no response timeout.
 */
export declare class ISocket<ImplementedMethods, CallableMethods, RequestContext extends RequestContextBase> {
    private readonly ws;
    private readonly requestHandlers;
    private readonly globalMiddlewares;
    private readonly responseHandler;
    private peerAuthorization?;
    protected nxtRequestId: number;
    private connectionTimeout;
    protected logger: {
        error: (message?: string) => void;
        info: (message?: string) => void;
        warn: (message?: string) => void;
    };
    private timeouts?;
    private isClosed;
    constructor(ws: WebSocket, requestHandlers: MethodHandlers<ImplementedMethods, CallableMethods, RequestContext>, globalMiddlewares: GenericMiddleware<CallableMethods, RequestContext>[], options: {
        /**
         * This callback is called when the WebSocket connection is closed,
         * either with a close handshake or immediately if the connection is dropped
         *
         * If code is INTENTIONAL_CLOSE_CODE, it was closed due to an internal timeout.
         * Otherwise, the other side closed the connection.
         *
         * @param event - The WebSocket.CloseEvent object.
         */
        onClose: (event: WebSocket.CloseEvent) => void;
        timeouts?: SocketTimeouts;
        logger?: {
            error: (message?: string) => void;
            info: (message?: string) => void;
            warn: (message?: string) => void;
        };
    });
    protected handleMessage(message: SocketMessage): Promise<void>;
    protected callHandler<Params, Result, CallableMethods, RequestContext extends RequestContextBase>(handler: MethodHandler<Params, Result, CallableMethods, RequestContext>, params: Params, ctx: RequestContext, client: ISocketClient<CallableMethods>, next: () => Promise<Result>): Promise<Result>;
    request<Params, Result>(method: string, params: Params, authorization?: string): Promise<Result>;
    requestWithTracing<Params, Result>(method: string, params: Params, tracingHeaders: {
        traceparent?: string;
        tracestate?: string;
    }, authorization?: string): Promise<Result>;
    protected decorateToSend(message: SocketMessage): SocketMessage;
    protected respond<Result>(requestId: number, result: Result): void;
    protected respondError(requestId: number, error: SocketError, exception?: Error): void;
    private resetConnectionTimeout;
    private handleConnectionTimeout;
    private resetNoResponseTimeout;
    private handleNoResponseTimeout;
    close(reason?: string): void;
    closeAndRejectPendingRequests(reason?: string): void;
}
export declare function createISocketClient<CallableMethods, ImplementedMethods, RequestContext extends RequestContextBase>(socket: ISocket<ImplementedMethods, CallableMethods, RequestContext>): ISocketClient<CallableMethods>;
export {};
//# sourceMappingURL=socket.d.ts.map