export class EventEmitter {
#listeners = new Map();
on(event, listener) {
if (!this.#listeners.has(event)) {
this.#listeners.set(event, new Set());
}
this.#listeners.get(event).add(listener);
return () => this.off(event, listener); // returns unsubscribe fn
}
once(event, listener) {
const wrapper = (...args) => {
listener(...args);
this.off(event, wrapper);
};
return this.on(event, wrapper);
}
off(event, listener) {
this.#listeners.get(event)?.delete(listener);
return this;
}
emit(event, ...args) {
this.#listeners.get(event)?.forEach(l => l(...args));
return this;
}
clear(event) {
if (event) this.#listeners.delete(event);
else this.#listeners.clear();
return this;
}
}