Integrate terminal emulator in server.ts (Phase 1)

This commit is contained in:
Jared Miller 2026-01-31 09:45:38 -05:00
parent c9908c87c3
commit 0366e459f5
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C

View file

@ -19,6 +19,7 @@ import {
updateLastSeen,
updateSessionStats,
} from "./db";
import { createTerminal, disposeTerminal, type TerminalSession } from "./terminal";
import type {
AnswerResponse,
ClientMessage,
@ -33,6 +34,7 @@ const sessionWebSockets = new Map<number, ServerWebSocket<SessionData>>();
const sessionStates = new Map<number, SessionState>();
// Buffer for incomplete ANSI sequences per session to avoid leaking partial control codes
const ansiCarryovers = new Map<number, string>();
const sessionTerminals = new Map<number, TerminalSession>();
interface SessionData {
deviceId: number;
@ -437,6 +439,10 @@ const server = Bun.serve<SessionData>({
// Initialize in-memory session state
sessionStates.set(session.id, createDefaultSessionState());
// Create terminal emulator with default size (will be resized later)
const termSession = createTerminal(80, 24);
sessionTerminals.set(session.id, termSession);
console.debug(
`Session ${session.id} started for device ${device.id}`,
);
@ -506,6 +512,12 @@ const server = Bun.serve<SessionData>({
appendOutput(sessionId, body); // Store raw ANSI without trailing incomplete fragment
// Write to terminal emulator
const termSession = sessionTerminals.get(sessionId);
if (termSession) {
termSession.terminal.write(msg.data);
}
broadcastSSE({
type: "output",
session_id: sessionId,
@ -615,6 +627,13 @@ const server = Bun.serve<SessionData>({
console.debug(
`Session ${ws.data.sessionId} resized to ${msg.cols}x${msg.rows}`,
);
// Resize terminal emulator
const termSession = sessionTerminals.get(ws.data.sessionId);
if (termSession) {
termSession.terminal.resize(msg.cols, msg.rows);
}
return;
}
@ -654,6 +673,13 @@ const server = Bun.serve<SessionData>({
sessionWebSockets.delete(ws.data.sessionId);
ansiCarryovers.delete(ws.data.sessionId);
// Dispose terminal emulator
const termSession = sessionTerminals.get(ws.data.sessionId);
if (termSession) {
disposeTerminal(termSession);
sessionTerminals.delete(ws.data.sessionId);
}
// Persist final state before cleanup
const state = sessionStates.get(ws.data.sessionId);
if (state?.dirty) {