All files / ethers.js/src.ts/utils events.ts

100% Statements 105/105
75% Branches 3/4
100% Functions 3/3
100% Lines 105/105

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 1061x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 2x 2x 2x 87x  
/**
 *  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<any>) => void;
 
/**
 *  An **EventEmitterable** behaves similar to an EventEmitter
 *  except provides async access to its methods.
 *
 *  An EventEmitter implements the observer pattern.
 */
export interface EventEmitterable<T> {
    /**
     *  Registers a %%listener%% that is called whenever the
     *  %%event%% occurs until unregistered.
     */
    on(event: T, listener: Listener): Promise<this>;
 
    /**
     *  Registers a %%listener%% that is called the next time
     *  %%event%% occurs.
     */
    once(event: T, listener: Listener): Promise<this>;
 
    /**
     *  Triggers each listener for %%event%% with the %%args%%.
     */
    emit(event: T, ...args: Array<any>): Promise<boolean>;
 
    /**
     *  Resolves to the number of listeners for %%event%%.
     */
    listenerCount(event?: T): Promise<number>;
 
    /**
     *  Resolves to the listeners for %%event%%.
     */
    listeners(event?: T): Promise<Array<Listener>>;
 
    /**
     *  Unregister the %%listener%% for %%event%%. If %%listener%%
     *  is unspecified, all listeners are unregistered.
     */
    off(event: T, listener?: Listener): Promise<this>;
 
    /**
     *  Unregister all listeners for %%event%%.
     */
    removeAllListeners(event?: T): Promise<this>;
 
    /**
     *  Alias for [[on]].
     */
    addListener(event: T, listener: Listener): Promise<this>;
 
    /**
     *  Alias for [[off]].
     */
    removeListener(event: T, listener: Listener): Promise<this>;
}
 
/**
 *  When an [[EventEmitterable]] triggers a [[Listener]], the
 *  callback always ahas one additional argument passed, which is
 *  an **EventPayload**.
 */
export class EventPayload<T> {
    /**
     *  The event filter.
     */
    readonly filter!: T;
 
    /**
     *  The **EventEmitterable**.
     */
    readonly emitter!: EventEmitterable<T>;
 
    readonly #listener: null | Listener;
 
    /**
     *  Create a new **EventPayload** for %%emitter%% with
     *  the %%listener%% and for %%filter%%.
     */
    constructor(emitter: EventEmitterable<T>, listener: null | Listener, filter: T) {
        this.#listener = listener;
        defineProperties<EventPayload<any>>(this, { emitter, filter });
    }
 
    /**
     *  Unregister the triggered listener for future events.
     */
    async removeListener(): Promise<void> {
        if (this.#listener == null) { return; }
        await this.emitter.off(this.filter, this.#listener);
    }
}