Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sisilicon
GitHub Repository: sisilicon/worldedit-be
Path: blob/master/src/library/classes/eventEmitter.ts
1784 views
1
/* eslint-disable @typescript-eslint/ban-types */
2
/* eslint-disable @typescript-eslint/no-explicit-any */
3
import { EventEmitterTypes } from "../@types/classes/eventEmitter";
4
5
export class EventEmitter<T extends { [K in keyof T]: any[] }> implements EventEmitterTypes<T> {
6
private _listeners: any[] = [];
7
private _configurations = {
8
maxListeners: 10,
9
};
10
11
/**
12
* @private
13
* @param {any} eventName Event type to listen for
14
* @param {Function} listener Function to callback on fire
15
* @param {boolean} [once] Whether to listen for the event only ONCE or not
16
* @param {boolean} [prepend] Insert the Event in the beginning of the Array, so it executes first
17
*/
18
private _addListener(eventName: any, listener: (...args: any[]) => void, once?: boolean, prepend?: boolean): void {
19
const listenerCount = this.listenerCount(eventName);
20
if (listenerCount >= this._configurations.maxListeners)
21
throw `Warning: Possible EventEmitter memory leak detected. ${listenerCount + 1} ${eventName} listeners added. Use emitter.setMaxListeners(n) to increase limit`;
22
const data = {
23
eventName,
24
listener,
25
once,
26
executed: false,
27
};
28
if (prepend) this._listeners.unshift(data);
29
else this._listeners.push(data);
30
}
31
32
/**
33
* @private
34
* @param {string} eventName Event type to remove
35
* @param {Function} listener Function that is being called
36
*/
37
private _removeListener<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): void {
38
if (typeof listener === "number") this._listeners.splice(listener, 1);
39
const index = this._listeners.findIndex((v) => v.eventName === eventName && v.listener === listener);
40
if (index !== -1) this._listeners.splice(index, 1);
41
}
42
43
addListener<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {
44
this._addListener(eventName, listener, false);
45
return this;
46
}
47
48
shutdown(): this {
49
this._listeners.length = 0;
50
return this;
51
}
52
53
emit<K extends keyof T>(eventName: K, ...args: T[K]): boolean {
54
let status = false;
55
this._listeners.forEach((object) => {
56
if (object.eventName === eventName) {
57
if (object.once && object.executed) return;
58
object.listener(...args);
59
(status = true), (object.executed = true);
60
}
61
});
62
return status;
63
}
64
65
eventNames(): Array<string> {
66
return this._listeners.map((v) => v.eventName);
67
}
68
69
getMaxListeners(): number {
70
return this._configurations?.maxListeners;
71
}
72
73
listenerCount<K extends keyof T>(eventName: K): number {
74
return eventName ? this._listeners.filter((v) => v.eventName === eventName).length : this._listeners.length;
75
}
76
77
listeners<K extends keyof T>(eventName: K): Array<Function> {
78
const Functions: Array<Function> = [];
79
this._listeners.forEach((object) => {
80
if (object.eventName === eventName && !object.once) Functions.push(object.listener);
81
});
82
return Functions;
83
}
84
85
off<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {
86
this._removeListener(eventName, listener);
87
return this;
88
}
89
90
on<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {
91
this._addListener(eventName, listener, false);
92
return this;
93
}
94
95
once<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {
96
this._addListener(eventName, listener, true);
97
return this;
98
}
99
100
prependListener<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {
101
this._addListener(eventName, listener, false, true);
102
return this;
103
}
104
105
prependOnceListener<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {
106
this._addListener(eventName, listener, true, true);
107
return this;
108
}
109
110
removeAllListeners<K extends keyof T>(eventName: K): void {
111
eventName ? (this._listeners = this._listeners.filter((element) => element.eventName !== eventName)) : (this._listeners = []);
112
}
113
114
removeListener<K extends keyof T>(eventName: K, listener: (...args: T[K]) => void): this {
115
this._removeListener(eventName, listener);
116
return this;
117
}
118
119
setMaxListeners(number: number): void {
120
if (typeof number === "number") this._configurations.maxListeners = number;
121
}
122
123
rawListeners<K extends keyof T>(eventName: K): Array<Function> {
124
const Functions: Array<Function> = [];
125
this._listeners.forEach((object) => {
126
if (object.eventName === eventName) Functions.push(object.listener);
127
});
128
return Functions;
129
}
130
}
131
132