import type express from 'express';
import * as matchMaker from './MatchMaker.ts';
import { RegisteredHandler } from './matchmaker/RegisteredHandler.ts';
import { type OnCreateOptions, Room } from './Room.ts';
import { Deferred, type Type } from './utils/Utils.ts';
import type { Presence } from "./presence/Presence.ts";
import { Transport } from './Transport.ts';
import { type Router } from './router/index.ts';
import { type SDKTypes as SharedSDKTypes } from '@colyseus/shared-types';
export type ServerOptions = {
    publicAddress?: string;
    presence?: Presence;
    driver?: matchMaker.MatchMakerDriver;
    transport?: Transport;
    gracefullyShutdown?: boolean;
    logger?: any;
    /**
     * Optional callback to execute before the server listens.
     * This is useful for example to connect into a database or other services before the server listens.
     */
    beforeListen?: () => Promise<void> | void;
    /**
     * Optional callback to configure Express routes.
     * When provided, the transport layer will initialize an Express-compatible app
     * and pass it to this callback for custom route configuration.
     *
     * For uWebSockets transport, this uses the uwebsockets-express module.
     */
    express?: (app: express.Application) => Promise<void> | void;
    /**
     * Custom function to determine which process should handle room creation.
     * Default: assign new rooms the process with least amount of rooms created
     */
    selectProcessIdToCreateRoom?: matchMaker.SelectProcessIdCallback;
    /**
     * Whether this process is running as a standalone match-maker or not. (default: false)
     * When enabled, this process will not spawn rooms and will only be responsible for matchmaking.
     */
    isStandaloneMatchMaker?: boolean;
    /**
     * If enabled, rooms are going to be restored in the server-side upon restart,
     * clients are going to automatically re-connect when server reboots.
     *
     * Beware of "schema mismatch" issues. When updating Schema structures and
     * reloading existing data, you may see "schema mismatch" errors in the
     * client-side.
     *
     * (This operation is costly and should not be used in a production
     * environment)
     */
    devMode?: boolean;
    /**
     * Display greeting message on server start.
     * Default: true
     */
    greet?: boolean;
};
/**
 * Exposed types for the client-side SDK.
 * Re-exported from @colyseus/shared-types with specific type constraints.
 */
export interface SDKTypes<RoomTypes extends Record<string, RegisteredHandler> = any, Routes extends Router = any> extends SharedSDKTypes<RoomTypes, Routes> {
}
export declare class Server<RoomTypes extends Record<string, RegisteredHandler> = any, Routes extends Router = any> implements SDKTypes<RoomTypes, Routes> {
    '~rooms': RoomTypes;
    '~routes': Routes;
    transport: Transport;
    router: Routes;
    options: ServerOptions;
    protected presence: Presence;
    protected driver: matchMaker.MatchMakerDriver;
    protected port: number | string;
    protected greet: boolean;
    protected _onTransportReady: Deferred<Transport>;
    private _originalRoomOnMessage;
    constructor(options?: ServerOptions);
    attach(options: ServerOptions): Promise<void>;
    /**
     * Bind the server into the port specified.
     *
     * @param port - Port number or Unix socket path
     * @param hostname
     * @param backlog
     * @param listeningListener
     */
    listen(port: number | string, hostname?: string, backlog?: number, listeningListener?: Function): Promise<any>;
    /**
     * Define a new type of room for matchmaking.
     *
     * @param name public room identifier for match-making.
     * @param roomClass Room class definition
     * @param defaultOptions default options for `onCreate`
     */
    define<T extends Type<Room>>(roomClass: T, defaultOptions?: OnCreateOptions<T>): RegisteredHandler;
    define<T extends Type<Room>>(name: string, roomClass: T, defaultOptions?: OnCreateOptions<T>): RegisteredHandler;
    /**
     * Remove a room definition from matchmaking.
     * This method does not destroy any room. It only dissallows matchmaking
     */
    removeRoomType(name: string): void;
    gracefullyShutdown(exit?: boolean, err?: Error): Promise<void>;
    /**
     * Add simulated latency between client and server.
     * @param milliseconds round trip latency in milliseconds.
     */
    simulateLatency(milliseconds: number): void;
    /**
     * Register a callback that is going to be executed before the server shuts down.
     * @param callback
     */
    onShutdown(callback: () => void | Promise<any>): void;
    onBeforeShutdown(callback: () => void | Promise<any>): void;
    protected getDefaultTransport(options: any): Promise<Transport>;
    protected onShutdownCallback: () => void | Promise<any>;
    protected onBeforeShutdownCallback: () => void | Promise<any>;
}
export type RoomDefinitions = Record<string, RegisteredHandler | Type<Room>>;
export declare function registerRoomDefinitions<T extends RoomDefinitions>(rooms: T): string[];
export declare function unregisterRoomDefinitions(roomNames: Iterable<string>): void;
export type DefineServerOptions<T extends Record<string, RegisteredHandler>, R extends Router> = ServerOptions & {
    rooms: T;
    routes?: R;
};
export declare function defineServer<T extends Record<string, RegisteredHandler>, R extends Router>(options: DefineServerOptions<T, R>): Server<T, R>;
export declare function defineRoom<T extends Type<Room>>(roomKlass: T, defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0]): RegisteredHandler<InstanceType<T>>;
