import { AsyncTeardownManager, type Subscription } from "../teardown-manager.js";
/**
 * Extracts the keys of events from an object.
 * @template T
 * @typedef {Object} EventKeys
 * @property {keyof T} key - The key of the event.
 */
export type EventKeys<T extends object> = {
    [key in keyof T]: T[key] extends IEvent<any[], any, any> ? key : never;
}[keyof T];
/**
 * Options for attaching events.
 * @typedef {Object} AttachEventOptions
 * @property {boolean} once - Whether the event should be triggered only once.
 */
export interface AttachEventOptions {
    once: boolean;
}
/**
 * Represents a listener function for events.
 * @template T
 * @template TReturnType
 * @typedef {function(...T): TReturnType} Listener
 */
export type Listener<T extends readonly unknown[] = unknown[], TReturnType = void> = (...args: T) => TReturnType;
/**
 * Represents a listener function for a specific event type.
 * @template T
 * @typedef {function(...TArgs): TReturnType} EventListener
 */
export type EventListener<T> = T extends IEventSink<infer TArgs, infer TReturnType, any> ? (...args: TArgs) => TReturnType : never;
/**
 * Extracts the argument types of an event.
 * @template TEvent
 * @typedef {TEvent extends IEventSink<infer X, infer _Y, infer _Z> ? X : never} EventArgs
 */
export type EventArgs<TEvent> = TEvent extends IEventSink<infer X, infer _Y, infer _Z> ? X : never;
/**
 * Extracts the return type of an event.
 * @template TEvent
 * @typedef {TEvent extends IEventSink<infer _X, infer Y, infer _Z> ? Y : never} EventReturnType
 */
export type EventReturnType<TEvent> = TEvent extends IEventSink<infer _X, infer Y, infer _Z> ? Y : never;
/**
 * Extracts the options type of an event.
 * @template TEvent
 * @typedef {TEvent extends IEventSink<infer _X, infer _Y, infer Z> ? Z : never} EventOptions
 */
export type EventOptions<TEvent> = TEvent extends IEventSink<infer _X, infer _Y, infer Z> ? Z : never;
/**
 * Interface for an event sink.
 * @template T
 * @template TReturnType
 * @template TOptions
 * @interface IEventSink
 */
export interface IEventSink<T extends readonly unknown[], TReturnType, TOptions extends {
    once?: boolean;
}> {
    maxListeners: number;
    hasListeners: boolean;
    addListener(listener: Listener<T, TReturnType>, options?: TOptions): Subscription;
    removeListener(listener?: Listener<T, TReturnType>): boolean;
    [Symbol.dispose](): void;
}
/**
 * Interface for an event.
 * @template T
 * @template TReturnType
 * @template TOptions
 * @interface IEvent
 * @extends {IEventSink<T, TReturnType, TOptions>}
 */
export type IEvent<T extends readonly unknown[], TReturnType, TOptions extends {
    once?: boolean;
} = {
    once?: boolean;
}> = IEventSink<T, TReturnType, TOptions> & {
    emit(...args: T): TReturnType;
    pipe(event: IEvent<T, TReturnType, TOptions>): Subscription;
};
/**
 * Event class to manage listeners and emit events.
 * @template T
 * @template TReturnType
 * @template TOptions
 * @extends {TeardownManager}
 * @implements {IEvent<T, TReturnType, TOptions>}
 */
export declare class Event<T extends readonly unknown[] = unknown[], TReturnType = void, TOptions extends {
    once?: boolean;
} = {
    once?: boolean;
}> extends AsyncTeardownManager implements IEvent<T, TReturnType, TOptions> {
    maxListeners: number;
    protected readonly combineReturnTypes?: (args: TReturnType[]) => TReturnType;
    /**
     * Combines named events into a single event.
     * @template T
     * @param {T} obj - The object containing named events.
     * @returns {IEvent<[{ [K in keyof T]: T[K] extends IEventSink<infer X, unknown, unknown> ? X : T[K] }], void>} - The combined event.
     */
    static combineNamed<T extends {
        [K in keyof T]?: T[K] | IEventSink<T[K] extends unknown[] ? T[K] : [T[K]], unknown, {
            once?: boolean;
        }>;
    }>(obj: T): IEvent<[{
        [K in keyof T]: T[K] extends IEventSink<infer X, unknown, unknown> ? X : T[K];
    }], void>;
    /**
     * Combines multiple events into a single event.
     * @template T
     * @param {...T} events - The events to combine.
     * @returns {IEventSink<T, void>} - The combined event.
     */
    static combine<T extends unknown[]>(...events: {
        [K in keyof T]?: T[K] | IEventSink<T[K] extends unknown[] ? T[K] : [T[K]], unknown, {
            once?: boolean;
        }>;
    }): IEventSink<T, void, {
        once?: boolean;
    }>;
    /**
     * Creates an instance of Event.
     * @param {number} [maxListeners=Event.maxListeners] - The maximum number of listeners.
     * @param {(args: TReturnType[]) => TReturnType} [combineReturnTypes] - Function to combine return types.
     */
    constructor(maxListeners?: number, combineReturnTypes?: (args: TReturnType[]) => TReturnType);
    /**
     * Clones the event.
     * @returns {Event<T, TReturnType, TOptions>} - The cloned event.
     */
    clone(): Event<T, TReturnType, TOptions>;
    static maxListeners: number;
    protected readonly listeners: Listener<T, TReturnType>[];
    /**
     * Checks if the event has listeners.
     * @returns {boolean} - True if the event has listeners, false otherwise.
     */
    get hasListeners(): boolean;
    /**
     * Adds a listener to the event.
     * @param {Listener<T, TReturnType>} listener - The listener to add.
     * @param {TOptions} [options] - The event options.
     * @returns {Subscription} - The subscription.
     */
    addListener(listener: (...args: T) => TReturnType, options?: TOptions): Subscription;
    /**
     * Removes a listener from the event.
     * @param {Listener<T, TReturnType>} listener - The listener to remove.
     * @returns {boolean} - True if the listener was removed, false otherwise.
     */
    removeListener(listener?: (...args: T) => TReturnType): boolean;
    /**
     * Emits the event.
     * @param {...T} args - The arguments to pass to the listeners.
     * @returns {TReturnType} - The return value of the listeners.
     */
    emit(...args: T): TReturnType;
    /**
     * Pipes the event to another event or emitter.
     * @param {IEvent<T, TReturnType, TOptions>} event - The event to pipe to.
     * @returns {Subscription} - The subscription.
     */
    pipe(event: IEvent<T, TReturnType, TOptions>): Subscription;
    /**
     * Pipes the event to another event or emitter.
     * @param {IEvent<T, TReturnType, TOptions>} event - The event to pipe to.
     * @returns {Subscription} - The subscription.
     */
    pipe<U extends unknown[]>(event: Listener<T, U>): IEventSink<U, TReturnType, TOptions>;
    /**
     * Disposes the event.
     */
    [Symbol.dispose](): void;
}
/**
 * PipeEvent class to map and pipe events.
 * @template T
 * @template U
 * @template TReturnType
 * @template TOptions
 * @extends {Event<U, TReturnType, TOptions>}
 */
export declare class PipeEvent<T extends unknown[], U extends unknown[], TReturnType, TOptions extends {
    once?: boolean;
}> extends Event<U, TReturnType, TOptions> {
    protected readonly source: IEventSink<T, TReturnType, TOptions>;
    private readonly map;
    protected subscription: ReturnType<IEventSink<T, TReturnType, TOptions>['addListener']>;
    /**
     * Creates an instance of PipeEvent.
     * @param {IEventSink<T, TReturnType, TOptions>} source - The source event sink.
     * @param {(...args: T) => U} map - Function to map arguments.
     * @param {(results: TReturnType[]) => TReturnType} combineResults - Function to combine return types.
     */
    constructor(source: IEventSink<T, TReturnType, TOptions>, map: (...args: T) => U, combineResults: (results: TReturnType[]) => TReturnType);
    /**
     * Subscribes to the source event if required.
     */
    protected subscribeToSourceIfRequired(): void;
    /**
     * Adds a listener to the pipe event.
     * @param {Listener<U, TReturnType>} listener - The listener to add.
     * @param {TOptions} [options] - The event options.
     * @returns {Subscription} - The subscription.
     */
    addListener(listener: (...args: U) => TReturnType, options?: TOptions): () => boolean;
    /**
     * Removes a listener from the pipe event.
     * @param {Listener<U, TReturnType>} listener - The listener to remove.
     * @returns {boolean} - True if the listener was removed, false otherwise.
     */
    removeListener(listener: (...args: U) => TReturnType): boolean;
}
/**
 * ReplayEvent class to manage events with a buffer.
 * @template T
 * @template TReturnType
 * @extends {Event<T, TReturnType>}
 */
export declare class ReplayEvent<T extends unknown[], TReturnType = void> extends Event<T, TReturnType> {
    private readonly bufferLength;
    private readonly buffer;
    /**
     * Creates an instance of ReplayEvent.
     * @param {number} bufferLength - The length of the buffer.
     * @param {number} maxListeners - The maximum number of listeners.
     * @param {(args: TReturnType[]) => TReturnType} [combineReturnTypes] - Function to combine return types.
     */
    constructor(bufferLength: number, maxListeners?: number, combineReturnTypes?: (args: TReturnType[]) => TReturnType);
    /**
     * Emits the event and stores the arguments in the buffer.
     * @param {...T} args - The arguments to pass to the listeners.
     * @returns {TReturnType} - The return value of the listeners.
     */
    emit(...args: T): TReturnType;
    /**
     * Adds a listener to the event and replays the buffered events.
     * @param {Listener<T, TReturnType>} listener - The listener to add.
     * @param {{ once?: boolean }} [options] - The event options.
     * @returns {Subscription} - The subscription.
     */
    addListener(listener: (...args: T) => TReturnType, options?: {
        once?: boolean;
    }): () => boolean;
}
