Files
go-service/cmd/server/web/js/app.js

156 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// app.js (оркестратор)
import { fetchHealth, fetchHistory } from "./data.js";
import { state, smooth, addSignals, resetBufferTracking } from "./state.js";
import {
initDOM,
setStatus,
setMeta,
setBars,
setSignal,
DOM
} from "./ui.js";
import { initAccordion } from "./accordion.js";
import { drawChart } from "./chart.js";
let lastChart = 0;
let connectionLost = false;
let consecutiveErrors = 0;
const MAX_ERRORS = 3;
let pollTimer = null;
// ================= INIT =================
window.addEventListener("DOMContentLoaded", () => {
initDOM();
initAccordion();
});
// ================= UPDATE =================
async function update() {
try {
const [h, hist] = await Promise.all([
fetchHealth(),
fetchHistory()
]);
consecutiveErrors = 0;
if (connectionLost) {
console.log("[app] Соединение восстановлено");
}
// ===== STATUS =====
const isOnline = h.pipe_alive && h.has_data;
if (isOnline) {
setStatus("На связи");
connectionLost = false;
} else {
setStatus("Нет связи", true);
if (!connectionLost) {
resetBufferTracking();
}
connectionLost = true;
}
const arr = Array.isArray(hist.bytes) ? hist.bytes : [];
const raw = arr[arr.length - 1] ?? 0;
// ===== ДОБАВЛЯЕМ ТОЛЬКО НОВЫЕ БАЙТЫ =====
if (arr.length > 0 && isOnline) {
const bufferSize = h.stats?.filled ?? 0;
addSignals(arr, bufferSize);
}
// ===== DECODE =====
const value = raw & 0x3F;
const level = (raw >> 6) & 0x3;
const percent = (value / 63) * 100;
// ===== UI =====
if (isOnline) {
setBars(smooth(percent));
setSignal(level);
} else {
setBars(0, true);
setSignal(0, true);
}
if (DOM.lastByte) {
DOM.lastByte.textContent = isOnline ? value : "--";
}
// ===== META =====
const uptime = Math.round(h.uptime_sec || 0);
const filled = h.stats?.filled ?? 0;
const Bps = Math.round(h.stats?.bytes_per_sec ?? 0);
setMeta(
`Работа: ${uptime}s | Буфер: ${filled} | Приём: ${Bps} B/s`
);
// ===== HISTORY =====
if (DOM.history) {
DOM.history.innerHTML = arr
.map((b, i) =>
`[${i}] ${(b & 0xFF).toString(2).padStart(8, "0")} = ${b & 0xFF}`
)
.join("<br>");
}
// ===== CHART =====
const now = performance.now();
if (now - lastChart > 100 && DOM.canvas) {
drawChart(DOM.canvas, state.signalHistory);
lastChart = now;
}
} catch (e) {
consecutiveErrors++;
if (consecutiveErrors === 1) {
console.warn("[app] Сервер недоступен, ждём...");
}
setStatus("СЕРВЕР НЕДОСТУПЕН", true);
setBars(0, true);
setSignal(0, true);
resetBufferTracking();
if (DOM.lastByte) {
DOM.lastByte.textContent = "--";
}
if (consecutiveErrors >= MAX_ERRORS) {
clearInterval(pollTimer);
pollTimer = setInterval(update, 2000);
console.log("[app] Замедлили опрос до 2с");
}
}
}
// ================= RECONNECT LOGIC =================
function startPolling() {
if (pollTimer) clearInterval(pollTimer);
if (consecutiveErrors > 0) {
console.log("[app] Попытка переподключения...");
update();
}
pollTimer = setInterval(update, 500);
}
window.addEventListener("focus", () => {
if (consecutiveErrors >= MAX_ERRORS) {
console.log("[app] Окно в фокусе, ускоряем опрос");
consecutiveErrors = 0;
startPolling();
}
});
// ================= START =================
startPolling();
update();