diff --git a/src/emitter.ts b/src/emitter.ts index be0e2bf..87f2879 100644 --- a/src/emitter.ts +++ b/src/emitter.ts @@ -1,28 +1,33 @@ -export type Listener = (event: T) => any; +export type Listener = (...args: any[]) => any; +export type TypedEvents = {[k in string | symbol]: Listener} & {'*': (event: string, ...args: any[]) => any}; -export class Emitter { - private listeners: {[key: string]: Listener} = {}; +export class TypedEmitter { + private listeners: { [key in keyof T]?: Function[] } = {}; - constructor() { } + emit(event: K, ...args: Parameters) { + (this.listeners['*'] || []).forEach(l => l(event, ...args)); + (this.listeners[event] || []).forEach(l => l(...args)); + }; - emit(e: T) { - Object.values(this.listeners).forEach(l => l(e)); + off(event: K, listener: T[K]): this { + console.log('cleared'); + this.listeners[event] = (this.listeners[event] || []).filter(l => l === listener); + return this; } - listen(fn: Listener): () => {}; - listen(key: string, fn: Listener): () => {}; - listen(keyOrFn: string | Listener, fn?: Listener): () => {} { - const func: any = fn ? fn : keyOrFn; - const key: string = typeof keyOrFn == 'string' ? keyOrFn : - `_${Object.keys(this.listeners).length.toString()}`; - this.listeners[key] = func; - return () => delete this.listeners[key]; + on(event: K, listener: T[K]) { + if(!this.listeners[event]) this.listeners[event] = []; + this.listeners[event]?.push(listener); + return () => this.off(event, listener); } - once(fn: Listener) { - const stop = this.listen(e => { - fn(e); - stop(); + once(event: K, listener?: T[K]): Promise { + return new Promise(res => { + const unsubscribe = this.on(event, ((...args: any) => { + res(args.length == 1 ? args[0] : args); + if(listener) listener(...args); + unsubscribe(); + })); }); } }