From 2b1a7660b69f0aba2d71c219bbebb1539c281a1b Mon Sep 17 00:00:00 2001 From: SuperComboGamer Date: Sat, 20 Dec 2025 23:02:31 -0500 Subject: [PATCH] refactor: update terminal session limits and improve layout saving - Refactored session limit checks in terminal settings to use constants for minimum and maximum session values. - Enhanced terminal layout saving mechanism with debouncing to prevent excessive writes during rapid changes. - Updated error messages to reflect new session limit constants. --- .../src/routes/terminal/routes/settings.ts | 6 +++--- apps/server/src/services/terminal-service.ts | 6 +++++- apps/ui/src/components/views/terminal-view.tsx | 18 ++++++++++++++++-- package-lock.json | 2 +- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/apps/server/src/routes/terminal/routes/settings.ts b/apps/server/src/routes/terminal/routes/settings.ts index 9bd493c8..f4d6c007 100644 --- a/apps/server/src/routes/terminal/routes/settings.ts +++ b/apps/server/src/routes/terminal/routes/settings.ts @@ -3,7 +3,7 @@ */ import type { Request, Response } from "express"; -import { getTerminalService } from "../../../services/terminal-service.js"; +import { getTerminalService, MIN_MAX_SESSIONS, MAX_MAX_SESSIONS } from "../../../services/terminal-service.js"; import { getErrorMessage, logError } from "../common.js"; export function createSettingsGetHandler() { @@ -26,10 +26,10 @@ export function createSettingsUpdateHandler() { const { maxSessions } = req.body; if (typeof maxSessions === "number") { - if (maxSessions < 1 || maxSessions > 500) { + if (maxSessions < MIN_MAX_SESSIONS || maxSessions > MAX_MAX_SESSIONS) { res.status(400).json({ success: false, - error: "maxSessions must be between 1 and 500", + error: `maxSessions must be between ${MIN_MAX_SESSIONS} and ${MAX_MAX_SESSIONS}`, }); return; } diff --git a/apps/server/src/services/terminal-service.ts b/apps/server/src/services/terminal-service.ts index 8d671f79..4d506d25 100644 --- a/apps/server/src/services/terminal-service.ts +++ b/apps/server/src/services/terminal-service.ts @@ -13,6 +13,10 @@ import * as fs from "fs"; // Maximum scrollback buffer size (characters) const MAX_SCROLLBACK_SIZE = 50000; // ~50KB per terminal +// Session limit constants - shared with routes/settings.ts +export const MIN_MAX_SESSIONS = 1; +export const MAX_MAX_SESSIONS = 500; + // Maximum number of concurrent terminal sessions // Can be overridden via TERMINAL_MAX_SESSIONS environment variable // Default set to 1000 - effectively unlimited for most use cases @@ -200,7 +204,7 @@ export class TerminalService extends EventEmitter { * Set maximum allowed sessions (can be called dynamically) */ setMaxSessions(limit: number): void { - if (limit >= 1 && limit <= 500) { + if (limit >= MIN_MAX_SESSIONS && limit <= MAX_MAX_SESSIONS) { maxSessions = limit; console.log(`[Terminal] Max sessions limit updated to ${limit}`); } diff --git a/apps/ui/src/components/views/terminal-view.tsx b/apps/ui/src/components/views/terminal-view.tsx index 8c405d13..4d801e42 100644 --- a/apps/ui/src/components/views/terminal-view.tsx +++ b/apps/ui/src/components/views/terminal-view.tsx @@ -627,12 +627,26 @@ export function TerminalView() { } }, [currentProject?.path, saveTerminalLayout, getPersistedTerminalLayout, clearTerminalState, addTerminalTab, serverUrl]); - // Save terminal layout whenever it changes (debounced via the effect) + // Save terminal layout whenever it changes (debounced to prevent excessive writes) // Also save when tabs become empty so closed terminals stay closed on refresh + const saveLayoutTimeoutRef = useRef(null); useEffect(() => { if (currentProject?.path && !isRestoringLayoutRef.current) { - saveTerminalLayout(currentProject.path); + // Debounce saves to prevent excessive localStorage writes during rapid changes + if (saveLayoutTimeoutRef.current) { + clearTimeout(saveLayoutTimeoutRef.current); + } + saveLayoutTimeoutRef.current = setTimeout(() => { + saveTerminalLayout(currentProject.path); + saveLayoutTimeoutRef.current = null; + }, 500); // 500ms debounce } + + return () => { + if (saveLayoutTimeoutRef.current) { + clearTimeout(saveLayoutTimeoutRef.current); + } + }; }, [terminalState.tabs, currentProject?.path, saveTerminalLayout]); // Handle password authentication diff --git a/package-lock.json b/package-lock.json index c2221d93..149743db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1005,7 +1005,7 @@ }, "node_modules/@electron/node-gyp": { "version": "10.2.0-electron.1", - "resolved": "git+ssh://git@github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "resolved": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", "integrity": "sha512-4MSBTT8y07YUDqf69/vSh80Hh791epYqGtWHO3zSKhYFwQg+gx9wi1PqbqP6YqC4WMsNxZ5l9oDmnWdK5pfCKQ==", "dev": true, "license": "MIT",