import type { LogLevel } from '../types';
import type { UserRequest } from '../../gen/models';
import { TokenManager } from '../TokenManager';
import { ConnectionIdManager } from '../ConnectionIdManager';
import { ConnectedEvent } from './event-models';
export type WSConfig = {
    baseUrl: string;
    user: UserRequest;
};
type WSError = Error & {
    code?: string | number;
    isWSFailure?: boolean;
    StatusCode?: string | number;
};
/**
 * StableWSConnection - A WS connection that reconnects upon failure.
 * - the browser will sometimes report that you're online or offline
 * - the WS connection can break and fail (there is a 30s health check)
 * - sometimes your WS connection will seem to work while the user is in fact offline
 * - to speed up online/offline detection you can use the window.addEventListener('offline');
 *
 * There are 4 ways in which a connection can become unhealthy:
 * - websocket.onerror is called
 * - websocket.onclose is called
 * - the health check fails and no event is received for ~40 seconds
 * - the browser indicates the connection is now offline
 *
 * There are 2 assumptions we make about the server:
 * - state can be recovered by querying the channel again
 * - if the servers fails to publish a message to the client, the WS connection is destroyed
 */
export declare class StableWSConnection {
    private readonly config;
    private readonly tokenManager;
    private readonly connectionIdManager;
    private readonly decoders;
    connectionID?: string;
    connectionOpen?: Promise<ConnectedEvent>;
    authenticationSent: boolean;
    consecutiveFailures: number;
    pingInterval: number;
    healthCheckTimeoutRef?: NodeJS.Timeout;
    isConnecting: boolean;
    isDisconnected: boolean;
    isHealthy: boolean;
    isResolved?: boolean;
    lastEvent: Date | null;
    connectionCheckTimeout: number;
    connectionCheckTimeoutRef?: NodeJS.Timeout;
    rejectPromise?: (reason?: WSError) => void;
    requestID: string | undefined;
    resolvePromise?: (value: ConnectedEvent) => void;
    totalFailures: number;
    ws?: WebSocket;
    wsID: number;
    private readonly dispatcher;
    private readonly clientId;
    constructor(config: WSConfig, tokenManager: TokenManager, connectionIdManager: ConnectionIdManager, decoders?: Array<(event: any) => any>);
    _log: (msg: string, extra?: any, level?: LogLevel) => void;
    on: (eventName: "network.changed" | "all" | "app.updated" | "feeds.activity.added" | "feeds.activity.deleted" | "feeds.activity.marked" | "feeds.activity.pinned" | "feeds.activity.reaction.added" | "feeds.activity.reaction.deleted" | "feeds.activity.reaction.updated" | "feeds.activity.removed_from_feed" | "feeds.activity.unpinned" | "feeds.activity.updated" | "feeds.bookmark.added" | "feeds.bookmark.deleted" | "feeds.bookmark.updated" | "feeds.bookmark_folder.deleted" | "feeds.bookmark_folder.updated" | "feeds.comment.added" | "feeds.comment.deleted" | "feeds.comment.reaction.added" | "feeds.comment.reaction.deleted" | "feeds.comment.reaction.updated" | "feeds.comment.updated" | "feeds.feed.created" | "feeds.feed.deleted" | "feeds.feed.updated" | "feeds.feed_group.changed" | "feeds.feed_group.deleted" | "feeds.feed_member.added" | "feeds.feed_member.removed" | "feeds.feed_member.updated" | "feeds.follow.created" | "feeds.follow.deleted" | "feeds.follow.updated" | "feeds.notification_feed.updated" | "feeds.poll.closed" | "feeds.poll.deleted" | "feeds.poll.updated" | "feeds.poll.vote_casted" | "feeds.poll.vote_changed" | "feeds.poll.vote_removed" | "health.check" | "user.updated" | "moderation.custom_action" | "moderation.flagged" | "moderation.mark_reviewed" | "user.banned" | "user.deactivated" | "user.muted" | "user.reactivated" | "connection.changed", handler: (event: import("../../types").FeedsEvent) => void) => () => void;
    off: (eventName: "network.changed" | "all" | "app.updated" | "feeds.activity.added" | "feeds.activity.deleted" | "feeds.activity.marked" | "feeds.activity.pinned" | "feeds.activity.reaction.added" | "feeds.activity.reaction.deleted" | "feeds.activity.reaction.updated" | "feeds.activity.removed_from_feed" | "feeds.activity.unpinned" | "feeds.activity.updated" | "feeds.bookmark.added" | "feeds.bookmark.deleted" | "feeds.bookmark.updated" | "feeds.bookmark_folder.deleted" | "feeds.bookmark_folder.updated" | "feeds.comment.added" | "feeds.comment.deleted" | "feeds.comment.reaction.added" | "feeds.comment.reaction.deleted" | "feeds.comment.reaction.updated" | "feeds.comment.updated" | "feeds.feed.created" | "feeds.feed.deleted" | "feeds.feed.updated" | "feeds.feed_group.changed" | "feeds.feed_group.deleted" | "feeds.feed_member.added" | "feeds.feed_member.removed" | "feeds.feed_member.updated" | "feeds.follow.created" | "feeds.follow.deleted" | "feeds.follow.updated" | "feeds.notification_feed.updated" | "feeds.poll.closed" | "feeds.poll.deleted" | "feeds.poll.updated" | "feeds.poll.vote_casted" | "feeds.poll.vote_changed" | "feeds.poll.vote_removed" | "health.check" | "user.updated" | "moderation.custom_action" | "moderation.flagged" | "moderation.mark_reviewed" | "user.banned" | "user.deactivated" | "user.muted" | "user.reactivated" | "connection.changed", handler: (event: import("../../types").FeedsEvent) => void) => void;
    offAll: (eventName?: "network.changed" | "all" | "app.updated" | "feeds.activity.added" | "feeds.activity.deleted" | "feeds.activity.marked" | "feeds.activity.pinned" | "feeds.activity.reaction.added" | "feeds.activity.reaction.deleted" | "feeds.activity.reaction.updated" | "feeds.activity.removed_from_feed" | "feeds.activity.unpinned" | "feeds.activity.updated" | "feeds.bookmark.added" | "feeds.bookmark.deleted" | "feeds.bookmark.updated" | "feeds.bookmark_folder.deleted" | "feeds.bookmark_folder.updated" | "feeds.comment.added" | "feeds.comment.deleted" | "feeds.comment.reaction.added" | "feeds.comment.reaction.deleted" | "feeds.comment.reaction.updated" | "feeds.comment.updated" | "feeds.feed.created" | "feeds.feed.deleted" | "feeds.feed.updated" | "feeds.feed_group.changed" | "feeds.feed_group.deleted" | "feeds.feed_member.added" | "feeds.feed_member.removed" | "feeds.feed_member.updated" | "feeds.follow.created" | "feeds.follow.deleted" | "feeds.follow.updated" | "feeds.notification_feed.updated" | "feeds.poll.closed" | "feeds.poll.deleted" | "feeds.poll.updated" | "feeds.poll.vote_casted" | "feeds.poll.vote_changed" | "feeds.poll.vote_removed" | "health.check" | "user.updated" | "moderation.custom_action" | "moderation.flagged" | "moderation.mark_reviewed" | "user.banned" | "user.deactivated" | "user.muted" | "user.reactivated" | "connection.changed" | undefined) => void;
    /**
     * connect - Connect to the WS URL
     * the default 15s timeout allows between 2~3 tries
     * @return {ConnectAPIResponse<ConnectedEvent>} Promise that completes once the first health check message is received
     */
    connect(timeout?: number): Promise<ConnectedEvent | undefined>;
    /**
     * _waitForHealthy polls the promise connection to see if its resolved until it times out
     * the default 15s timeout allows between 2~3 tries
     * @param timeout duration(ms)
     */
    _waitForHealthy(timeout?: number): Promise<ConnectedEvent | undefined>;
    /**
     * disconnect - Disconnect the connection and doesn't recover...
     *
     */
    disconnect(timeout?: number): Promise<void>;
    /**
     * _connect - Connect to the WS endpoint
     *
     * @return {ConnectAPIResponse<ConnectedEvent>} Promise that completes once the first health check message is received
     */
    _connect(): Promise<ConnectedEvent | undefined>;
    /**
     * _reconnect - Retry the connection to WS endpoint
     *
     * @param {{ interval?: number; refreshToken?: boolean }} options Following options are available
     *
     * - `interval`	{int}			number of ms that function should wait before reconnecting
     * - `refreshToken` {boolean}	reload/refresh user token be refreshed before attempting reconnection.
     */
    _reconnect(options?: {
        interval?: number;
        refreshToken?: boolean;
    }): Promise<void>;
    /**
     * onlineStatusChanged - this function is called when the browser connects or disconnects from the internet.
     *
     * @param {Event} event Event with type online or offline
     *
     */
    onlineStatusChanged: (event: Event) => void;
    onopen: (wsID: number) => Promise<void>;
    onmessage: (wsID: number, event: MessageEvent) => void;
    onclose: (wsID: number, event: CloseEvent) => void;
    onerror: (wsID: number, event: Event) => void;
    /**
     * _setHealth - Sets the connection to healthy or unhealthy.
     * Broadcasts an event in case the connection status changed.
     *
     * @param {boolean} healthy boolean indicating if the connection is healthy or not
     * @param {boolean} dispatchImmediately boolean indicating to dispatch event immediately even if the connection is unhealthy
     *
     */
    _setHealth: (healthy: boolean, dispatchImmediately?: boolean) => void;
    dispatchConnectionChanged: () => void;
    /**
     * _errorFromWSEvent - Creates an error object for the WS event
     *
     */
    _errorFromWSEvent: (event: CloseEvent | Event | ErrorEvent, isWSFailure?: boolean) => WSError;
    /**
     * _destroyCurrentWSConnection - Removes the current WS connection
     *
     */
    _destroyCurrentWSConnection(): void;
    /**
     * _setupPromise - sets up the this.connectOpen promise
     */
    _setupConnectionPromise: () => void;
    /**
     * Schedules a next health check ping for websocket.
     */
    scheduleNextPing: () => void;
    /**
     * scheduleConnectionCheck - schedules a check for time difference between last received event and now.
     * If the difference is more than 35 seconds, it means our health check logic has failed and websocket needs
     * to be reconnected.
     */
    scheduleConnectionCheck: () => void;
}
export {};
