Rebrand the project as Tinyforge to reflect its evolution from a Docker container watcher into a self-hosted mini CI/deployment platform. Rename covers: Go module path, Docker labels, DB/config filenames, JWT issuer, Dockerfile binary, docker-compose, CI workflows, frontend i18n, README with static sites docs, and all code comments.
This commit is contained in:
@@ -25,6 +25,29 @@
|
||||
let logContainer: HTMLDivElement | undefined = $state();
|
||||
let eventSource: EventSource | null = null;
|
||||
|
||||
// Batch incoming SSE log lines to avoid per-line re-renders.
|
||||
let pendingLines: string[] = [];
|
||||
let flushTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
function flushPendingLines() {
|
||||
flushTimer = null;
|
||||
if (pendingLines.length === 0) return;
|
||||
let updated = [...lines, ...pendingLines];
|
||||
pendingLines = [];
|
||||
if (updated.length > tailCount * 2) {
|
||||
updated = updated.slice(-tailCount);
|
||||
}
|
||||
lines = updated;
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
function enqueueLine(line: string) {
|
||||
pendingLines.push(line);
|
||||
if (!flushTimer) {
|
||||
flushTimer = setTimeout(flushPendingLines, 150);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadLogs() {
|
||||
loading = true;
|
||||
error = '';
|
||||
@@ -49,12 +72,7 @@
|
||||
try {
|
||||
const data = JSON.parse(e.data);
|
||||
if (data.line) {
|
||||
lines = [...lines, data.line];
|
||||
// Trim to max lines.
|
||||
if (lines.length > tailCount * 2) {
|
||||
lines = lines.slice(-tailCount);
|
||||
}
|
||||
scrollToBottom();
|
||||
enqueueLine(data.line);
|
||||
}
|
||||
} catch { /* ignore parse errors */ }
|
||||
};
|
||||
@@ -69,6 +87,9 @@
|
||||
eventSource.close();
|
||||
eventSource = null;
|
||||
}
|
||||
// Flush any buffered lines before stopping.
|
||||
if (flushTimer) { clearTimeout(flushTimer); flushTimer = null; }
|
||||
flushPendingLines();
|
||||
following = false;
|
||||
}
|
||||
|
||||
@@ -90,7 +111,10 @@
|
||||
// Load on mount.
|
||||
$effect(() => { loadLogs(); });
|
||||
|
||||
onDestroy(() => { stopFollowing(); });
|
||||
onDestroy(() => {
|
||||
stopFollowing();
|
||||
if (flushTimer) { clearTimeout(flushTimer); flushTimer = null; }
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="rounded-xl border border-[var(--border-primary)] bg-[var(--surface-page)] shadow-lg">
|
||||
|
||||
Reference in New Issue
Block a user