// LightSync frontend — Phase 1 shell // WebSocket stub + device list loader // Phase 2 expands audio, transport, and WS protocol const WS_URL = `${location.protocol === 'https:' ? 'wss' : 'ws'}://${location.host}/ws`; async function apiPost(path, data) { const res = await fetch(path, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), }); if (!res.ok) throw new Error(`POST ${path}: HTTP ${res.status}`); return res.json(); } async function apiDelete(path) { const res = await fetch(path, { method: "DELETE" }); if (!res.ok && res.status !== 204) throw new Error(`DELETE ${path}: HTTP ${res.status}`); } class LightSyncClient { constructor() { this.ws = null; this.reconnectDelay = 2000; this._reconnectTimer = null; } connect() { if (this._reconnectTimer) { clearTimeout(this._reconnectTimer); this._reconnectTimer = null; } this.ws = new WebSocket(WS_URL); this.ws.onopen = () => { document.getElementById("status-dot").className = "status-dot connected"; document.getElementById("status-text").textContent = "CONNECTED"; }; this.ws.onclose = () => { document.getElementById("status-dot").className = "status-dot"; document.getElementById("status-text").textContent = "OFFLINE"; this._reconnectTimer = setTimeout(() => this.connect(), this.reconnectDelay); }; this.ws.onerror = () => { document.getElementById("status-dot").className = "status-dot error"; }; this.ws.onmessage = (event) => { const msg = JSON.parse(event.data); this.handleMessage(msg); }; } handleMessage(msg) { // Phase 2 will dispatch on msg.type console.debug("[ws]", msg); } send(msg) { if (this.ws?.readyState === WebSocket.OPEN) { this.ws.send(JSON.stringify(msg)); } } } const client = new LightSyncClient(); client.connect(); // Load device list on startup async function loadDevices() { try { const res = await fetch("/api/devices"); if (!res.ok) throw new Error(`HTTP ${res.status}`); const devices = await res.json(); const list = document.getElementById("device-list"); if (devices.length === 0) { list.innerHTML = 'no devices registered'; return; } list.innerHTML = devices.map(d => `