import { ILogger } from '../logging/logger.mjs';

type EventHandler<T = any> = (data: T) => void | Promise<void>;
interface IEventEmitter<EventTypes = Record<string, any>> {
    on<Event extends keyof EventTypes>(event: Event, handler: EventHandler<EventTypes[Event]>): number;
    once<Event extends keyof EventTypes>(event: Event, handler: EventHandler<EventTypes[Event]>): number;
    off(id: number): void;
    emit<Event extends keyof EventTypes>(event: Event, value: EventTypes[Event]): void;
}
declare class EventEmitter<EventTypes = Record<string, any>> implements IEventEmitter<EventTypes> {
    protected readonly logger?: ILogger | undefined;
    protected index: number;
    protected subscriptions: Map<keyof EventTypes, Array<{
        readonly id: number;
        readonly handler: EventHandler;
    }>>;
    /**
     * @param logger Used to report handler failures from {@link emitAsync}.
     * Defaults to `console` when omitted, so failures are never silent.
     */
    constructor(logger?: ILogger | undefined);
    on<Event extends keyof EventTypes>(event: Event, handler: EventHandler<EventTypes[Event]>): number;
    once<Event extends keyof EventTypes>(event: Event, handler: EventHandler<EventTypes[Event]>): number;
    off(id: number): void;
    emit<Event extends keyof EventTypes>(event: Event, value: EventTypes[Event]): void;
    /**
     * Emit an event and wait for every subscribed handler to settle.
     *
     * Handlers are started in subscription order and then awaited together, so
     * async handlers run concurrently. Use this instead of `emit` when the
     * emitter must not continue until async listeners have finished — for
     * example when those listeners touch resources that are torn down once the
     * emitting operation returns.
     *
     * A handler that throws or rejects is logged and does not stop the other
     * handlers; this never rejects.
     */
    emitAsync<Event extends keyof EventTypes>(event: Event, value: EventTypes[Event]): Promise<void>;
    private reportHandlerError;
}

export { EventEmitter, type EventHandler, type IEventEmitter };
