import { Emitter } from 'fancy-emitter';
import type { ClientID, Name, LobbyID } from '@mothepro/signaling-lobby';
import type Peer from './Peer.js';
import { parseFallback } from '../util/parsers.js';
import Client, { SimpleClient, MockClient } from './Client.js';
export declare const enum State {
    /** Connection with server is not yet open, i.e. closed. */
    CLOSED = 0,
    /** When our connection to signaling server is established. */
    READY = 1,
    /** A group has been finalized and peers can began establishing direct connections. */
    FINALIZED = 2,
    /** The server connection will be used as a proxy for failed direct connections. */
    FALLBACK = 3
}
/**
 * Handle the communication with the signaling server.
 *
 * Joins the lobby on server upon construction.
 * Allows for creation, approval and rejection of groups.
 * Listening on the `groupFinal` emitter will tell caller which offers/answers to create/accept
 */
export default class {
    self?: MockClient;
    /** Socket to signaling server. */
    private readonly server;
    /** Map of all clients connected to this signaling server. */
    private readonly allClients;
    private readonly groups;
    private state;
    readonly stateChange: Emitter<State>;
    /** Nonce generated by the server after finalization. */
    code?: number;
    /** My ID on the signaling server once finalized. */
    myId?: ClientID;
    /** Clients we have finalized with. */
    members?: Client[];
    /** Activates when a new client joins the lobby. */
    readonly connection: Emitter<SimpleClient>;
    /** Activates when the server sends a message on behalf of a failed peer connection. */
    readonly fallbackMessage: Emitter<ReturnType<typeof parseFallback>>;
    /** The direct, indirect & mock peers, it's only passed here for server logging. */
    peersForFallbackLogging: Peer[];
    /** Activates when receiving some data from the signaling server. */
    private readonly message;
    private handleClientJoin;
    private handleGroupChange;
    private handleGroupFinalize;
    /** Attempts to get a client that has connected. Throws if unable to. */
    private readonly getClient;
    /** A wrapper around socket send since that method doesn't throw, for some reason. */
    private serverSend;
    private sendSdpOnCreation;
    private bindStateChanges;
    constructor(address: URL | string, lobby: LobbyID, name?: Name, protocol?: string | string[]);
    /** Proposes a group to the server and returns the emitter that will be activated when clients accept it. */
    proposeGroup(...members: SimpleClient[]): Emitter<SimpleClient>;
    groupExists(...members: SimpleClient[]): boolean;
    /** Sends an indirect message to a peer thru signaling server. */
    sendFallback(id: ClientID, data: ArrayBuffer): void;
}
