Files
cookie-consent-jurisdiction…/core/events.js
T

105 lines
2.2 KiB
JavaScript

/**
* 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"
]);