// Core EventBus using pure DOM CustomEvents import { EventLogEntry, ListenerEntry, IEventBus } from '../types/CalendarTypes'; /** * Central event dispatcher for calendar using DOM CustomEvents * Provides logging and debugging capabilities */ export class EventBus implements IEventBus { private eventLog: EventLogEntry[] = []; private debug: boolean = false; private listeners: Set = new Set(); /** * Subscribe to an event via DOM addEventListener */ on(eventType: string, handler: EventListener, options?: AddEventListenerOptions): () => void { document.addEventListener(eventType, handler, options); // Track for cleanup this.listeners.add({ eventType, handler, options }); // Return unsubscribe function return () => this.off(eventType, handler); } /** * Subscribe to an event once */ once(eventType: string, handler: EventListener): () => void { return this.on(eventType, handler, { once: true }); } /** * Unsubscribe from an event */ off(eventType: string, handler: EventListener): void { document.removeEventListener(eventType, handler); // Remove from tracking for (const listener of this.listeners) { if (listener.eventType === eventType && listener.handler === handler) { this.listeners.delete(listener); break; } } } /** * Emit an event via DOM CustomEvent */ emit(eventType: string, detail: any = {}): boolean { const event = new CustomEvent(eventType, { detail, bubbles: true, cancelable: true }); // Log event if (this.debug) { console.log(`📢 Event: ${eventType}`, detail); } this.eventLog.push({ type: eventType, detail, timestamp: Date.now() }); // Emit on document (only DOM events now) return !document.dispatchEvent(event); } /** * Get event history */ getEventLog(eventType?: string): EventLogEntry[] { if (eventType) { return this.eventLog.filter(e => e.type === eventType); } return this.eventLog; } /** * Enable/disable debug mode */ setDebug(enabled: boolean): void { this.debug = enabled; } /** * Clean up all tracked listeners */ destroy(): void { for (const listener of this.listeners) { document.removeEventListener(listener.eventType, listener.handler); } this.listeners.clear(); this.eventLog = []; } } // Create singleton instance export const eventBus = new EventBus();