Files
bitvid/js/utils/eventEmitter.js
T
google-labs-jules[bot]andPR0M3TH3AN c6b7d5ab32 🧹 Centralize SimpleEventEmitter class
Extract duplicated SimpleEventEmitter class from multiple service files into a shared utility file `js/utils/eventEmitter.js`.

- Created `js/utils/eventEmitter.js` with unified implementation.
- Refactored `AuthService`, `NostrService`, `ModerationService`, and `PlaybackService` to use the shared class.
- Added support for constructor-defined context strings for improved error logging.
- Added comprehensive unit tests for `SimpleEventEmitter`.
- Verified changes with targeted service tests.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 03:08:07 +00:00

66 lines
1.8 KiB
JavaScript

/**
* A lightweight event emitter used by services to communicate state changes
* and other events to the UI and other parts of the application.
*/
export class SimpleEventEmitter {
/**
* @param {Function|null} logger - Optional logger function for error reporting.
* @param {string} context - Optional context string for error messages.
*/
constructor(logger = null, context = "SimpleEventEmitter") {
this.logger = typeof logger === "function" ? logger : null;
this.context = typeof context === "string" ? context : "SimpleEventEmitter";
this.listeners = new Map();
}
/**
* Registers a handler for a specific event.
* @param {string} eventName
* @param {Function} handler
* @returns {Function} Unsubscribe function.
*/
on(eventName, handler) {
if (typeof handler !== "function") {
return () => {};
}
if (!this.listeners.has(eventName)) {
this.listeners.set(eventName, new Set());
}
const handlers = this.listeners.get(eventName);
handlers.add(handler);
return () => {
handlers.delete(handler);
if (!handlers.size) {
this.listeners.delete(eventName);
}
};
}
/**
* Emits an event to all registered handlers.
* @param {string} eventName
* @param {any} detail
*/
emit(eventName, detail) {
const handlers = this.listeners.get(eventName);
if (!handlers || !handlers.size) {
return;
}
for (const handler of Array.from(handlers)) {
try {
handler(detail);
} catch (error) {
if (this.logger) {
try {
this.logger(`${this.context} listener for "${eventName}" threw`, error);
} catch (logError) {
// Fallback if the provided logger itself throws
console.warn(`[${this.context}] listener logger threw`, logError);
}
}
}
}
}
}