UNPKG

@reldens/utils

Version:
147 lines (134 loc) 5.66 kB
/** * * Reldens - EventsManager * * This extension includes a few new features: * * - The onWithKey and offWithKey methods will allow you to specify a "group" key for the event listener, the related * event will be referenced in a new property called "eventsByRemoveKey" so you can detach multiple listeners at the * time. * * - Then the normal "on" and "off" aliases were override to include a debug check with a log. Using the debug property * you can specify to log "all" the fire and listeners, or just by key. Note the key search will be applied in both * directions, it will check if the debug value exists in the event key or if the event key exists in the debug value. * */ const AwaitEventEmitter = require('await-event-emitter').default; const Logger = require('./logger'); const sc = require('./shortcuts'); class AwaitEventEmitterExtended extends AwaitEventEmitter { constructor() { super(); this.eventsByRemoveKeys = {}; this.debug = false; } onWithKey(eventName, callback, uniqueRemoveKey, masterKey) { if( sc.hasOwn(this.eventsByRemoveKeys, uniqueRemoveKey) || ( masterKey && sc.hasOwn(this.eventsByRemoveKeys, masterKey) && sc.hasOwn(this.eventsByRemoveKeys[masterKey], uniqueRemoveKey) ) ){ Logger.debug('Event "'+eventName+'" exists with key "'+uniqueRemoveKey+'" and masterKey "'+masterKey+'".'); return false; } this.on(eventName, callback); let dataArr = this.listeners(eventName); let currentListenerIndex = dataArr.indexOf(callback); let currentListener = dataArr[currentListenerIndex]; if(!masterKey){ this.eventsByRemoveKeys[uniqueRemoveKey] = {eventName, callback}; return currentListener; } if(!sc.hasOwn(this.eventsByRemoveKeys, masterKey)){ this.eventsByRemoveKeys[masterKey] = {}; } this.eventsByRemoveKeys[masterKey][uniqueRemoveKey] = {eventName, callback}; return currentListener; } /** * This method will remove a SINGLE event using the unique remove key. * If the event listener was assigned using a masterKey then we need to pass it as well to find the event. */ offWithKey(uniqueRemoveKey, masterKey) { if(masterKey && !sc.hasOwn(this.eventsByRemoveKeys, masterKey)){ Logger.debug('Event not found by masterKey "'+masterKey+'".'); return false; } if(!masterKey && !sc.hasOwn(this.eventsByRemoveKeys, uniqueRemoveKey)){ Logger.debug('Event not found by removeKey "'+uniqueRemoveKey+'".'); return false; } let eventToRemove = masterKey ? this.eventsByRemoveKeys[masterKey][uniqueRemoveKey] : this.eventsByRemoveKeys[uniqueRemoveKey]; let dataArr = this.listeners(eventToRemove.eventName); let currentListenerIndex = dataArr.indexOf(eventToRemove.callback); this._events[eventToRemove.eventName].splice(currentListenerIndex, 1); if(0 === this._events[eventToRemove.eventName].length){ delete this._events[eventToRemove.eventName]; } if(masterKey){ delete this.eventsByRemoveKeys[masterKey][uniqueRemoveKey]; Logger.debug('Deleted event by removeKey "'+uniqueRemoveKey+'" and masterKey "'+masterKey+'".'); return true; } delete this.eventsByRemoveKeys[uniqueRemoveKey]; Logger.debug('Deleted event by removeKey "'+uniqueRemoveKey+'".'); return true; } /** * This method will remove ALL the events below the specified masterKey. */ offByMasterKey(masterKey) { if(!sc.hasOwn(this.eventsByRemoveKeys, masterKey)){ Logger.debug('Events not found by masterKey "'+masterKey+'".'); return false; } // @NOTE: we loop all the events related to the masterKey and remove them one by one since the _events property // is an object with multiple listeners attached. Logger.debug('Removing events by masterKey: '+masterKey, Object.keys(this.eventsByRemoveKeys[masterKey])); for(let uniqueRemoveKey of Object.keys(this.eventsByRemoveKeys[masterKey])){ let eventToRemove = this.eventsByRemoveKeys[masterKey][uniqueRemoveKey]; let dataArr = this.listeners(eventToRemove.eventName); let currentListenerIndex = dataArr.indexOf(eventToRemove.callback); this._events[eventToRemove.eventName].splice(currentListenerIndex, 1); if(0 === this._events[eventToRemove.eventName].length){ delete this._events[eventToRemove.eventName]; } } delete this.eventsByRemoveKeys[masterKey]; } on(key, callback) { if(this.debug !== false){ this.logDebugEvent(key, 'Listen'); } super.on(key, callback); } async emit(key, ...args) { if(this.debug !== false){ this.logDebugEvent(key, 'Fire'); } await super.emit(key, ...args); } logDebugEvent(key, type) { if( this.debug.indexOf('all') !== -1 || this.debug.indexOf(key) !== -1 || key.indexOf(this.debug) !== -1 ){ Logger.debug(type+' Event:', key); } } } module.exports = AwaitEventEmitterExtended;