feat: rename Docker Watcher to Tinyforge
Build / build (push) Successful in 12m20s

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:
2026-04-12 21:30:23 +03:00
parent 8d2c5a063b
commit 791cd4d6af
68 changed files with 512 additions and 224 deletions
+31 -7
View File
@@ -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">