/* Copyright 2026 Marimo. All rights reserved. */ import { atom, useAtomValue, useSetAtom } from "jotai"; import { AlertCircleIcon, CheckCircle2Icon, PowerOffIcon } from "lucide-react"; import type React from "react"; import { Spinner } from "@/components/icons/spinner"; import { Tooltip } from "@/components/ui/tooltip"; import { connectionAtom } from "@/core/network/connection"; import { useConnectToRuntime, useRuntimeManager } from "@/core/runtime/config"; import { store } from "@/core/state/jotai"; import { isWasm } from "@/core/wasm/utils"; import { isAppClosing, isAppConnected, isAppConnecting, isAppNotStarted, } from "@/core/websocket/connection-utils"; import { useAsyncData } from "@/hooks/useAsyncData"; import { useInterval } from "@/hooks/useInterval"; import { Strings } from "@/utils/strings"; const CHECK_HEALTH_INTERVAL_MS = 30_000; type ConnectionStatus = "healthy" | "unhealthy" | "connecting" | "disconnected"; // Atom to track connection status for use in other components export const connectionStatusAtom = atom("connecting"); export function getConnectionStatus(): ConnectionStatus { return store.get(connectionStatusAtom); } /** * Backend connection status indicator for the developer panel header */ export const BackendConnectionStatus: React.FC = () => { const connection = useAtomValue(connectionAtom).state; const runtime = useRuntimeManager(); const connectToRuntime = useConnectToRuntime(); const setConnectionStatus = useSetAtom(connectionStatusAtom); const { isFetching, error, data, refetch } = useAsyncData(async () => { // If the connection is not connected, return if (!isAppConnected(connection)) { setConnectionStatus("disconnected"); return; } // Skip wasm since there is no health check for wasm if (isWasm()) { setConnectionStatus("healthy"); return { isHealthy: true, lastChecked: new Date(), error: undefined, }; } try { const isHealthy = await runtime.isHealthy(); setConnectionStatus(isHealthy ? "healthy" : "unhealthy"); return { isHealthy, lastChecked: new Date(), error: undefined, }; } catch (error) { setConnectionStatus("unhealthy"); return { isHealthy: false, lastChecked: new Date(), error: error instanceof Error ? error.message : "Unknown error", }; } }, [runtime, connection]); useInterval(refetch, { delayMs: isAppConnected(connection) ? CHECK_HEALTH_INTERVAL_MS : null, whenVisible: true, }); const getStatusInfo = () => { if (isAppNotStarted(connection)) { return "Not connected to a runtime"; } const baseStatus = Strings.startCase(connection.toLowerCase()); const healthInfo = data?.lastChecked ? data.isHealthy ? "✓ Healthy" : "✗ Unhealthy" : "Health: Unknown"; const errorInfo = error ? `Error: ${error}` : ""; return [baseStatus, healthInfo, errorInfo].filter(Boolean).join("\n"); }; const getStatusIcon = () => { if (isFetching || isAppConnecting(connection)) { return ; } if (isAppClosing(connection)) { return ; } if (isAppConnected(connection)) { if (data?.isHealthy) { return ; } if (data?.lastChecked) { return ; } return ; } if (isAppNotStarted(connection)) { return ; } return ; }; const handleClick = () => { if (isAppNotStarted(connection)) { void connectToRuntime(); } else { refetch(); } }; return ( {getStatusInfo()} {isAppConnected(connection) && (
Click to refresh health status
)} } data-testid="footer-backend-status" >
); };