/** A function that performs cleanup when called */
export type DisposeFn = () => void;
/**
 * Interface for objects that hold resources and can be disposed.
 * Implement this interface on any object that needs deterministic cleanup.
 *
 * @example
 * ```ts
 * class MyResource implements IDisposable {
 *     dispose() { /* release resources *\/ }
 * }
 * ```
 *
 * @category Utilities
 * @group Lifecycle
 */
export interface IDisposable {
    dispose(): void;
}
/**
 * Type guard to check if an object implements {@link IDisposable}.
 *
 * @example
 * ```ts
 * if (isDisposable(obj)) {
 *     obj.dispose(); // safe to call
 * }
 * ```
 */
export declare function isDisposable(value: unknown): value is IDisposable;
/**
 * @experimental
 * Subscribe to a DOM event on any {@link EventTarget} (window, document, HTML elements, etc.)
 * and return an {@link IDisposable} that removes the listener when disposed.
 *
 * Provides full TypeScript event type inference — the callback parameter
 * is automatically typed based on the event name (e.g. `"resize"` → `UIEvent`,
 * `"click"` → `MouseEvent`).
 *
 * Use with {@link DisposableStore.add} for automatic lifecycle cleanup in components.
 *
 * @param target The EventTarget to listen on (window, document, an element, etc.)
 * @param type The event name (e.g. `"resize"`, `"click"`, `"keydown"`)
 * @param listener The event handler callback
 * @param options Optional addEventListener options (passive, capture, once, signal)
 * @returns An {@link IDisposable} that removes the event listener when disposed
 *
 * @example Standalone usage
 * ```ts
 * import { on } from "@needle-tools/engine";
 *
 * const sub = on(window, "resize", (ev) => {
 *     // ev is typed as UIEvent
 *     console.log("resized", ev.target);
 * });
 *
 * // Later: clean up
 * sub.dispose();
 * ```
 *
 * @example With autoCleanup in a component
 * ```ts
 * import { Behaviour, on } from "@needle-tools/engine";
 *
 * export class MyComponent extends Behaviour {
 *     onEnable() {
 *         this.autoCleanup(on(window, "resize", (ev) => { /* UIEvent *\/ }));
 *         this.autoCleanup(on(document, "keydown", (ev) => { /* KeyboardEvent *\/ }));
 *         this.autoCleanup(on(this.context.domElement, "click", (ev) => { /* MouseEvent *\/ }));
 *     }
 *     // All listeners removed automatically on disable!
 * }
 * ```
 *
 * @category Utilities
 * @group Lifecycle
 */
export declare function on<K extends keyof WindowEventMap>(target: Window, type: K, listener: (ev: WindowEventMap[K]) => void, options?: boolean | AddEventListenerOptions): IDisposable;
export declare function on<K extends keyof DocumentEventMap>(target: Document, type: K, listener: (ev: DocumentEventMap[K]) => void, options?: boolean | AddEventListenerOptions): IDisposable;
export declare function on<K extends keyof HTMLElementEventMap>(target: HTMLElement, type: K, listener: (ev: HTMLElementEventMap[K]) => void, options?: boolean | AddEventListenerOptions): IDisposable;
export declare function on(target: EventTarget, type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): IDisposable;
/**
 * A store for managing disposable resources (event subscriptions, listeners, callbacks)
 * that should be cleaned up together.
 *
 * DisposableStore collects disposables and disposes them all at once when
 * {@link dispose} is called. After disposal, the store can be reused — new items
 * can be added and a subsequent {@link dispose} call will clean those up.
 *
 * This is the same pattern used internally by VSCode for lifecycle-bound resource management.
 *
 * @example Basic usage
 * ```ts
 * import { DisposableStore, on } from "@needle-tools/engine";
 *
 * const store = new DisposableStore();
 *
 * // Register a DOM event listener (typed!)
 * store.add(on(window, "resize", (ev) => console.log(ev)));
 *
 * // Register the return value of EventList.on()
 * store.add(myEventList.on(data => console.log(data)));
 *
 * // Register a raw cleanup function
 * store.add(() => someSDK.off("event", handler));
 *
 * // Later: dispose everything at once
 * store.dispose();
 * ```
 *
 * @example Use with Needle Engine components
 * ```ts
 * import { Behaviour, serializable, EventList, on } from "@needle-tools/engine";
 *
 * export class MyComponent extends Behaviour {
 *     @serializable(EventList)
 *     onClick?: EventList;
 *
 *     onEnable() {
 *         // DOM events — fully typed
 *         this.autoCleanup(on(window, "resize", (ev) => this.onResize(ev)));
 *
 *         // EventList — .on() returns a function, autoCleanup accepts it
 *         this.autoCleanup(this.onClick?.on(() => console.log("clicked!")));
 *     }
 *     // No onDisable needed — cleaned up automatically!
 * }
 * ```
 *
 * @category Utilities
 * @group Lifecycle
 */
export declare class DisposableStore implements IDisposable {
    private _disposables;
    /** The number of registered disposables */
    get size(): number;
    /**
     * Register a disposable resource. Accepts:
     * - An {@link IDisposable} object (has a `dispose()` method) — e.g. from {@link on}
     * - A cleanup function (e.g. return value of `EventList.on()`)
     * - `null` or `undefined` (safe no-op for conditional subscriptions)
     *
     * When {@link dispose} is called, all registered resources are cleaned up.
     *
     * @param disposable The resource to register for disposal
     *
     * @example
     * ```ts
     * const store = new DisposableStore();
     *
     * // IDisposable object from on()
     * store.add(on(window, "resize", handler));
     *
     * // Function returned by EventList.on()
     * store.add(myEvent.on(handler));
     *
     * // Raw cleanup function
     * store.add(() => connection.close());
     *
     * // Conditional — safe with undefined
     * store.add(this.maybeEvent?.on(handler));
     * ```
     */
    add(disposable: IDisposable | DisposeFn | Function | null | undefined): void;
    /**
     * Dispose all registered resources. Each registered disposable is cleaned up,
     * then the internal list is cleared. The store can be reused after disposal.
     *
     * Called automatically by the engine when a component's `onDisable` lifecycle fires.
     */
    dispose(): void;
}
