import WebSocket, { ClientOptions, RawData } from 'ws';
import { EndpointContext } from '../adapter';
import { ProviderResult } from '../util/types';
import { TypeFromDefinition } from '../validation/input-params';
import { TransportGenerics } from './';
import { StreamingTransport, SubscriptionDeltas } from './abstract/streaming';
export { WebSocket, RawData as WebSocketRawData };
type WebSocketClass = new (url: string, protocols?: string | string[] | undefined, options?: ClientOptions) => WebSocket;
export declare class WebSocketClassProvider {
    static ctor: WebSocketClass;
    static set(ctor: WebSocketClass): void;
    static get(): WebSocketClass;
}
/**
 * Config object that is provided to the WebSocketTransport constructor.
 */
export interface WebSocketTransportConfig<T extends WebsocketTransportGenerics> {
    /** Endpoint to which to open the WS connection*/
    url: (context: EndpointContext<T>, desiredSubs: TypeFromDefinition<T['Parameters']>[]) => Promise<string> | string;
    /** Optional parameters used when establishing the WebSocket connection */
    options?: (context: EndpointContext<T>, desiredSubs: TypeFromDefinition<T['Parameters']>[]) => Promise<ClientOptions> | ClientOptions;
    /** Map of handlers for different WS lifecycle events */
    handlers: {
        /**
         * Handles when the WS is successfully opened.
         * Optional since logic is not always needed on connection.
         * Note: any listeners set in this method will be cleared after its execution.
         *
         * @param wsConnection - the WebSocket with an established connection
         * @returns an empty Promise, or void
         */
        open?: (wsConnection: WebSocket, context: EndpointContext<T>) => Promise<void> | void;
        /**
         * Handles when the websocket connection dispatches an error event
         * Optional to let the adapter handle the event in its own way if it decides to
         *
         * @param errorEvent - the WebSocket error event
         * @param context - the background context for the Adapter
         * @returns void
         */
        error?: (errorEvent: WebSocket.ErrorEvent, context: EndpointContext<T>) => void;
        /**
         * Handles when the websocket connection dispatches a close event
         * Optional to let the adapter handle the event in its own way if it decides to
         *
         * @param closeEvent - the WebSocket close event
         * @param context - the background context for the Adapter
         * @returns void
         */
        close?: (closeEvent: WebSocket.CloseEvent, context: EndpointContext<T>) => void;
        /**
         * Handles when the WS receives a message
         *
         * @param message - the message received by the WS
         * @param context - the background context for the Adapter
         * @returns a list of cache entries of adapter responses to set in the cache
         */
        message: (message: T['Provider']['WsMessage'], context: EndpointContext<T>) => ProviderResult<T>[] | undefined;
    };
    /** Map of "builders", functions that will be used to prepare specific WS messages */
    builders?: {
        /**
         * Builds a WS message that will be sent to subscribe to a specific feed
         *
         * @param params - the body of the adapter request
         * @param context - the background context for the Adapter
         * @returns the WS message (can be any type as long as the [[WebSocket]] doesn't complain)
         */
        subscribeMessage?: (params: TypeFromDefinition<T['Parameters']>, context: EndpointContext<T>) => unknown;
        /**
         * Builds a WS message that will be sent to unsubscribe to a specific feed
         *
         * @param params - the body of the adapter request
         * @param context - the background context for the Adapter
         * @returns the WS message (can be any type as long as the [[WebSocket]] doesn't complain)
         */
        unsubscribeMessage?: (params: TypeFromDefinition<T['Parameters']>, context: EndpointContext<T>) => unknown;
    };
}
/**
 * Helper struct type that will be used to pass types to the generic parameters of a Transport.
 * Extends the common TransportGenerics, adding Provider specific types for this WS endpoint.
 */
export type WebsocketTransportGenerics = TransportGenerics & {
    /**
     * Type details for any provider specific interfaces.
     */
    Provider: {
        /**
         * Structure of any message that will come through the websocket connection.
         */
        WsMessage: unknown;
    };
};
/**
 * Transport implementation that takes incoming requests, adds them to an [[subscriptionSet]] and,
 * through a WebSocket connection, subscribes to the relevant feeds to populate the cache.
 *
 * @typeParam T - Helper struct type that will be used to pass types to the generic parameters (check [[WebsocketTransportGenerics]])
 */
export declare class WebSocketTransport<T extends WebsocketTransportGenerics> extends StreamingTransport<T> {
    private config;
    wsConnection?: WebSocket;
    currentUrl: string;
    lastMessageReceivedAt: number;
    connectionOpenedAt: number;
    constructor(config: WebSocketTransportConfig<T>);
    getSubscriptionTtlFromConfig(adapterSettings: T['Settings']): number;
    connectionClosed(): boolean;
    serializeMessage(payload: unknown): string;
    deserializeMessage(data: WebSocket.Data): T['Provider']['WsMessage'];
    buildConnectionHandlers(context: EndpointContext<T>, connection: WebSocket, connectionReadyResolve: (value: WebSocket) => void): {
        open: (event: WebSocket.Event) => Promise<void>;
        message: (event: WebSocket.MessageEvent) => Promise<void>;
        error: (event: WebSocket.ErrorEvent) => Promise<void>;
        close: (event: WebSocket.CloseEvent) => void;
    };
    establishWsConnection(context: EndpointContext<T>, url: string, options?: WebSocket.ClientOptions | undefined): Promise<WebSocket>;
    sendMessages(context: EndpointContext<T>, subscribes: unknown[], unsubscribes: unknown[]): Promise<void>;
    streamHandler(context: EndpointContext<T>, subscriptions: SubscriptionDeltas<TypeFromDefinition<T['Parameters']>>): Promise<void>;
    private rejectionHandler;
}
/**
 * Transport that wraps the WebSocketTransport in order to provide helper methods for a reverse mapping. This is useful
 * when the Data Provider uses pair IDs that cannot be programmatically translated into request params.
 *
 * Example with `{from: "STETH", to: "USD"} -> "STETHUSD"`:
 * Instead of trying to split the Data Provider ID string based on length, we can use
 * `setReverseMapping("STETHUSD", {from: "STETH", to: "USD"})` to map the Data Provider ID to the request payload, then
 * use `getReverseMapping("STETHUSD")` to get the right input parameters.
 *
 * @typeParam T - Helper struct type that will be used to pass types to the generic parameters (check [[WebsocketTransportGenerics]])
 * @typeParam K - The type for the Data Provider's IDs
 */
export declare class WebsocketReverseMappingTransport<T extends WebsocketTransportGenerics, K> extends WebSocketTransport<T> {
    private requestMapping;
    /**
     * Sets the request params mapping for the given value
     *
     * @param value - the Data Provider lookup value to map to `params`
     * @param params - the body of the adapter request
     * @returns the WS message (can be any type as long as the [[WebSocket]] doesn't complain)
     */
    setReverseMapping(value: K, params: TypeFromDefinition<T['Parameters']>): void;
    /**
     * Gets the request params mapping for the given value
     *
     * @param value - the Data Provider lookup value
     * @returns the request parameters for the Data Provider lookup value, if one has been set
     */
    getReverseMapping(value: K): TypeFromDefinition<T['Parameters']> | undefined;
}
