fix(app): keep host connection statuses live under the React Compiler

The hook read a store version only as a memo trigger (void version); the
compiler dropped it, so pages that mounted before a host came online kept
showing it as connecting.
This commit is contained in:
Mohamed Boudra
2026-09-26 20:53:05 +02:00
parent 539097debc
commit 77e33f8845
2 changed files with 36 additions and 11 deletions
@@ -40,6 +40,30 @@ test.describe("usage screen", () => {
await expect(group.getByText("Unavailable", { exact: true })).toBeVisible();
});
test("shows the host once it connects after a cold load on a phone", async ({ page }) => {
test.setTimeout(120_000);
const serverId = getServerId();
const usage = await installUsageReportsFixture(page, {
lists: [
[
{
sourceId: "alpha",
sourceLabel: "Alpha plan",
report: { account: { key: "a" }, status: "available", windows: [] },
},
],
],
});
await page.setViewportSize({ width: 390, height: 844 });
await page.goto("/usage");
await usage.waitForListRequests(1);
await expect(
page.getByTestId(`usage-host-${serverId}`).getByText("Alpha plan", { exact: true }),
).toBeVisible({ timeout: 10_000 });
});
test("tells the user to update a host without usage sources", async ({ page }) => {
test.setTimeout(120_000);
const serverId = getServerId();
+12 -11
View File
@@ -2653,21 +2653,22 @@ export function useHostRuntimeConnectionStatuses(
serverIds: readonly string[],
): ReadonlyMap<string, HostRuntimeConnectionStatus> {
const store = getHostRuntimeStore();
const version = useSyncExternalStore(
// The snapshot is the statuses themselves, joined into a string so React compares by
// value. A version counter read only for reactivity is dropped by the React Compiler.
const readStatuses = () =>
serverIds
.map((serverId) => store.getSnapshot(serverId)?.connectionStatus ?? "connecting")
.join("\n");
const statuses = useSyncExternalStore(
(onStoreChange) => store.subscribeAll(onStoreChange),
() => store.getVersion(),
() => store.getVersion(),
readStatuses,
readStatuses,
);
return useMemo(() => {
// The aggregate version is the reactivity trigger; re-read snapshots on every host tick.
void version;
const entries: Array<[string, HostRuntimeConnectionStatus]> = serverIds.map((serverId) => [
serverId,
store.getSnapshot(serverId)?.connectionStatus ?? "connecting",
]);
return new Map(entries);
}, [serverIds, store, version]);
const values = statuses.split("\n") as HostRuntimeConnectionStatus[];
return new Map(serverIds.map((serverId, index) => [serverId, values[index]]));
}, [serverIds, statuses]);
}
export function useHostRuntimeLastError(serverId: string): string | null {