import * as msg from './messages.js';
import { MessageTransport } from '../transport/transport.js';
import { Emitter, Event } from '../utils/event.js';
import { Deferred } from '../utils/promise.js';
import { Encryption } from './encryption.js';
export type Handler<P extends unknown[], R = void> = (origin: string, ...parameters: P) => (R | Promise<R>);
export type UnhandledMessageHandler = (origin: string, method: string, ...parameters: unknown[]) => any | Promise<any>;
export type ErrorHandler = (message: string) => void;
export interface BroadcastConnection {
    onRequest(type: string, handler: Handler<any[], any>): void;
    onRequest<P extends unknown[], R>(type: msg.RequestType<P, R>, handler: Handler<P, R>): void;
    onRequest(handler: UnhandledMessageHandler): void;
    onNotification(type: string, handler: Handler<any[]>): void;
    onNotification<P extends unknown[]>(type: msg.NotificationType<P>, handler: Handler<P>): void;
    onNotification(handler: UnhandledMessageHandler): void;
    onBroadcast(type: string, handler: Handler<any[]>): void;
    onBroadcast<P extends unknown[]>(type: msg.BroadcastType<P>, handler: Handler<P>): void;
    onBroadcast(handler: UnhandledMessageHandler): void;
    onError(handler: ErrorHandler): void;
    sendRequest(type: string, ...parameters: any[]): Promise<any>;
    sendRequest<P extends unknown[], R>(type: msg.RequestType<P, R>, ...parameters: P): Promise<R>;
    sendNotification(type: string, ...parameters: any[]): void;
    sendNotification<P extends unknown[]>(type: msg.NotificationType<P>, ...parameters: P): void;
    sendBroadcast(type: string, ...parameters: any[]): void;
    sendBroadcast<P extends unknown[]>(type: msg.BroadcastType<P>, ...parameters: P): void;
    dispose(): void;
    onDisconnect: Event<void>;
    onReconnect: Event<void>;
    onConnectionError: Event<string>;
}
export interface RelayedRequest {
    id: string | number;
    response: Deferred<any>;
    dispose(): void;
}
export interface AbstractBroadcastConnectionOptions {
    privateKey: string;
    transport: MessageTransport;
}
export declare abstract class AbstractBroadcastConnection implements BroadcastConnection {
    readonly options: AbstractBroadcastConnectionOptions;
    protected messageHandlers: Map<string, Handler<any[], any>>;
    protected onErrorEmitter: Emitter<string>;
    protected onDisconnectEmitter: Emitter<void>;
    protected onConnectionErrorEmitter: Emitter<string>;
    protected onReconnectEmitter: Emitter<void>;
    protected onUnhandledRequestHandler?: (method: string) => Handler<any[], any>;
    protected onUnhandledBroadcastHandler?: (method: string) => Handler<any[], any>;
    protected onUnhandledNotificationHandler?: (method: string) => Handler<any[], any>;
    get onError(): Event<string>;
    get onDisconnect(): Event<void>;
    get onReconnect(): Event<void>;
    get onConnectionError(): Event<string>;
    protected requestMap: Map<string | number, RelayedRequest>;
    protected requestId: number;
    protected symKey: Promise<string>;
    protected encryptionKeyCache: Record<string, string>;
    protected decryptionKeyCache: Record<string, string>;
    protected maxCacheSize: number;
    protected _ready: Deferred<void>;
    constructor(options: AbstractBroadcastConnectionOptions);
    dispose(): void;
    protected ready(): void;
    /**
     * Cleanup the encryption and decryption key caches if they exceed the maximum cache size.
     * This is to prevent memory leaks in case the cache grows due to symmetric key swapping
     * or many peers joining/leaving a room.
     */
    protected cleanupCaches(): void;
    protected handleMessage(data: Uint8Array): Promise<void>;
    protected abstract getPublicKey(origin: string | undefined): Encryption.AsymmetricKey;
    protected abstract getPublicKeys(): Encryption.AsymmetricKey[];
    protected abstract getPublicKeysLength(): number;
    private write;
    onRequest(handler: UnhandledMessageHandler): void;
    onRequest(type: string, handler: Handler<any[], any>): void;
    onRequest<P extends unknown[], R>(type: msg.RequestType<P, R> | string, handler: Handler<P, R>): void;
    onNotification(handler: UnhandledMessageHandler): void;
    onNotification(type: string, handler: Handler<any[]>): void;
    onNotification<P extends unknown[]>(type: msg.NotificationType<P> | string, handler: Handler<P>): void;
    onBroadcast(handler: UnhandledMessageHandler): void;
    onBroadcast(type: msg.BroadcastType<any[]> | string, handler: Handler<any[]>): void;
    onBroadcast(type: msg.BroadcastType<any[]> | string, handler: Handler<any[]>): void;
    sendRequest(type: string, target: msg.MessageTarget, ...parameters: any[]): Promise<any>;
    sendRequest<P extends unknown[], R>(type: msg.RequestType<P, R> | string, target: msg.MessageTarget, ...parameters: P): Promise<R>;
    sendNotification(type: string, target: msg.MessageTarget, ...parameters: any[]): Promise<void>;
    sendNotification<P extends unknown[]>(type: msg.NotificationType<P>, target: msg.MessageTarget, ...parameters: P): Promise<void>;
    sendBroadcast(type: string, ...parameters: any[]): Promise<void>;
    sendBroadcast<P extends unknown[]>(type: msg.BroadcastType<P>, ...parameters: P): Promise<void>;
}
//# sourceMappingURL=abstract-connection.d.ts.map