// server/ws/outputHub.ts type Listener = (chunk: string) => void; const MAX_BUFFER = 5000; // lignes/chunks gardés pour le rejeu export class OutputHub { private buffers = new Map(); private listeners = new Map>(); publish(machineId: string, chunk: string): void { const buf = this.buffers.get(machineId) ?? []; buf.push(chunk); if (buf.length > MAX_BUFFER) buf.shift(); this.buffers.set(machineId, buf); this.listeners.get(machineId)?.forEach((l) => l(chunk)); } /** S'abonne et reçoit immédiatement le buffer existant (rejeu). */ subscribe(machineId: string, listener: Listener): () => void { (this.buffers.get(machineId) ?? []).forEach((c) => listener(c)); const set = this.listeners.get(machineId) ?? new Set(); set.add(listener); this.listeners.set(machineId, set); return () => set.delete(listener); } clear(machineId: string): void { this.buffers.delete(machineId); } } export const outputHub = new OutputHub();