import { v4 as uuid } from '../node_modules/uuid/dist/esm-browser/index.js';
/**
* Event Emitter
*/
class EventEmitter {
constructor() {
this._events = {};
}
addEvent(eventName) {
if (!this._events[eventName]) {
this._events[eventName] = {};
}
}
on(eventName, listener, id) {
if (!this._events[eventName]) {
// throw new Error(`Subscribing to unknown event ${this.constructor.name}#${eventName}`)
this._events[eventName] = {};
}
const listenerId = id || uuid();
this._events[eventName][listenerId] = listener;
if (this._events.listenerChange) {
this.emit('listenerChange',{event: eventName, listenerObject: this._events[eventName]});
}
}
once(eventName,listener) {
const listenerId = uuid();
this.on(
eventName,
(...data) => {
this.removeListener(eventName,listenerId);
listener(...data);
},
listenerId
);
}
hasListener(eventName, id) {
if ( ! this._events) {
// console.log('Event object destroyed', this.label, this);
return false;
}
return this._events[eventName] && this._events[eventName][id];
}
removeListener(eventName, id) {
if (!this._events[eventName]) {
throw new Error(`Can't remove listener for unknown event "${eventName}".`);
}
if (!this._events[eventName][id]) {
throw new Error(`Can't remove ${eventName} listener with unknown id "${id}".`);
}
delete this._events[eventName][id];
if (this._events.listenerChange) {
this.emit('listenerChange',{event: eventName, listenerObject: this._events[eventName]});
}
// const filterListeners = (listener) => listener !== listenerToRemove;
// this._events[name] = this._events[name].filter(filterListeners);
}
/**
* @param {string} eventName
* @param {any} data
* @returns {Promise<any>}
*/
emit(eventName, data) {
if (!this._events[eventName]) {
// console.warn('create in emit', eventName)
this._events[eventName] = {};
}
return Promise.all(
Object.values(this._events[eventName]).map(eventHandler => eventHandler(data))
);
}
removeAllListeners() {
for ( let [ evt, listeners] of Object.entries( this._events || {}) ) {
for ( let [ id, listener ] of Object.entries( listeners ) ) {
this.removeListener(evt, id);
}
}
}
destroy() {
this.removeAllListeners();
if ( typeof super.destroy === 'function' ) {
super.destroy()
}
// destroy everything
// this class doesn't extend anything
for ( let prop in this ) {
this[ prop ] = null;
}
}
}
export { EventEmitter };