import { type InferState, type NormalizeRoomType, type ExtractRoomMessages, type ExtractRoomClientMessages, type ExtractMessageType } from '@colyseus/shared-types';
import { Schema } from '@colyseus/schema';
import { Packr } from '@colyseus/msgpackr';
import { Connection } from './Connection.ts';
import { Serializer } from './serializer/Serializer.ts';
import { SchemaConstructor, SchemaSerializer } from './serializer/SchemaSerializer.ts';
export type InferSerializer<State> = [State] extends [Schema] ? SchemaSerializer<State> : Serializer<State>;
export interface RoomAvailable<Metadata = any> {
    name: string;
    roomId: string;
    clients: number;
    maxClients: number;
    metadata?: Metadata;
}
export interface ReconnectionOptions {
    /**
     * Whether automatic reconnection is enabled.
     * Set to `false` to disable automatic reconnection entirely.
     * @default true
     */
    enabled: boolean;
    /**
     * The maximum number of reconnection attempts.
     */
    maxRetries: number;
    /**
     * The minimum delay between reconnection attempts.
     */
    minDelay: number;
    /**
     * The maximum delay between reconnection attempts.
     */
    maxDelay: number;
    /**
     * The minimum uptime of the room before reconnection attempts can be made.
     */
    minUptime: number;
    /**
     * The current number of reconnection attempts.
     */
    retryCount: number;
    /**
     * The initial delay between reconnection attempts.
     */
    delay: number;
    /**
     * The function to calculate the delay between reconnection attempts.
     * @param attempt - The current attempt number.
     * @param delay - The initial delay between reconnection attempts.
     * @returns The delay between reconnection attempts.
     */
    backoff: (attempt: number, delay: number) => number;
    /**
     * The maximum number of enqueued messages to buffer.
     */
    maxEnqueuedMessages: number;
    /**
     * Buffer for messages sent while connection is not open.
     * These messages will be sent once the connection is re-established.
     */
    enqueuedMessages: Array<{
        data: Uint8Array;
    }>;
    /**
     * Whether the room is currently reconnecting.
     */
    isReconnecting: boolean;
}
export declare class Room<T = any, State = InferState<T, never>> {
    #private;
    roomId: string;
    sessionId: string;
    reconnectionToken: string;
    name: string;
    connection: Connection;
    onStateChange: {
        once: (cb: (state: State) => void) => void;
        remove: (cb: (state: State) => void) => void;
        invoke: (state: State) => void;
        invokeAsync: (state: State) => Promise<any[]>;
        clear: () => void;
    } & ((this: any, cb: (state: State) => void) => import("./core/signal.ts").EventEmitter<(state: State) => void>);
    onError: {
        once: (cb: (code: number, message?: string) => void) => void;
        remove: (cb: (code: number, message?: string) => void) => void;
        invoke: (code: number, message?: string) => void;
        invokeAsync: (code: number, message?: string) => Promise<any[]>;
        clear: () => void;
    } & ((this: any, cb: (code: number, message?: string) => void) => import("./core/signal.ts").EventEmitter<(code: number, message?: string) => void>);
    onLeave: {
        once: (cb: (code: number, reason?: string) => void) => void;
        remove: (cb: (code: number, reason?: string) => void) => void;
        invoke: (code: number, reason?: string) => void;
        invokeAsync: (code: number, reason?: string) => Promise<any[]>;
        clear: () => void;
    } & ((this: any, cb: (code: number, reason?: string) => void) => import("./core/signal.ts").EventEmitter<(code: number, reason?: string) => void>);
    onReconnect: {
        once: (cb: () => void) => void;
        remove: (cb: () => void) => void;
        invoke: () => void;
        invokeAsync: () => Promise<any[]>;
        clear: () => void;
    } & ((this: any, cb: () => void) => import("./core/signal.ts").EventEmitter<() => void>);
    onDrop: {
        once: (cb: (code: number, reason?: string) => void) => void;
        remove: (cb: (code: number, reason?: string) => void) => void;
        invoke: (code: number, reason?: string) => void;
        invokeAsync: (code: number, reason?: string) => Promise<any[]>;
        clear: () => void;
    } & ((this: any, cb: (code: number, reason?: string) => void) => import("./core/signal.ts").EventEmitter<(code: number, reason?: string) => void>);
    protected onJoin: {
        once: (cb: (...args: any[]) => void | Promise<any>) => void;
        remove: (cb: (...args: any[]) => void | Promise<any>) => void;
        invoke: (...args: any[]) => void;
        invokeAsync: (...args: any[]) => Promise<any[]>;
        clear: () => void;
    } & ((this: any, cb: (...args: any[]) => void | Promise<any>) => import("./core/signal.ts").EventEmitter<(...args: any[]) => void | Promise<any>>);
    serializerId: string;
    serializer: InferSerializer<State>;
    reconnection: ReconnectionOptions;
    protected joinedAtTime: number;
    protected onMessageHandlers: import("./core/nanoevents.ts").Emitter<import("./core/nanoevents.ts").EventsMap>;
    protected packr: Packr;
    constructor(name: string, rootSchema?: SchemaConstructor<State>);
    connect(endpoint: string, options?: any, headers?: any): void;
    leave(consented?: boolean): Promise<number>;
    onMessage<MessageType extends keyof ExtractRoomClientMessages<NormalizeRoomType<T>>>(message: MessageType, callback: (payload: ExtractRoomClientMessages<NormalizeRoomType<T>>[MessageType]) => void): () => void;
    onMessage<Payload = any>(type: "*", callback: (messageType: string | number, payload: Payload) => void): () => void;
    onMessage<Payload = any>(type: [keyof ExtractRoomClientMessages<NormalizeRoomType<T>>] extends [never] ? (string | number) : never, callback: (payload: Payload) => void): () => void;
    ping(callback: (ms: number) => void): void;
    send<MessageType extends keyof ExtractRoomMessages<NormalizeRoomType<T>>>(messageType: MessageType, payload?: ExtractMessageType<ExtractRoomMessages<NormalizeRoomType<T>>[MessageType]>): void;
    send<Payload = any>(messageType: [keyof ExtractRoomMessages<NormalizeRoomType<T>>] extends [never] ? (string | number) : never, payload?: Payload): void;
    sendUnreliable<T = any>(type: string | number, message?: T): void;
    sendBytes(type: string | number, bytes: Uint8Array): void;
    get state(): State;
    removeAllListeners(): void;
    protected onMessageCallback(event: MessageEvent): void;
    private dispatchMessage;
    private destroy;
    private getMessageHandlerKey;
    private handleReconnection;
    private retryReconnection;
}
