Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | 464x 457x 22x 72x 72x 72x 72x 72x 31x 58x 58x 26x 32x 32x 70x 32x 32x 58x 58x 76x 76x 1x 76x | import { WebSocket } from "ws";
import { WSMessageType, type ServerToClientWSMessage } from "@shared/schema";
type SerialBufferState = {
lines: Array<{ data: string; isComplete: boolean }>;
flushTimer: NodeJS.Timeout | null;
};
export function sendMessageToClient(
ws: WebSocket,
message: ServerToClientWSMessage,
): void {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(message));
}
}
export class WsOutputBuffer {
private readonly clientSerialBuffers = new Map<WebSocket, SerialBufferState>();
sendSerialOutputBatched(
ws: WebSocket,
line: string,
isComplete?: boolean,
): void {
let bufferState = this.clientSerialBuffers.get(ws);
bufferState ??= { lines: [], flushTimer: null };
this.clientSerialBuffers.set(ws, bufferState);
bufferState.lines.push({ data: line, isComplete: isComplete ?? true });
bufferState.flushTimer ??= setTimeout(() => {
this.flushSerialOutputBuffer(ws);
}, 50);
}
flushSerialOutputBuffer(ws: WebSocket): void {
const bufferState = this.clientSerialBuffers.get(ws);
if (!bufferState || bufferState.lines.length === 0) {
return;
}
bufferState.flushTimer = null;
const combinedData = bufferState.lines
.map((lineObj) => (lineObj.isComplete ? `${lineObj.data}\n` : lineObj.data))
.join("");
const lastLine = bufferState.lines.at(-1);
const finalIsComplete = lastLine?.isComplete ?? true;
bufferState.lines = [];
sendMessageToClient(ws, {
type: WSMessageType.SERIAL_OUTPUT,
data: combinedData,
isComplete: finalIsComplete,
});
}
clearClient(ws: WebSocket): void {
const bufferState = this.clientSerialBuffers.get(ws);
if (bufferState?.flushTimer) {
clearTimeout(bufferState.flushTimer);
}
this.clientSerialBuffers.delete(ws);
}
}
|