const DEFAULT_DATA = { overview: { generated_at: new Date().toISOString(), overall_status: "online", refresh_hint_seconds: 20, services: { online: 8, degraded: 2, offline: 1, total: 11 }, docker: { running: 18, stopped: 2, unhealthy: 1, total: 20, source_status: "online" }, system: { cpu_percent: 23, ram_percent: 61, root_storage_percent: 49, network_rx_mbps: 12.4, network_tx_mbps: 3.1, uptime_seconds: 864000, }, home_assistant: { status: "online", label: "Home Assistant", version: "2026.3.4", response_time_ms: 142, last_checked: new Date().toISOString(), }, }, system: { generated_at: new Date().toISOString(), source: { name: "beszel", status: "online", host_name: "homelab-01", agent_name: "beszel-agent", }, cpu: { usage_percent: 23, cores: 8, load_1: 0.82, load_5: 0.74, load_15: 0.69 }, memory: { used_gb: 19.6, total_gb: 32, available_gb: 12.4, usage_percent: 61 }, network: { primary_interface: "eth0", rx_mbps: 12.4, tx_mbps: 3.1 }, host: { uptime_seconds: 864000, platform: "linux", kernel: "6.8.0" }, }, services: { generated_at: new Date().toISOString(), summary: { overall_status: "degraded", docker: { running: 18, stopped: 2, unhealthy: 1, total: 20, source_status: "online" }, uptime_kuma: { monitors_up: 8, monitors_down: 1, monitors_paused: 1, total: 10, source_status: "online" }, }, services: [ { id: "homeassistant", name: "Home Assistant", kind: "core", status: "online", health: "healthy", latency_ms: 142, docker_state: "running", url: "#", source: "home_assistant", last_checked: new Date().toISOString(), }, { id: "immich", name: "Immich", kind: "service", status: "degraded", health: "warning", latency_ms: 821, docker_state: "running", url: "#", source: "uptime_kuma", last_checked: new Date().toISOString(), }, { id: "gitea", name: "Gitea", kind: "service", status: "online", health: "healthy", latency_ms: 98, docker_state: "running", url: "#", source: "uptime_kuma", last_checked: new Date().toISOString(), }, { id: "adguard", name: "AdGuard", kind: "service", status: "offline", health: "offline", latency_ms: null, docker_state: "stopped", url: "#", source: "docker", last_checked: new Date().toISOString(), }, ], }, storage: { generated_at: new Date().toISOString(), summary: { overall_status: "degraded", critical_disks: 0, warning_disks: 1, total_disks: 3 }, root: { name: "rootfs", mount: "/", used_gb: 233.8, total_gb: 480, free_gb: 246.2, usage_percent: 48.7, status: "online" }, disks: [ { name: "rootfs", mount: "/", used_gb: 233.8, total_gb: 480, free_gb: 246.2, usage_percent: 48.7, status: "online" }, { name: "data", mount: "/data", used_gb: 712.1, total_gb: 1000, free_gb: 287.9, usage_percent: 71.2, status: "warning" }, { name: "backup", mount: "/backup", used_gb: 201.4, total_gb: 2000, free_gb: 1798.6, usage_percent: 10.1, status: "online" }, ], }, adguard: { source_name: "adguard", source_status: "offline", total_queries: 0, blocked_queries: 0, blocked_percent: 0, avg_processing_ms: 0, }, scrutiny: { source_name: "scrutiny", source_status: "offline", overall_status: "offline", devices: [], failed_count: 0, total_count: 0, }, }; const listeners = new Set(); const state = { data: structuredClone(DEFAULT_DATA), isLoading: true, error: null, lastRefreshAt: null, refreshIntervalMs: 20000, }; export function subscribe(listener) { listeners.add(listener); listener(state); return () => listeners.delete(listener); } export function getState() { return state; } export function updateData(payload) { state.data = payload; state.isLoading = false; state.error = null; state.lastRefreshAt = new Date(); state.refreshIntervalMs = Math.max((payload?.overview?.refresh_hint_seconds ?? 20) * 1000, 15000); emit(); } export function setError(error) { state.isLoading = false; state.error = error; emit(); } function emit() { for (const listener of listeners) { listener(state); } }