class EventEmitter {
#listeners = new Map();
on(eventName, callback) {
if (!this.#listeners.has(eventName)) {
this.#listeners.set(eventName, []);
}
this.#listeners.get(eventName).push(callback);
return this;
}
once(eventName, callback) {
const wrapper = (...args) => {
this.removeListener(eventName, wrapper);
callback(...args);
};
return this.on(eventName, wrapper);
}
emit(eventName, ...args) {
const callbacks = this.#listeners.get(eventName);
if (callbacks) {
callbacks.forEach(cb => {
try {
cb(...args);
} catch (e) {
console.error(`Error in event '${eventName}':`, e);
}
});
return true;
}
return false;
}
addListener(eventName, callback) {
return this.on(eventName, callback);
}
removeListener(eventName, callback) {
const callbacks = this.#listeners.get(eventName);
if (callbacks) {
const index = callbacks.indexOf(callback);
if (index !== -1) {
callbacks.splice(index, 1);
}
}
return this;
}
}
globalThis.EventEmitter = EventEmitter;