@haelp/teto
Version:
A typescript-based controllable TETR.IO client.
84 lines (83 loc) • 2.52 kB
JavaScript
export class EventEmitter {
#listeners;
#maxListeners = 10;
/** Enables more debugging logs for memory leaks */ verbose = false;
constructor(){
this.#listeners = [];
}
on(event, cb) {
this.#listeners.push([
event,
cb,
false
]);
const listeners = this.#listeners.filter(([e])=>e === event);
if (listeners.length > this.#maxListeners) {
console.warn(`Max listeners exceeded for event "${String(event)}". Current: ${this.#listeners.filter(([e])=>e === event).length}, Max: ${this.#maxListeners}`);
if (this.verbose) console.warn(`Trace: ${new Error().stack}\n\nListeners:\n`, listeners.map(([_, fn])=>fn.toString()).join("\n\n"));
}
return this;
}
off(event, cb) {
this.#listeners = this.#listeners.filter(([e, c])=>e !== event || c !== cb);
return this;
}
emit(event, data) {
const toRemove = new Set();
this.#listeners.forEach(([e, cb, once], idx)=>{
if (e !== event) return;
cb(data);
if (once) toRemove.add(idx);
});
this.#listeners = this.#listeners.filter((_, idx)=>!toRemove.has(idx));
return this;
}
once(event, cb) {
this.#listeners.push([
event,
cb,
true
]);
return this;
}
removeAllListeners(event) {
if (event) {
this.#listeners = this.#listeners.filter(([e])=>e !== event);
} else {
this.#listeners = [];
}
}
set maxListeners(n) {
if (n <= 0 || !Number.isInteger(n)) {
throw new RangeError("Max listeners must be a positive integer");
}
this.#maxListeners = n;
}
get maxListeners() {
return this.#maxListeners;
}
export() {
return {
listeners: this.#listeners.map(([event, cb, once])=>({
event,
cb,
once
})),
maxListeners: this.#maxListeners,
verbose: this.verbose
};
}
import(data) {
data.listeners.forEach(({ event, cb, once })=>{
if (once) {
this.once(event, cb);
} else {
this.on(event, cb);
}
});
this.#maxListeners = data.maxListeners;
this.verbose = data.verbose;
return this;
}
}
//# sourceMappingURL=events.js.map