UNPKG

birch-event-emitter

Version:
98 lines (82 loc) 2.13 kB
type Disposer = () => void type Listener = (...args: any[]) => any export interface IDisposable { dispose(...args) } export class Disposable { private disposer: Disposer constructor(disposer: Disposer) { this.disposer = disposer } dispose(...args) { this.disposer.apply(this.disposer, args) } } export class DisposablesComposite { private disposables: Set<Disposable> constructor() { this.disposables = new Set() } add(disposable) { this.disposables.add(disposable) return disposable } dispose(...args) { this.disposables.forEach(disposable => { disposable.dispose.apply(disposable, args) }) this.disposables = new Set() } } export class EventEmitter<T> { private listeners: Map<T, Set<Listener>> private onceListeners: Map<T, Set<Listener>> constructor() { this.listeners = new Map() this.onceListeners = new Map() } emit(event: T, ...args) { const callbacks = this.listeners.get(event) if (callbacks) { callbacks.forEach(cb => cb(...args)) } const onceCallbacks = this.onceListeners.get(event) if (onceCallbacks) { onceCallbacks.forEach(cb => cb(...args)) this.onceListeners.delete(event) } } on(event: T, cb: Listener) { if (!this.listeners.has(event)) { this.listeners.set(event, new Set()) } const existing = this.listeners.get(event)! existing.add(cb) return new Disposable(() => { existing.delete(cb) }) } once(event: T, cb: Listener) { if (!this.onceListeners.has(event)) { this.onceListeners.set(event, new Set()) } const existing = this.onceListeners.get(event)! existing.add(cb) return new Disposable(() => { existing.delete(cb) }) } emitWithReturn<K>(event: T, ...args): K[] { const callbacks = Array.from(this.listeners.get(event) || []) return callbacks.map(cb => cb(...args)) } clear(event?: T) { if (event) { this.listeners.delete(event) this.onceListeners.delete(event) } else { this.listeners.clear() this.onceListeners.clear() } } }