import { Arr } from '@ephox/katamari'; export type EventHandler = (event: T) => void; export interface Bindable { bind: (handler: EventHandler) => void; unbind: (handler: EventHandler) => void; } export interface Event extends Bindable { trigger: (...values: any[]) => void; } export const Event = (fields: string[]): Event => { let handlers: EventHandler[] = []; const bind = (handler: EventHandler) => { if (handler === undefined) { throw new Error('Event bind error: undefined handler'); } handlers.push(handler); }; const unbind = (handler: EventHandler) => { // This is quite a bit slower than handlers.splice() but we hate mutation. // Unbind isn't used very often so it should be ok. handlers = Arr.filter(handlers, (h) => { return h !== handler; }); }; const trigger = (...args: T[]) => { const event: Record = {}; Arr.each(fields, (name, i) => { event[name] = args[i]; }); Arr.each(handlers, (handler) => { handler(event); }); }; return { bind, unbind, trigger }; };