/** * Cookie Consent Core * events.js * * Tiny dependency-free event bus. */ export function createEventBus() { const listeners = new Map(); function on(eventName, callback) { if (typeof eventName !== "string" || !eventName.trim()) { throw new TypeError("eventName must be a non-empty string."); } if (typeof callback !== "function") { throw new TypeError("callback must be a function."); } if (!listeners.has(eventName)) { listeners.set(eventName, new Set()); } listeners.get(eventName).add(callback); return () => off(eventName, callback); } function once(eventName, callback) { const unsubscribe = on(eventName, (payload) => { unsubscribe(); callback(payload); }); return unsubscribe; } function off(eventName, callback) { const callbacks = listeners.get(eventName); if (!callbacks) { return false; } const removed = callbacks.delete(callback); if (callbacks.size === 0) { listeners.delete(eventName); } return removed; } function emit(eventName, payload) { const callbacks = listeners.get(eventName); if (!callbacks) { return; } [...callbacks].forEach((callback) => { try { callback(payload); } catch (error) { queueMicrotask(() => { throw error; }); } }); } function clear(eventName) { if (typeof eventName === "string") { listeners.delete(eventName); return; } listeners.clear(); } function listenerCount(eventName) { return listeners.get(eventName)?.size || 0; } return Object.freeze({ on, once, off, emit, clear, listenerCount }); } export const EVENT_NAMES = Object.freeze([ "initialized", "consent:loaded", "consent:accepted", "consent:rejected", "consent:changed", "consent:revoked", "consent:expired", "consent:reset", "storage:error" ]);