fix: keep instance statuses between switcher opens

The switcher held reachability in component state and replaced the whole map at
the end of a probe run. It ran once per open before the config had loaded — with
Local as the only host — so that pass wiped every other instance's status and
each open started on "Checking", including for the instance the app was
connected to and actively talking to.

Statuses move to their own module: startup warms them so the switcher opens on
real values, a re-probe replaces each value in place as it lands rather than
blanking them first, and stale entries are dropped against the loaded config
instead of a partial host list. The connected instance never reads "Checking" —
the live connection already answers what the probe would ask.
This commit is contained in:
Bohdan Triapitsyn
2026-09-03 11:49:34 +03:00
parent 8f1e0c8b5f
commit 17fd46d4e5
4 changed files with 313 additions and 62 deletions
+11
View File
@@ -1,6 +1,7 @@
import { getRuntimeExtraHeadersSync, refreshLocalRuntimeUrlAuthToken, refreshRuntimeUrlAuthToken, setRuntimeBearerToken, setRuntimeExtraHeaders } from '@openchamber/ui/lib/runtime-auth';
import { installRuntimeFetchBridge } from '@openchamber/ui/lib/runtime-fetch';
import { initializeRuntimeEndpoint, switchRuntimeEndpoint } from '@openchamber/ui/lib/runtime-switch';
import { warmDesktopHostStatuses } from '@openchamber/ui/lib/desktopHostStatus';
import { restoreDesktopRelayRuntime } from '@openchamber/ui/lib/desktopRelayRestore';
import { getInjectedBootOutcome } from '@openchamber/ui/lib/desktopBoot';
import { configureRuntimeUrlResolver } from '@openchamber/ui/lib/runtime-url';
@@ -8,6 +9,9 @@ import type { EmbeddedSessionRuntimeBootstrap } from '@openchamber/ui/components
import { opencodeClient } from '@openchamber/ui/lib/opencode/client';
import { createWebAPIs } from './api';
// The switcher's statuses are warmed after boot settles, not during it.
const HOST_STATUS_WARMUP_DELAY_MS = 3_000;
const sameOrigin = (left: string, right: string): boolean => {
if (!left || !right) return false;
try {
@@ -93,5 +97,12 @@ export const createConfiguredWebAPIs = (bootstrap?: EmbeddedSessionRuntimeBootst
// subscribes to runtime-change events, so bind the SDK explicitly.
opencodeClient.reconnectToRuntimeBaseUrl();
});
// Learn every instance's reachability in the background, so the switcher opens
// on real values instead of probing for the first time under the user's
// cursor. After the endpoint is settled and past the app's own bootstrap:
// this is unprompted work and the machine's network is busiest at launch.
void desktopRelayRestoreReady.then(() => {
window.setTimeout(() => { void warmDesktopHostStatuses().catch(() => {}); }, HOST_STATUS_WARMUP_DELAY_MS);
});
return createWebAPIs({ urls });
};