Last active
August 15, 2021 05:49
-
-
Save zgover/42c0d91adbb9315d883b8a00eb8fae40 to your computer and use it in GitHub Desktop.
[TS/JS MittEmitter] Typed Event Emitter Function Factory #javascript #typescript #mitt #eventemitter #emit #events
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This file is based on https://github.com/developit/mitt/blob/v1.1.3/src/index.js | |
// It's been edited for the needs of this script | |
// See the LICENSE at the top of the file | |
// Event handler callback function | |
type EventHandler = (...events: any[]) => void | |
// Wild card handler function receiving the first parameter as the event name | |
type WildCardEventHandler = (name: string, ...events: any[]) => void | |
// An array of all currently registered event handlers for an event name | |
type EventHandlerList = Array<EventHandler> | |
// An array of all currently registered wildcard event handlers for an event name | |
type WildCardEventHandlerList = Array<WildCardEventHandler> | |
// A map of event types and their corresponding event handlers. | |
type EventHandlerMap = { | |
'*'?: WildCardEventHandlerList, | |
[type: string]: EventHandlerList, | |
} | |
/** | |
* Basic event emitter with on/off/emit listening events. | |
* Concepts include functional event emitting and publish–subscribe | |
* patterns (Pub/Sub) https://cloud.google.com/pubsub/docs/overview | |
*/ | |
export type MittEmitter = { | |
/** | |
* Register an event handler for the given type. | |
* | |
* @example ``` | |
* const handler = (param1: string) => log(txt) | |
* mittEmitter.on('txtChangeEvent', handler) // Same handler used with off() | |
* ``` | |
* @param {string} name RefName/ID of event to listen for, or `"*"` for all events | |
* @param {EventHandler} handler Function to call in response to given event | |
* @memberOf MittEmitter | |
*/ | |
on(name: string, handler: EventHandler): void | |
/** | |
* Remove an event handler for the given type. | |
* | |
* @example ``` | |
* const handler = (param1: string) => log(txt) | |
* mittEmitter.off('txtChangeEvent', handler) // Same handler used with on() | |
* ``` | |
* @see MittEmitter.on | |
* @param {string} name RefName/ID of event to unregister `handler` from, or `"*"` | |
* @param {EventHandler} handler EventHandler function to remove | |
* @memberOf MittEmitter | |
*/ | |
off(name: string, handler: EventHandler): void | |
/** | |
* Invoke all handlers for the given type. | |
* If present, `"*"` handlers are invoked after type-matched handlers. | |
* | |
* @example ```mittEmitter.emit('txtChangeEvent', "Hello world, I'm event param #1")``` | |
* @param {string} type RefName/ID of event to invoke | |
* @param {any[]} events Any rest params (object is recommended and powerful), passed to each handler | |
* @memberOf MittEmitter | |
*/ | |
emit(name: string, ...events: any[]): void | |
} | |
/** | |
* MittEmitter: Small functional event emitter using publish/subscribe (Pub/Sub) pattern. | |
* | |
* @name mittEmitter | |
* @param {EventHandlerMap?} all Existing or default handler map | |
* @returns {MittEmitter} | |
*/ | |
export default function mittEmitter(all?: EventHandlerMap): MittEmitter { | |
all = all || Object.create(null) | |
return { | |
on(name: string, handler: EventHandler) { | |
(all[name] || (all[name] = [])).push(handler) | |
}, | |
off(name: string, handler: EventHandler) { | |
if (all[name]) { | |
all[name].splice(all[name].indexOf(handler) >>> 0, 1) | |
} | |
}, | |
emit(name: string, ...events: any[]) { | |
function handleFn( | |
fn: EventHandler | WildCardEventHandler | null, | |
wild: boolean = false | |
) { | |
if (typeof fn === 'function') { | |
if (wild) { | |
fn(name, ...events) | |
} else { | |
fn(...events) | |
} | |
} | |
} | |
;(all[name] ??= []).slice().map((fn?: EventHandler) => { handleFn(fn) }) | |
;(all['*'] ??= []).slice().map((fn?: WildCardEventHandler) => { handleFn(fn, true) }) | |
} | |
} as MittEmitter | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment