/** * Events allow for applications to use the observer pattern, which * allows subscribing and publishing events, outside the normal * execution paths. * * @_section api/utils/events:Events [about-events] */ import { defineProperties } from "./properties.js"; /** * A callback function called when a an event is triggered. */ export type Listener = (...args: Array) => void; /** * An **EventEmitterable** behaves similar to an EventEmitter * except provides async access to its methods. * * An EventEmitter implements the observer pattern. */ export interface EventEmitterable { /** * Registers a %%listener%% that is called whenever the * %%event%% occurs until unregistered. */ on(event: T, listener: Listener): Promise; /** * Registers a %%listener%% that is called the next time * %%event%% occurs. */ once(event: T, listener: Listener): Promise; /** * Triggers each listener for %%event%% with the %%args%%. */ emit(event: T, ...args: Array): Promise; /** * Resolves to the number of listeners for %%event%%. */ listenerCount(event?: T): Promise; /** * Resolves to the listeners for %%event%%. */ listeners(event?: T): Promise>; /** * Unregister the %%listener%% for %%event%%. If %%listener%% * is unspecified, all listeners are unregistered. */ off(event: T, listener?: Listener): Promise; /** * Unregister all listeners for %%event%%. */ removeAllListeners(event?: T): Promise; /** * Alias for [[on]]. */ addListener(event: T, listener: Listener): Promise; /** * Alias for [[off]]. */ removeListener(event: T, listener: Listener): Promise; } /** * When an [[EventEmitterable]] triggers a [[Listener]], the * callback always ahas one additional argument passed, which is * an **EventPayload**. */ export class EventPayload { /** * The event filter. */ readonly filter!: T; /** * The **EventEmitterable**. */ readonly emitter!: EventEmitterable; readonly #listener: null | Listener; /** * Create a new **EventPayload** for %%emitter%% with * the %%listener%% and for %%filter%%. */ constructor(emitter: EventEmitterable, listener: null | Listener, filter: T) { this.#listener = listener; defineProperties>(this, { emitter, filter }); } /** * Unregister the triggered listener for future events. */ async removeListener(): Promise { if (this.#listener == null) { return; } await this.emitter.off(this.filter, this.#listener); } }