import { Modding } from "@flamework/core";
import Destroyable from "@rbxts/destroyable";
import { MiddlewareProvider } from "./middleware";
import type { ClientMessageCallback, ServerMessageCallback, BaseMessage, MessageEmitterMetadata, ClientMessageFunctionCallback, ServerMessageFunctionCallback } from "./structs";
interface MessageEmitterOptions {
    readonly batchRemotes: boolean;
    readonly batchRate: number;
}
export declare class MessageEmitter<MessageData> extends Destroyable {
    private readonly options;
    readonly middleware: MiddlewareProvider<MessageData>;
    private readonly guards;
    private serializers;
    private clientCallbacks;
    private clientFunctions;
    private serverCallbacks;
    private serverFunctions;
    private serverQueue;
    private clientBroadcastQueue;
    private clientQueue;
    /** @metadata macro */
    static create<MessageData>(options?: Partial<MessageEmitterOptions>, meta?: Modding.Many<MessageEmitterMetadata<MessageData>>): MessageEmitter<MessageData>;
    private constructor();
    readonly server: {
        /**
         * @returns A destructor function that disconnects the callback from the message
         */
        on: <Kind extends keyof MessageData>(message: Kind & BaseMessage, callback: ServerMessageCallback<MessageData[Kind]>) => () => void;
        /**
         * Disconnects the callback as soon as it is called for the first time
         *
         * @returns A destructor function that disconnects the callback from the message
         */
        once: <Kind extends keyof MessageData>(message: Kind & BaseMessage, callback: ServerMessageCallback<MessageData[Kind]>) => () => void;
        /**
         * Emits a message to the server
         *
         * @param message The message kind to be sent
         * @param data The data associated with the message
         * @param unreliable Whether the message should be sent unreliably
         */
        emit: <Kind extends keyof MessageData>(message: Kind & BaseMessage, data?: MessageData[Kind], unreliable?: boolean) => void;
        /**
         * Simulates a remote function invocation.
         *
         * @param message The message kind to be sent
         * @param data The data associated with the message
         * @param unreliable Whether the message should be sent unreliably
         */
        invoke: <Kind extends keyof MessageData, ReturnKind extends keyof MessageData>(message: Kind & BaseMessage, returnMessage: ReturnKind & BaseMessage, data?: MessageData[Kind], unreliable?: boolean) => Promise<MessageData[ReturnKind]>;
        /**
         * Sets a callback for a simulated remote function
         *
         * @returns A destructor function that disconnects the callback from the message
         */
        setCallback: <Kind extends keyof MessageData, ReturnKind extends keyof MessageData>(message: Kind & BaseMessage, returnMessage: ReturnKind & BaseMessage, callback: ServerMessageFunctionCallback<MessageData[Kind], MessageData[ReturnKind]>) => () => void;
    };
    readonly client: {
        /**
         * @returns A destructor function that disconnects the callback from the message
         */
        on: <Kind extends keyof MessageData>(message: Kind & BaseMessage, callback: ClientMessageCallback<MessageData[Kind]>) => () => void;
        /**
         * Disconnects the callback as soon as it is called for the first time
         *
         * @returns A destructor function that disconnects the callback from the message
         */
        once: <Kind extends keyof MessageData>(message: Kind & BaseMessage, callback: ClientMessageCallback<MessageData[Kind]>) => () => void;
        /**
         * Emits a message to a specific client or multiple clients
         *
         * @param player The player(s) to whom the message is sent
         * @param message The message kind to be sent
         * @param data The data associated with the message
         * @param unreliable Whether the message should be sent unreliably
         */
        emit: <Kind extends keyof MessageData>(player: Player | Player[], message: Kind & BaseMessage, data?: MessageData[Kind], unreliable?: boolean) => void;
        /**
         * Emits a message to all clients except the specified client(s)
         *
         * @param player The player(s) to whom the message is not sent
         * @param message The message kind to be sent
         * @param data The data associated with the message
         * @param unreliable Whether the message should be sent unreliably
         */
        emitExcept: <Kind extends keyof MessageData>(player: Player | Player[], message: Kind & BaseMessage, data?: MessageData[Kind], unreliable?: boolean) => void;
        /**
         * Emits a message to all connected clients
         *
         * @param message The message kind to be sent
         * @param data The data associated with the message
         * @param unreliable Whether the message should be sent unreliably
         */
        emitAll: <Kind extends keyof MessageData>(message: Kind & BaseMessage, data?: MessageData[Kind], unreliable?: boolean) => void;
        /**
         * Simulates a remote function invocation.
         *
         * @param message The message kind to be sent
         * @param data The data associated with the message
         * @param unreliable Whether the message should be sent unreliably
         */
        invoke: <Kind extends keyof MessageData, ReturnKind extends keyof MessageData>(message: Kind & BaseMessage, returnMessage: ReturnKind & BaseMessage, player: Player, data?: MessageData[Kind], unreliable?: boolean) => Promise<MessageData[ReturnKind]>;
        /**
         * Sets a callback for a simulated remote function
         *
         * @returns A destructor function that disconnects the callback from the message
         */
        setCallback: <Kind extends keyof MessageData, ReturnKind extends keyof MessageData>(message: Kind & BaseMessage, returnMessage: ReturnKind & BaseMessage, callback: ClientMessageFunctionCallback<MessageData[Kind], MessageData[ReturnKind]>) => () => void;
    };
    private initialize;
    private update;
    private runClientMiddlewares;
    private runServerMiddlewares;
    private validateData;
    private onRemoteFire;
    private executeFunctions;
    private executeEventCallbacks;
    private deserializeAndValidate;
    private once;
    private on;
    private getPacket;
    /** @metadata macro */
    private addSerializer;
    /** @metadata macro */
    private createMessageSerializer;
    private getSerializer;
}
export {};
