UNPKG

retrobus

Version:

An event bus that allows listeners to be retroactive

103 lines (102 loc) 3.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createEventBus = exports.clearEmittedEvents = exports.emit = exports.clearEventBusListeners = exports.removeEventBusListener = exports.addEventBusListener = void 0; const CACHE_EMITTED_EVENT_LIMIT = 1000; const emittedEvents = new Map(); const eventListeners = new Map(); const defaultOptions = { retro: false, retroStrategy: 'last-one', once: false, unique: false }; const addEventBusListener = (name, callback, options = defaultOptions) => { const unsubscribe = () => (0, exports.removeEventBusListener)(name, callback); const listeners = eventListeners.get(name); if (options.retro && emittedEvents.has(name)) { const emittedEventArgs = emittedEvents.get(name); switch (options.retroStrategy) { case 'all': { for (const args of emittedEventArgs) { callback(...args); } break; } case 'last-one': default: { const args = emittedEventArgs[emittedEventArgs.length - 1]; callback(...args); break; } } if (options.once) { return unsubscribe; } } const listener = Object.assign({ callback }, options); if (!listeners) { eventListeners.set(name, [listener]); return unsubscribe; } if (options.unique && listeners.find((c) => c.callback === callback)) { return unsubscribe; } eventListeners.set(name, listeners.concat([listener])); return unsubscribe; }; exports.addEventBusListener = addEventBusListener; const removeEventBusListener = (name, callback) => { const calls = eventListeners.get(name); if (!calls) { return; } eventListeners.set(name, calls.filter((call) => call.callback !== callback)); }; exports.removeEventBusListener = removeEventBusListener; const clearEventBusListeners = (name) => { if (name === undefined) { eventListeners.clear(); return; } eventListeners.delete(name); }; exports.clearEventBusListeners = clearEventBusListeners; const getLimitedHistoryOfEmittedEventArgs = (emittedEventArgs) => { if (emittedEventArgs.length > CACHE_EMITTED_EVENT_LIMIT) { return [...emittedEventArgs.slice(-CACHE_EMITTED_EVENT_LIMIT)]; } return emittedEventArgs; }; const emit = (name, ...args) => { const listeners = eventListeners.get(name); if (emittedEvents.has(name)) { const emittedEventArgs = emittedEvents.get(name); emittedEvents.set(name, getLimitedHistoryOfEmittedEventArgs(emittedEventArgs.concat([args]))); } else { emittedEvents.set(name, [args]); } if (!listeners) { return; } listeners.map((call) => call.callback(...args)); eventListeners.set(name, listeners.filter((call) => !call.once)); }; exports.emit = emit; const clearEmittedEvents = (name) => { if (name === undefined) { emittedEvents.clear(); return; } emittedEvents.delete(name); }; exports.clearEmittedEvents = clearEmittedEvents; const createEventBus = (event = Symbol()) => { return { emit: (payload) => (0, exports.emit)(event, payload), clearEmittedEvents: () => (0, exports.clearEmittedEvents)(event), addEventBusListener: (callback, options) => (0, exports.addEventBusListener)(event, callback, options), clearEventBusListeners: () => (0, exports.clearEventBusListeners)(event) }; }; exports.createEventBus = createEventBus;