UNPKG

mocha-multiple-sessions-detailed-runner

Version:
184 lines (154 loc) 5.92 kB
import type { IUnifiedEventBus, EventFilter } from '../../interfaces/events/unified-event-bus'; import type { RunnerEvent, RunnerEventType } from '../../interfaces/events/runner-events'; import type { SessionEvent, SessionEventType } from '../../interfaces/events/session-events'; export class UnifiedEventBus implements IUnifiedEventBus { private runnerListeners = new Map<RunnerEventType, Set<(event: RunnerEvent) => void>>(); private sessionListeners = new Map<SessionEventType, Set<(event: SessionEvent) => void>>(); private anyEventListeners = new Set<(event: RunnerEvent | SessionEvent) => void>(); private eventHistory: (RunnerEvent | SessionEvent)[] = []; private readonly maxHistorySize = 1000; emitRunnerEvent(event: RunnerEvent): void { // Add to history this.addToHistory(event); // Emit to specific listeners const listeners = this.runnerListeners.get(event.type); if (listeners) { listeners.forEach(callback => { try { callback(event); } catch (error) { console.error('Error in runner event listener:', error); } }); } // Emit to universal listeners this.anyEventListeners.forEach(callback => { try { callback(event); } catch (error) { console.error('Error in universal event listener:', error); } }); } onRunnerEvent(eventType: RunnerEventType, callback: (event: RunnerEvent) => void): () => void { if (!this.runnerListeners.has(eventType)) { this.runnerListeners.set(eventType, new Set()); } this.runnerListeners.get(eventType)!.add(callback); // Return unsubscribe function return () => { const listeners = this.runnerListeners.get(eventType); if (listeners) { listeners.delete(callback); if (listeners.size === 0) { this.runnerListeners.delete(eventType); } } }; } emitSessionEvent(event: SessionEvent): void { // Add to history this.addToHistory(event); // Emit to specific listeners const listeners = this.sessionListeners.get(event.type); if (listeners) { listeners.forEach(callback => { try { callback(event); } catch (error) { console.error('Error in session event listener:', error); } }); } // Emit to universal listeners this.anyEventListeners.forEach(callback => { try { callback(event); } catch (error) { console.error('Error in universal event listener:', error); } }); } onSessionEvent(eventType: SessionEventType, callback: (event: SessionEvent) => void): () => void { if (!this.sessionListeners.has(eventType)) { this.sessionListeners.set(eventType, new Set()); } this.sessionListeners.get(eventType)!.add(callback); // Return unsubscribe function return () => { const listeners = this.sessionListeners.get(eventType); if (listeners) { listeners.delete(callback); if (listeners.size === 0) { this.sessionListeners.delete(eventType); } } }; } onAnyEvent(callback: (event: RunnerEvent | SessionEvent) => void): () => void { this.anyEventListeners.add(callback); // Return unsubscribe function return () => { this.anyEventListeners.delete(callback); }; } getEventHistory(filter?: EventFilter): (RunnerEvent | SessionEvent)[] { let filtered = [...this.eventHistory]; if (filter) { if (filter.eventTypes) { filtered = filtered.filter(event => filter.eventTypes!.includes(event.type as any)); } if (filter.sessionLabel) { filtered = filtered.filter(event => 'sessionLabel' in event && event.sessionLabel === filter.sessionLabel ); } if (filter.timeRange) { filtered = filtered.filter(event => { const eventTime = new Date(event.timestamp); return eventTime >= filter.timeRange!.start && eventTime <= filter.timeRange!.end; }); } if (filter.maxEvents) { filtered = filtered.slice(-filter.maxEvents); } } return filtered; } clearEventHistory(): void { this.eventHistory = []; } hasListeners(eventType?: RunnerEventType | SessionEventType): boolean { if (!eventType) { return this.runnerListeners.size > 0 || this.sessionListeners.size > 0 || this.anyEventListeners.size > 0; } return (this.runnerListeners.get(eventType as RunnerEventType)?.size || 0) > 0 || (this.sessionListeners.get(eventType as SessionEventType)?.size || 0) > 0; } getListenerCount(eventType?: RunnerEventType | SessionEventType): number { if (!eventType) { let total = this.anyEventListeners.size; this.runnerListeners.forEach(listeners => total += listeners.size); this.sessionListeners.forEach(listeners => total += listeners.size); return total; } const runnerCount = this.runnerListeners.get(eventType as RunnerEventType)?.size || 0; const sessionCount = this.sessionListeners.get(eventType as SessionEventType)?.size || 0; return runnerCount + sessionCount; } destroy(): void { this.runnerListeners.clear(); this.sessionListeners.clear(); this.anyEventListeners.clear(); this.eventHistory = []; } private addToHistory(event: RunnerEvent | SessionEvent): void { this.eventHistory.push(event); // Trim history if it gets too large if (this.eventHistory.length > this.maxHistorySize) { this.eventHistory = this.eventHistory.slice(-this.maxHistorySize); } } }