UNPKG

t0n

Version:

Collection of elegant typescript resources for web artisans

107 lines (82 loc) 2.74 kB
const emitter = new EventTarget() const listeners = new Map<string, Map<Function, EventListener>>() export const getEvents = () => Array.from(listeners.keys()) const getListeners = (event: string) => { if (!listeners.has(event)) { listeners.set(event, new Map()) } return listeners.get(event)! } const createHandler = <E>(callback: (detail: E) => void): EventListener => (e: Event) => callback((e as CustomEvent<E>).detail) export const emit = <D = unknown>( event: string, detail?: D ) => emitter.dispatchEvent(new CustomEvent(event, detail ? { detail } : undefined)) export const on = <D = unknown>( event: string, callback: (detail: D) => void ): () => void => { const handler = createHandler<D>(callback) getListeners(event).set(callback, handler) emitter.addEventListener(event, handler) return () => off(event, callback) } export const once = <D = unknown>( event: string, callback: (detail: D) => void ) => { const handler: EventListener = (e: Event) => { callback((e as CustomEvent<D>).detail) const eventListeners = listeners.get(event) if (eventListeners) { eventListeners.delete(callback) if (eventListeners.size === 0) listeners.delete(event) } } getListeners(event).set(callback, handler) emitter.addEventListener(event, handler, { once: true }) return () => off(event, callback) } export const off = <D = unknown>( event: string, callback?: (detail: D) => void ) => { if (!callback) return removeAll(event) const eventListeners = listeners.get(event) if (!eventListeners) return const handler = eventListeners.get(callback) if (handler) { emitter.removeEventListener(event, handler) eventListeners.delete(callback) if (eventListeners.size === 0) listeners.delete(event) } } export const removeAll = (event: string) => { const eventListeners = listeners.get(event) if (!eventListeners) return for (const [, handler] of eventListeners) emitter.removeEventListener(event, handler) listeners.delete(event) } export const clearAll = () => { for (const [event, eventListeners] of listeners) { for (const [, handler] of eventListeners) emitter.removeEventListener(event, handler) } listeners.clear() } export const hasListener = (event: string, callback?: Function) => { const eventListeners = listeners.get(event) if (!eventListeners) return false return callback ? eventListeners.has(callback) : eventListeners.size > 0 } export const countEvent = (event?: string) => { if (event) return listeners.get(event)?.size ?? 0 let total = 0 for (const [, eventListeners] of listeners) total += eventListeners.size return total }