From 55f9f6d8ede4128baba7b0ba694e54bbdcf4bc36 Mon Sep 17 00:00:00 2001 From: M1 Date: Tue, 17 Mar 2026 07:03:10 +0400 Subject: [PATCH] refactor: SSE just refreshes sparkline/chart from server, no DOM stat patching --- apps/web/src/views/detail.ejs | 65 ++--------------------------------- apps/web/src/views/home.ejs | 41 ++++------------------ 2 files changed, 10 insertions(+), 96 deletions(-) diff --git a/apps/web/src/views/detail.ejs b/apps/web/src/views/detail.ejs index d1c1b3e..f3e3341 100644 --- a/apps/web/src/views/detail.ejs +++ b/apps/web/src/views/detail.ejs @@ -265,68 +265,9 @@ } }); - // Track running stats for SSE incremental updates - let _totalPings = <%= pings.length %>, _upPings = <%= upPings.length %>; - let _latencySum = <%= latencies.reduce((a, b) => a + b, 0) %>, _latencyCount = <%= latencies.length %>; - - // SSE: live ping updates (minimal DOM patches only — no chart re-render) - watchMonitor(monitorId, (ping) => { - // Stats - _totalPings++; - if (ping.up) _upPings++; - if (ping.latency_ms != null) { - _latencySum += ping.latency_ms; - _latencyCount++; - const avg = Math.round(_latencySum / _latencyCount); - document.getElementById('stat-latency').textContent = avg + 'ms'; - } - - document.getElementById('stat-last').innerHTML = timeAgo(ping.checked_at); - document.getElementById('stat-status').innerHTML = ping.up - ? 'Up' - : 'Down'; - document.getElementById('status-dot').innerHTML = ping.up - ? '' - : ''; - - if (_totalPings > 0) { - const pct = Math.round((_upPings / _totalPings) * 100); - document.getElementById('stat-uptime').textContent = pct + '%'; - } - - // Status history bar — append new segment - const bar = document.getElementById('status-bar'); - if (bar) { - const seg = document.createElement('div'); - seg.className = `flex-1 ${ping.up ? 'bg-green-500/70' : 'bg-red-500/70'}`; - seg.title = `${new Date(ping.checked_at).toLocaleString()} — ${ping.up ? 'Up' : 'Down'}${ping.latency_ms ? ' ' + ping.latency_ms + 'ms' : ''}`; - bar.prepend(seg); - while (bar.children.length > 60) bar.removeChild(bar.lastChild); - } - - // Refresh latency chart (debounced) - scheduleChartRefresh(); - - // Ping table — prepend plain HTML row - const tbody = document.getElementById('pings-table'); - if (tbody) { - const tr = document.createElement('tr'); - tr.className = 'hover:bg-gray-800/50'; - tr.innerHTML = ` - ${ping.up ? 'Up' : 'Down'} - ${ping.status_code ?? '—'} - ${ping.latency_ms ? ping.latency_ms + 'ms' : '—'} - ${timeAgo(ping.checked_at)} - ${ping.error ? escapeHtml(ping.error) : ''} - `; - tbody.prepend(tr); - while (tbody.children.length > 100) tbody.removeChild(tbody.lastChild); - } - }); - - // Refresh latency chart from server (debounced — at most once per 5s) + // SSE: on each ping, refresh the chart (debounced — at most once per 5s) let _chartRefreshTimer = null; - function scheduleChartRefresh() { + watchMonitor(monitorId, () => { if (_chartRefreshTimer) return; _chartRefreshTimer = setTimeout(async () => { _chartRefreshTimer = null; @@ -335,7 +276,7 @@ if (res.ok) document.getElementById('latency-chart').innerHTML = await res.text(); } catch {} }, 5000); - } + }); <%~ include('./partials/foot') %> diff --git a/apps/web/src/views/home.ejs b/apps/web/src/views/home.ejs index f4296ae..4297f58 100644 --- a/apps/web/src/views/home.ejs +++ b/apps/web/src/views/home.ejs @@ -88,41 +88,14 @@ }, 5000); } - // SSE: subscribe to all monitors for live updates - const sseConnections = []; - function subscribeAll() { - const monitorCards = document.querySelectorAll('[data-monitor-id]'); - monitorCards.forEach(card => { - const mid = card.dataset.monitorId; - const es = watchMonitor(mid, (ping) => { - // Status dot - const statusDot = card.querySelector('.status-dot'); - if (statusDot) { - const wasUp = statusDot.classList.contains('bg-green-500'); - statusDot.className = `status-dot w-2.5 h-2.5 rounded-full ${ping.up ? 'bg-green-500' : 'bg-red-500'}`; - if (wasUp !== ping.up) { - const dots = document.querySelectorAll('.status-dot'); - const upNow = [...dots].filter(d => d.classList.contains('bg-green-500')).length; - const downNow = [...dots].filter(d => d.classList.contains('bg-red-500')).length; - const summary = document.getElementById('summary'); - if (summary) summary.innerHTML = `${upNow} up · ${downNow} down · ${dots.length} total`; - } - } - - // Latency text - if (ping.latency_ms) card.querySelector('.stat-latency').textContent = `${ping.latency_ms}ms`; - - // Timestamp - card.querySelector('.stat-last').innerHTML = timeAgo(ping.checked_at); - - // Sparkline — debounced fetch from server - const sparkEl = card.querySelector('.stat-sparkline'); - if (sparkEl) scheduleSparklineRefresh(mid, sparkEl); - }); - if (es) sseConnections.push(es); + // SSE: subscribe to all monitors, refresh sparkline on each ping + document.querySelectorAll('[data-monitor-id]').forEach(card => { + const mid = card.dataset.monitorId; + watchMonitor(mid, () => { + const sparkEl = card.querySelector('.stat-sparkline'); + if (sparkEl) scheduleSparklineRefresh(mid, sparkEl); }); - } - subscribeAll(); + }); <%~ include('./partials/foot') %>