Path: blob/master/src/library/classes/eventEmitter.ts
1784 views
/* eslint-disable @typescript-eslint/ban-types */1/* eslint-disable @typescript-eslint/no-explicit-any */2import { EventEmitterTypes } from "../@types/classes/eventEmitter";34export class EventEmitter<T extends { [K in keyof T]: any[] }> implements EventEmitterTypes<T> {5private _listeners: any[] = [];6private _configurations = {7maxListeners: 10,8};910/**11* @private12* @param {any} eventName Event type to listen for13* @param {Function} listener Function to callback on fire14* @param {boolean} [once] Whether to listen for the event only ONCE or not15* @param {boolean} [prepend] Insert the Event in the beginning of the Array, so it executes first16*/17private _addListener(eventName: any, listener: (...args: any[]) => void, once?: boolean, prepend?: boolean): void {18const listenerCount = this.listenerCount(eventName);19if (listenerCount >= this._configurations.maxListeners)20throw `Warning: Possible EventEmitter memory leak detected. ${listenerCount + 1} ${eventName} listeners added. Use emitter.setMaxListeners(n) to increase limit`;21const data = {22eventName,23listener,24once,25executed: false,26};27if (prepend) this._listeners.unshift(data);28else this._listeners.push(data);29}3031/**32* @private33* @param {string} eventName Event type to remove34* @param {Function} listener Function that is being called35*/36private _removeListener<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): void {37if (typeof listener === "number") this._listeners.splice(listener, 1);38const index = this._listeners.findIndex((v) => v.eventName === eventName && v.listener === listener);39if (index !== -1) this._listeners.splice(index, 1);40}4142addListener<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {43this._addListener(eventName, listener, false);44return this;45}4647shutdown(): this {48this._listeners.length = 0;49return this;50}5152emit<K extends keyof T>(eventName: K, ...args: T[K]): boolean {53let status = false;54this._listeners.forEach((object) => {55if (object.eventName === eventName) {56if (object.once && object.executed) return;57object.listener(...args);58(status = true), (object.executed = true);59}60});61return status;62}6364eventNames(): Array<string> {65return this._listeners.map((v) => v.eventName);66}6768getMaxListeners(): number {69return this._configurations?.maxListeners;70}7172listenerCount<K extends keyof T>(eventName: K): number {73return eventName ? this._listeners.filter((v) => v.eventName === eventName).length : this._listeners.length;74}7576listeners<K extends keyof T>(eventName: K): Array<Function> {77const Functions: Array<Function> = [];78this._listeners.forEach((object) => {79if (object.eventName === eventName && !object.once) Functions.push(object.listener);80});81return Functions;82}8384off<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {85this._removeListener(eventName, listener);86return this;87}8889on<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {90this._addListener(eventName, listener, false);91return this;92}9394once<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {95this._addListener(eventName, listener, true);96return this;97}9899prependListener<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {100this._addListener(eventName, listener, false, true);101return this;102}103104prependOnceListener<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {105this._addListener(eventName, listener, true, true);106return this;107}108109removeAllListeners<K extends keyof T>(eventName: K): void {110eventName ? (this._listeners = this._listeners.filter((element) => element.eventName !== eventName)) : (this._listeners = []);111}112113removeListener<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {114this._removeListener(eventName, listener);115return this;116}117118setMaxListeners(number: number): void {119if (typeof number === "number") this._configurations.maxListeners = number;120}121122rawListeners<K extends keyof T>(eventName: K): Array<Function> {123const Functions: Array<Function> = [];124this._listeners.forEach((object) => {125if (object.eventName === eventName) Functions.push(object.listener);126});127return Functions;128}129}130131132