import { type JsonCompatibleValue, type Uuid } from '@augment-vir/common';
import { type AnyDuration } from 'date-vir';
import { ListenTarget } from 'typed-event-target';
import { type RoomInput, type ShouldAllowConnectionCheck, WebrtcMultiplayerConnectionUpdateEvent, WebrtcMultiplayerController } from '../webrtc/webrtc-multiplayer-controller.js';
import { type MultiplayerApi } from './multiplayer-api.js';
/**
 * Message type for {@link LockStepMessage}.
 *
 * @category Internal
 */
export declare enum LockStepMessageType {
    Actions = "actions",
    Frame = "frame"
}
/**
 * Message for {@link LockStepGameStateController}.
 *
 * @category Internal
 */
export type LockStepMessage<Action> = 
/** Sent from child clients to the host as actions happen. */
{
    type: LockStepMessageType.Actions;
    sourceClientId: Uuid;
    actions: Action[];
} | {
    type: LockStepMessageType.Frame;
    actions: Action[];
};
declare const LockStepFrameEvent_base: (new (eventInitDict: {
    bubbles?: boolean;
    cancelable?: boolean;
    composed?: boolean;
    detail: any;
}) => import("typed-event-target").TypedCustomEvent<any, "lock-step-multiplayer-frame">) & Pick<{
    new (type: string, eventInitDict?: EventInit): Event;
    prototype: Event;
    readonly NONE: 0;
    readonly CAPTURING_PHASE: 1;
    readonly AT_TARGET: 2;
    readonly BUBBLING_PHASE: 3;
}, "prototype" | "NONE" | "CAPTURING_PHASE" | "AT_TARGET" | "BUBBLING_PHASE"> & Pick<import("typed-event-target").TypedCustomEvent<any, "lock-step-multiplayer-frame">, "type">;
/**
 * An event that is omitted from {@link LockStepGameStateController} when a frame is finalized.
 *
 * @category Internal
 */
export declare class LockStepFrameEvent<Action extends JsonCompatibleValue> extends LockStepFrameEvent_base {
    detail: Action;
}
/**
 * A wrapper for {@link WebrtcMultiplayerController} that ensures messages are sent and arrive in a
 * lock-step fashion. Also supports singleplayer mode.
 *
 * @category Internal
 */
export declare class LockStepGameStateController<Action extends JsonCompatibleValue = any> extends ListenTarget<LockStepFrameEvent<Action> | WebrtcMultiplayerConnectionUpdateEvent> {
    private readonly allowMultiplayerConnectionCheck;
    protected webrtcController: WebrtcMultiplayerController<LockStepMessage<Action>> | undefined;
    /** The current client id. */
    clientId: `${string}-${string}-${string}-${string}-${string}`;
    /** The current data flow FPS. */
    readonly currentFps: number;
    /** This is only used if the current controller is the host. */
    private clientsResponded;
    private frameActions;
    private timeoutId;
    private frameTickReady;
    private frameMs;
    private lastFpsCalculation;
    private singleplayer;
    constructor(frameDuration: AnyDuration | undefined, allowMultiplayerConnectionCheck?: ShouldAllowConnectionCheck<LockStepGameStateController<Action>>);
    /**
     * Get all connected client ids.
     *
     * - For host clients, this will indicate how many member clients are connected to the host
     *   client, _not_ including the host itself.
     * - For non-host clients, this will only list the host's client.
     *
     * For host clients, this does ont include the host client id whereas
     * {@link LockStepGameStateController.getAllClientIds} does.
     */
    getConnectedClientIds(): Uuid[];
    /**
     * Get all room client ids.
     *
     * - For host clients, this will indicate how many clients are connected to the room, including
     *   the host client itself.
     * - For non-host clients, this will only list the host's client.
     *
     * For host clients, this includes the host client id whereas
     * {@link LockStepGameStateController.getConnectedClientIds} does not.
     */
    getAllClientIds(): Uuid[];
    /** Checks if the current controller is the room host. */
    isHost(): boolean | undefined;
    /** Checks if the current controller is connected to the room. */
    isConnected(): boolean | undefined;
    /** Perform an action for the current client. */
    act(actions: ReadonlyArray<Action>): void;
    /**
     * Manually run the next frame.
     *
     * @throws Error if `frameDuration` has been set.
     */
    runFrame(actions?: ReadonlyArray<Action> | undefined): void;
    /** Cleanup everything. */
    destroy(): void;
    /**
     * Startup the controller in singleplayer mode.
     *
     * @see {@link LockStepGameStateController.multiplayerConnect} for starting the controller in multiplayer mode.
     */
    startSingleplayer(): void;
    /**
     * Startup the controller in multiplayer mode and connect to a room.
     *
     * @returns Whether the connection was a successful or not.
     * @see {@link LockStepGameStateController.startSingleplayer} for starting the controller in singleplayer mode.
     */
    multiplayerConnect(gameId: string, multiplayerApi: Readonly<MultiplayerApi>, 
    /**
     * - 'stun.l.google.com:19302'
     * - 'stun.stunprotocol.org'
     * - 'stun.cloudflare.com:3478'
     */
    stunServerUrls: ReadonlyArray<string>, multiplayerRoom: Readonly<RoomInput>): Promise<boolean>;
    private handleConnection;
    private calculateFps;
    private handleReceivedMessage;
    private finishFrame;
    private maybeFinishFrame;
}
export {};
