diff --git a/apps/app/src/app/lib/desktop.ts b/apps/app/src/app/lib/desktop.ts index 1ace9431..48ff91a9 100644 --- a/apps/app/src/app/lib/desktop.ts +++ b/apps/app/src/app/lib/desktop.ts @@ -86,8 +86,22 @@ export const desktopBridge: DesktopBridge = new Proxy({} as DesktopBridge, { }, }); +function isLoopbackUrl(input: RequestInfo | URL): boolean { + const raw = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url; + try { + const url = new URL(raw); + return url.hostname === "127.0.0.1" || url.hostname === "localhost" || url.hostname === "[::1]"; + } catch { + return false; + } +} + export const desktopFetch: typeof globalThis.fetch = (input, init) => { if (isElectronDesktopRuntime()) { + if (isLoopbackUrl(input)) { + return globalThis.fetch(input, init); + } + return invokeElectronHelper<{ status: number; statusText: string; diff --git a/apps/app/src/react-app/shell/session-route.tsx b/apps/app/src/react-app/shell/session-route.tsx index 0c3b5043..93228c95 100644 --- a/apps/app/src/react-app/shell/session-route.tsx +++ b/apps/app/src/react-app/shell/session-route.tsx @@ -395,15 +395,17 @@ export function SessionRoute() { [sessionsByWorkspaceId], ); - const backgroundSessionLoadInFlight = useRef>(new Set()); + const backgroundSessionLoadInFlight = useRef>(new Map()); const loadWorkspaceSessionsInBackground = useCallback( async (openworkClient: OpenworkServerClient, workspaces: RouteWorkspace[]) => { const MAX_ATTEMPTS = 6; const backoffMs = (attempt: number) => Math.min(500 * Math.pow(2, attempt), 4_000); const fetchOnce = async (workspace: RouteWorkspace, attempt: number): Promise => { - if (backgroundSessionLoadInFlight.current.has(workspace.id)) return; - backgroundSessionLoadInFlight.current.add(workspace.id); + const startedAt = backgroundSessionLoadInFlight.current.get(workspace.id) ?? 0; + if (startedAt && Date.now() - startedAt < 5_000) return; + const requestStartedAt = Date.now(); + backgroundSessionLoadInFlight.current.set(workspace.id, requestStartedAt); try { const response = await openworkClient.listSessions(workspace.id, { limit: 200 }); const workspaceRoot = normalizeDirectoryPath(workspace.path ?? ""); @@ -426,7 +428,9 @@ export function SessionRoute() { // in the meantime instead of flashing "error" next to the // workspace name. if (attempt + 1 < MAX_ATTEMPTS && isTransientStartupError(message)) { - backgroundSessionLoadInFlight.current.delete(workspace.id); + if (backgroundSessionLoadInFlight.current.get(workspace.id) === requestStartedAt) { + backgroundSessionLoadInFlight.current.delete(workspace.id); + } await new Promise((r) => window.setTimeout(r, backoffMs(attempt))); await fetchOnce(workspace, attempt + 1); return; @@ -439,7 +443,9 @@ export function SessionRoute() { current.includes(workspace.id) ? current.filter((id) => id !== workspace.id) : current, ); } finally { - backgroundSessionLoadInFlight.current.delete(workspace.id); + if (backgroundSessionLoadInFlight.current.get(workspace.id) === requestStartedAt) { + backgroundSessionLoadInFlight.current.delete(workspace.id); + } } };