type EventDeclaration = Record; type Handler = (...params: T[K]) => void; /** * Basic event broker class. Provides `on`, `off`, and `emit` methods. */ export class EventEmitter { constructor() { this.on = this.on.bind(this); this.off = this.off.bind(this); } protected handlers: any = {}; protected getHandlers(event: E) { return (this.handlers[event] || []) as Handler[]; } emit(event: E, params: T[E]) { const handlers = this.getHandlers(event); for (let h of handlers) { h(...params); } } on(event: E, f: Handler) on(events: E[], f: Handler) // on(events: E[], f: (event: E, ...args: T[E]) => void) on(event, f) { if (!Array.isArray(event)) event = [event]; for (let e of event) { this.handlers[e] ||= []; const handlers = this.getHandlers(e); if (!handlers.includes(f)) { handlers.push(f); } } return () => this.off(event, f); } off(event: E, f: Handler) off(events: E[], f: Handler) off(event, f: Handler) { if (!Array.isArray(event)) event = [event]; for (let e of event) { const handlers = this.getHandlers(e); const idx = handlers.indexOf(f); if (idx >= 0) handlers.splice(idx, 1); } } }