feat(debug): replace HTTP polling with WebSocket for real-time debug updates
This commit is contained in:
+56
-34
@@ -528,15 +528,15 @@
|
||||
<h2>🔍 Live Debug</h2>
|
||||
<div style="display: flex; align-items: center; gap: 8px">
|
||||
<div class="live-dot"></div>
|
||||
<span style="font-size: 12px; color: var(--muted)">polling every</span>
|
||||
<select id="debug-interval" onchange="onDebugIntervalChange()"
|
||||
style="font-size: 12px; background: var(--surface2); color: var(--text); border: 1px solid var(--border); border-radius: 6px; padding: 2px 6px;">
|
||||
<option value="500">0.5s</option>
|
||||
<span style="font-size:12px;color:var(--muted);">every</span>
|
||||
<select id="debug-interval" onchange="setDebugInterval(parseInt(this.value))"
|
||||
style="font-size:12px;background:var(--surface2);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:2px 6px;margin:0 4px;">
|
||||
<option value="100">100ms</option>
|
||||
<option value="250">250ms</option>
|
||||
<option value="500">500ms</option>
|
||||
<option value="1000" selected>1s</option>
|
||||
<option value="2000">2s</option>
|
||||
<option value="5000">5s</option>
|
||||
<option value="10000">10s</option>
|
||||
<option value="30000">30s</option>
|
||||
</select>
|
||||
<button class="btn btn-ghost btn-xs" onclick="toggleDebug()">✕</button>
|
||||
</div>
|
||||
@@ -636,7 +636,8 @@
|
||||
// ═══════════════════════════════════════════════
|
||||
|
||||
let views = [];
|
||||
let debugPollTimer = null;
|
||||
let debugSocket = null;
|
||||
let debugReconnectTimer = null;
|
||||
let debugVisible = false;
|
||||
let debugIntervalMs = 1000;
|
||||
const { origin } = location;
|
||||
@@ -970,9 +971,54 @@
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════
|
||||
// DEBUG PANEL
|
||||
// DEBUG PANEL (WebSocket)
|
||||
// ═══════════════════════════════════════════════
|
||||
|
||||
function connectDebugSocket() {
|
||||
if (debugSocket) return;
|
||||
const protocol = location.protocol === "https:" ? "wss:" : "ws:";
|
||||
const wsUrl = `${protocol}//${location.host}/ws?interval=${debugIntervalMs}`;
|
||||
debugSocket = new WebSocket(wsUrl);
|
||||
|
||||
debugSocket.onopen = () => {
|
||||
if (debugReconnectTimer) { clearTimeout(debugReconnectTimer); debugReconnectTimer = null; }
|
||||
};
|
||||
|
||||
debugSocket.onmessage = (event) => {
|
||||
try {
|
||||
lastDebugData = JSON.parse(event.data);
|
||||
renderDebug(lastDebugData);
|
||||
} catch { /* ignore */ }
|
||||
};
|
||||
|
||||
debugSocket.onclose = () => {
|
||||
debugSocket = null;
|
||||
if (debugVisible) {
|
||||
debugReconnectTimer = setTimeout(connectDebugSocket, 2000);
|
||||
}
|
||||
};
|
||||
|
||||
debugSocket.onerror = () => {
|
||||
debugSocket?.close();
|
||||
};
|
||||
}
|
||||
|
||||
function disconnectDebugSocket() {
|
||||
if (debugReconnectTimer) { clearTimeout(debugReconnectTimer); debugReconnectTimer = null; }
|
||||
if (debugSocket) {
|
||||
debugSocket.onclose = null; // prevent auto-reconnect
|
||||
debugSocket.close();
|
||||
debugSocket = null;
|
||||
}
|
||||
}
|
||||
|
||||
function setDebugInterval(ms) {
|
||||
debugIntervalMs = ms;
|
||||
if (debugSocket && debugSocket.readyState === WebSocket.OPEN) {
|
||||
debugSocket.send(JSON.stringify({ type: "debug-interval", interval: ms }));
|
||||
}
|
||||
}
|
||||
|
||||
function toggleDebug() {
|
||||
debugVisible = !debugVisible;
|
||||
const panel = document.getElementById("debug-panel");
|
||||
@@ -980,39 +1026,15 @@
|
||||
if (debugVisible) {
|
||||
panel.classList.add("visible");
|
||||
btn.textContent = "🔍 Hide Debug";
|
||||
pollDebug();
|
||||
debugPollTimer = setInterval(pollDebug, debugIntervalMs);
|
||||
connectDebugSocket();
|
||||
} else {
|
||||
panel.classList.remove("visible");
|
||||
btn.textContent = "🔍 Debug";
|
||||
if (debugPollTimer) {
|
||||
clearInterval(debugPollTimer);
|
||||
debugPollTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onDebugIntervalChange() {
|
||||
debugIntervalMs = parseInt(document.getElementById("debug-interval").value);
|
||||
if (debugPollTimer) {
|
||||
clearInterval(debugPollTimer);
|
||||
debugPollTimer = setInterval(pollDebug, debugIntervalMs);
|
||||
disconnectDebugSocket();
|
||||
}
|
||||
}
|
||||
|
||||
let lastDebugData = null;
|
||||
|
||||
async function pollDebug() {
|
||||
if (!debugVisible) return;
|
||||
try {
|
||||
const res = await fetch(origin + "/api/debug");
|
||||
lastDebugData = await res.json();
|
||||
renderDebug(lastDebugData);
|
||||
} catch {
|
||||
/* silent */
|
||||
}
|
||||
}
|
||||
|
||||
let debugTickInterval = null;
|
||||
|
||||
function renderDebug(data) {
|
||||
|
||||
Reference in New Issue
Block a user