import type { EventEmitter } from "../classes"; import type { EventMap, Listener, ListenerOptions, Register, Unregister, } from "../types"; /** * Listens for `event` on `target`, calling `listener(event)` at the first occuring `event`. The `listener` is then unregistered upon the first occurence. The provided `options` are identical to those provided to `addEventListener`. * Returns a function that removes the `listener` from the `target` for the specified `event`. * * @param target The target on which to listen for the event. * @param event The event name to listen for. * @param listener The listener callback. * @param options Options to pass to the listener. * @returns A function that removes the `listener`. */ function once( target: HTMLElement, eventName: K, listener: Listener, options?: ListenerOptions, ): Unregister; function once( target: Document, eventName: K, listener: Listener, options?: ListenerOptions, ): Unregister; function once( target: Worker, eventName: K, listener: Listener, options?: ListenerOptions, ): Unregister; function once( target: EventEmitter, eventName: K, listener: Listener, ): Unregister; function once( target: EventTarget, eventName: string, listener: Listener, options?: ListenerOptions, ): Unregister; /** * Returns a function that registers a `listener` with optional `options` for a given `event` on the provided `target`. The `listener` is then unregistered upon the first occurence of the `event`. * * @example * ```typescript * const register = on(element, "click"); * // Start listening * const off = register(callback); * // Stop listening * off(); * ``` * * @param target The target on which to listen for the event. * @param event The event name to listen for. * @returns Function that registers a `listener` with optional `options`. */ function once( target: HTMLElement, eventName: K, ): Register, ListenerOptions>; function once( target: Document, eventName: K, ): Register, ListenerOptions>; function once( target: Worker, eventName: K, ): Register, ListenerOptions>; function once( target: EventEmitter, eventName: K, ): Register, never>; function once( target: EventTarget, eventName: string, ): Register, ListenerOptions>; function once( target: any, eventName: string | number | symbol, listener?: Listener, options?: any, ): Unregister | Register, any> { if (listener === undefined) { return ((listener: any, options: any) => once(target, eventName as any, listener, options)) as Register< Listener, any >; } const listenOnce: Listener = ((event: any) => { (listener as any)(event); off(); }) as any; const off = () => { target.removeEventListener(eventName, listenOnce, options); }; target.addEventListener(eventName, listenOnce, options); return off; } export { once };