const DEFAULT_PORT = 8080; const DEFAULT_HOST = '127.0.0.1'; const DEFAULT_URL = `http://${DEFAULT_HOST}:${DEFAULT_PORT}`; function isServiceWorker() { return typeof ServiceWorkerGlobalScope !== 'undefined' && self instanceof ServiceWorkerGlobalScope; } export async function getServerUrl() { if (isServiceWorker()) { const result = await chrome.storage.local.get('muyue_server_url'); return result.muyue_server_url || DEFAULT_URL; } const stored = localStorage.getItem('muyue_server_url'); return stored || DEFAULT_URL; } export async function setServerUrl(url) { if (isServiceWorker()) { await chrome.storage.local.set({ muyue_server_url: url }); } else { localStorage.setItem('muyue_server_url', url); } } export async function buildWsUrl(token) { const base = await getServerUrl(); const wsBase = base.replace(/^http/, 'ws'); return `${wsBase}/api/ws/browser-test?token=${encodeURIComponent(token)}`; } export async function fetchToken() { const base = await getServerUrl(); const res = await fetch(`${base}/api/test/snippet`); if (!res.ok) throw new Error(`Server returned ${res.status}`); const data = await res.json(); return { token: data.token, wsUrl: data.ws_url, expiresIn: data.expires_in }; } export async function fetchSessions() { const base = await getServerUrl(); const res = await fetch(`${base}/api/test/sessions`); if (!res.ok) throw new Error(`Server returned ${res.status}`); const data = await res.json(); return data.sessions || []; } export async function checkServerHealth() { try { const base = await getServerUrl(); const res = await fetch(`${base}/api/info`, { signal: AbortSignal.timeout(3000) }); return res.ok; } catch { return false; } }