Rework the logging and terminal emulator on the ui to work like an actual emulator for better output.
This commit is contained in:
@@ -2,20 +2,21 @@
|
||||
|
||||
import { useEffect, useState, useRef } from 'react';
|
||||
import { apiClient } from '@/utils/api';
|
||||
import { TerminalEmulator } from '@/utils/terminalEmulator';
|
||||
|
||||
interface FileObject {
|
||||
path: string;
|
||||
size: number;
|
||||
}
|
||||
|
||||
const clean = (text: string): string => {
|
||||
// remove \x1B[A\x1B[A
|
||||
text = text.replace(/\x1B\[A/g, '');
|
||||
return text;
|
||||
};
|
||||
|
||||
export default function useJobLog(jobID: string, reloadInterval: null | number = null) {
|
||||
const [log, setLog] = useState<string>('');
|
||||
// Emulates a terminal over the raw log stream so carriage returns, cursor
|
||||
// movement, and erase sequences collapse lines like a real terminal.
|
||||
const terminalRef = useRef<TerminalEmulator | null>(null);
|
||||
if (terminalRef.current === null) {
|
||||
terminalRef.current = new TerminalEmulator();
|
||||
}
|
||||
const didInitialLoadRef = useRef(false);
|
||||
// Byte offset into the log file that we've already consumed. Sent to the
|
||||
// server so it only returns newly appended content.
|
||||
@@ -42,14 +43,13 @@ export default function useJobLog(jobID: string, reloadInterval: null | number =
|
||||
.then(res => res.data)
|
||||
.then(data => {
|
||||
offsetRef.current = data.offset ?? null;
|
||||
const cleanLog = clean(data.log ?? '');
|
||||
const terminal = terminalRef.current!;
|
||||
if (data.reset) {
|
||||
// Log was reset/truncated (or initial load) — replace everything.
|
||||
setLog(cleanLog);
|
||||
} else if (cleanLog) {
|
||||
// Incremental — append only the new content.
|
||||
setLog(prev => prev + cleanLog);
|
||||
terminal.reset();
|
||||
}
|
||||
terminal.write(data.log ?? '');
|
||||
setLog(terminal.toString());
|
||||
setStatus('success');
|
||||
didInitialLoadRef.current = true;
|
||||
})
|
||||
@@ -67,6 +67,7 @@ export default function useJobLog(jobID: string, reloadInterval: null | number =
|
||||
offsetRef.current = null;
|
||||
didInitialLoadRef.current = false;
|
||||
inFlightRef.current = false;
|
||||
terminalRef.current?.reset();
|
||||
setLog('');
|
||||
refresh();
|
||||
|
||||
@@ -81,5 +82,5 @@ export default function useJobLog(jobID: string, reloadInterval: null | number =
|
||||
}
|
||||
}, [jobID]);
|
||||
|
||||
return { log, setLog, status, refresh };
|
||||
return { log, status, refresh };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user