UNPKG

simple-event-target

Version:

Thinnest possible wrapper around native events. It simplifies typing the custom event detail

42 lines (41 loc) 1.47 kB
const eventType = 'batik'; /** * Thinnest possible wrapper around native events * * @usage * const smokeSignals = new SimpleEventTarget(); * smokeSignals.subscribe(details => console.log(details)) * smokeSignals.emit('The BBQ is ready'); */ export default class SimpleEventTarget { /** * @deprecated Only for advanced use cases. Using this will break the type safety. */ get raw() { return { eventType, eventTarget: this.#target }; } #target = new EventTarget(); #weakListeners = new WeakMap(); subscribe(callback, options) { this.#target.addEventListener(eventType, this.#getNativeListener(callback), options); } unsubscribe(callback) { this.#target.removeEventListener(eventType, this.#getNativeListener(callback)); } emit(detail) { this.#target.dispatchEvent(new CustomEvent(eventType, { detail })); } // Permanently map simplified callbacks to native listeners. // This acts as a memoization/deduplication which matches the native behavior. // Calling `subscribe(cb); subscribe(cb); unsubscribe(cb)` should only add it once and remove it once. #getNativeListener(callback) { if (this.#weakListeners.has(callback)) { return this.#weakListeners.get(callback); } const native = ((event) => { callback(event.detail); }); this.#weakListeners.set(callback, native); return native; } }