Fix dashboard to handle terminal serialization output
The server's serializeAsHTML() returns the full terminal screen state, not incremental chunks. Updated the dashboard to: 1. Handle initial_state event to receive current terminal state on connection 2. Replace output instead of appending (output event now replaces session.output) 3. Simplify renderSessionOutput() to always do full innerHTML replacement This fixes the issue where output was being duplicated/appended incorrectly.
This commit is contained in:
parent
130f01a19f
commit
6bd599d47b
1 changed files with 16 additions and 23 deletions
|
|
@ -1133,11 +1133,23 @@
|
|||
renderSessions();
|
||||
});
|
||||
|
||||
es.addEventListener('initial_state', (e) => {
|
||||
const data = JSON.parse(e.data);
|
||||
const session = state.sessions.get(data.session_id);
|
||||
if (session) {
|
||||
// Replace output with current terminal state
|
||||
session.output = data.html;
|
||||
session.outputRenderedLength = 0; // Force re-render
|
||||
renderSessionOutput(data.session_id);
|
||||
}
|
||||
});
|
||||
|
||||
es.addEventListener('output', (e) => {
|
||||
const data = JSON.parse(e.data);
|
||||
const session = state.sessions.get(data.session_id);
|
||||
if (session) {
|
||||
session.output += data.data;
|
||||
session.output = data.data; // Replace, not append
|
||||
session.outputRenderedLength = 0; // Force full re-render
|
||||
renderSessionOutput(data.session_id);
|
||||
}
|
||||
});
|
||||
|
|
@ -1422,28 +1434,9 @@
|
|||
|
||||
const $output = document.getElementById(`output-${sessionId}`);
|
||||
if ($output) {
|
||||
// Append only new content since last render
|
||||
const newChunk = session.output.slice(session.outputRenderedLength);
|
||||
if (newChunk) {
|
||||
// More efficient than innerHTML += as it avoids reparsing existing content
|
||||
$output.insertAdjacentHTML('beforeend', newChunk);
|
||||
session.outputRenderedLength = session.output.length;
|
||||
}
|
||||
|
||||
// Soft cap to prevent unbounded growth in DOM and memory
|
||||
const MAX_OUTPUT_CHARS = 200000; // ~200KB of HTML per session
|
||||
if (session.output.length > MAX_OUTPUT_CHARS) {
|
||||
let start = session.output.length - MAX_OUTPUT_CHARS;
|
||||
// Find safe cut point - don't cut inside an HTML tag
|
||||
const firstTagEnd = session.output.indexOf('>', start);
|
||||
if (firstTagEnd !== -1 && firstTagEnd < start + 100) {
|
||||
start = firstTagEnd + 1;
|
||||
}
|
||||
session.output = session.output.slice(start);
|
||||
// Reset DOM to trimmed content and sync rendered length
|
||||
// Always full replace since serializeAsHTML() returns full screen state
|
||||
$output.innerHTML = session.output;
|
||||
session.outputRenderedLength = session.output.length;
|
||||
}
|
||||
|
||||
const $outputContainer = document.getElementById(`session-output-${sessionId}`);
|
||||
if ($outputContainer && session.expanded) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue