type Listener = (event: FightEvent) => void export interface FightEvent { fightId: string type: string data: Record timestamp: string } class EventBus { private listeners = new Map>() private globalListeners = new Set() on(fightId: string, listener: Listener) { if (!this.listeners.has(fightId)) { this.listeners.set(fightId, new Set()) } this.listeners.get(fightId)!.add(listener) return () => this.off(fightId, listener) } onAll(listener: Listener) { this.globalListeners.add(listener) return () => this.globalListeners.delete(listener) } off(fightId: string, listener: Listener) { this.listeners.get(fightId)?.delete(listener) } emit(event: FightEvent) { this.listeners.get(event.fightId)?.forEach(fn => fn(event)) this.globalListeners.forEach(fn => fn(event)) } cleanup(fightId: string) { this.listeners.delete(fightId) } } export const fightEvents = new EventBus()