export type EventType = string | symbol; // An event handler can take an optional event argument // and should not return a value export type Handler = (event: T) => void; // An array of all currently registered event handlers for a type export type EventHandlerList = Array>; // A map of event types and their corresponding event handlers. export type EventHandlerMap> = Map< keyof Events, EventHandlerList >; export class Emitter> { /** * A Map of event names to registered handler functions. */ public all: EventHandlerMap; public constructor() { this.all = new Map(); } public resetAll() { this.all = new Map(); } public reset(type: Key) { this.all!.set(type, [] as EventHandlerList); } /** * Register an event handler for the given type. * @param {string|symbol} type Type of event to listen for * @param {Function} handler Function to call in response to given event * @memberOf mitt */ public on(type: Key, handler: Handler) { const handlers: Array> | undefined = this.all!.get(type); if (handlers) { handlers.push(handler); } else { this.all!.set(type, [handler] as EventHandlerList); } } /** * Remove an event handler for the given type. * If `handler` is omitted, all handlers of the given type are removed. * @param {string|symbol} type Type of event to unregister `handler` from * @param {Function} [handler] Handler function to remove * @memberOf mitt */ public off(type: Key, handler?: Handler) { const handlers: Array> | undefined = this.all!.get(type); if (handlers) { if (handler) { handlers.splice(handlers.indexOf(handler) >>> 0, 1); } else { this.all!.set(type, []); } } } /** * Invoke all handlers for the given type. * * @param {string|symbol} type The event type to invoke * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler * @memberOf mitt */ emit(type: Key, evt: Events[Key]) { let handlers = this.all!.get(type); if (handlers) { (handlers as EventHandlerList) .slice() .map((handler) => { handler(evt!); }); } } }