/** * copy to https://github.com/developit/mitt * Expand clear method */ 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 export type WildcardHandler = (type: EventType, event?: any) => void // An array of all currently registered event handlers for a type export type EventHandlerList = Array export type WildCardEventHandlerList = Array // A map of event types and their corresponding event handlers. export type EventHandlerMap = Map export interface Emitter { all: EventHandlerMap on(type: EventType, handler: Handler): void on(type: '*', handler: WildcardHandler): void off(type: EventType, handler: Handler): void off(type: '*', handler: WildcardHandler): void emit(type: EventType, event?: T): void emit(type: '*', event?: any): void clear(): void } /** * Mitt: Tiny (~200b) functional event emitter / pubsub. * @name mitt * @returns {Mitt} 1 */ export function mitt(all?: EventHandlerMap): Emitter { all = all || new Map() return { /** * A Map of event names to registered handler functions. */ all, /** * Register an event handler for the given type. * @param {string|symbol} type Type of event to listen for, or `"*"` for all events * @param {Function} handler Function to call in response to given event * @memberOf mitt */ on(type: EventType, handler: Handler) { const handlers = all?.get(type) const added = handlers && handlers.push(handler) if (!added) all?.set(type, [handler]) }, /** * Remove an event handler for the given type. * @param {string|symbol} type Type of event to unregister `handler` from, or `"*"` * @param {Function} handler Handler function to remove * @memberOf mitt */ off(type: EventType, handler: Handler) { const handlers = all?.get(type) if (handlers) handlers.splice(handlers.indexOf(handler) >>> 0, 1) }, /** * Invoke all handlers for the given type. * If present, `"*"` handlers are invoked after type-matched handlers. * * Note: Manually firing "*" handlers is not supported. * * @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: EventType, evt: T) { // map ((all?.get(type) || []) as EventHandlerList).slice().forEach((handler) => { handler(evt) }); // map ((all?.get('*') || []) as WildCardEventHandlerList).slice().forEach((handler) => { handler(type, evt) }) }, /** * Clear all */ clear() { this.all.clear() }, } }