export class ScopedEventEmitter { private listeners: {[key: string]: any[]}; public addEventListener = this.on; constructor() { this.listeners = {}; } public on(name: string, event: string, func: any, once = false): void { if (!func || !event || !name) { throw new Error('missing arguments'); } if (!this.listeners[name]) { this.listeners[name] = []; } this.listeners[name].push({ event, func, name, once, }); } public once(name: string, event: string, func: any): void { this.on(name, event, func, true); } public emit(event: string, ...args: any[]): void { for (const name in this.listeners) { for (const i in this.listeners[name]) { if (!this.listeners[name]) { break; } const listener = this.listeners[name][i]; if (listener.event === event && listener.func) { listener.func(...args); if (listener.once) { this.listeners[name].splice(parseInt(i, 10), 1); } } } } } public emitTo(name: string, event: string, ...args: any[]): void { if (!this.listeners[name]) { return; } for (const i in this.listeners[name]) { if (!this.listeners[name]) { break; } const listener = this.listeners[name][i]; if (listener.event === event && listener.func) { listener.func(...args); if (listener.once) { this.listeners[name].splice(parseInt(i, 10), 1); } } } } public removeName(name: string): void { if (this.listeners[name]) { delete this.listeners[name]; } } }