fix(dashboard): remove dead unconditional useLiveRequests call in HomePageClient (#4759, #4745, #4596) (#4761)

Co-authored-by: Diego Rodrigues de Sa e Souza <souzamiriamrodrigues790@gmail.com>
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-06-23 08:22:42 -03:00
committed by GitHub
parent ec9c93fe29
commit bd1bcb5aba
3 changed files with 61 additions and 2 deletions

View File

@@ -13,6 +13,7 @@ _In development — bullets added per PR; finalized at release._
- **db-backups**: make the database-import size cap configurable via `OMNIROUTE_DB_IMPORT_MAX_MB` (default 100 MB, 4 GB ceiling) so backups larger than 100 MB can be restored; error message now points to the env var and to VACUUM (#4719).
- **Onboarding**: add the missing `onboarding.tiers` step-title translation so the setup wizard no longer crashes with `MISSING_MESSAGE: onboarding.tiers` (#4698).
- **deepseek-web**: fold `role:"tool"` results into the single-prompt transcript (`messagesToPrompt`) so tool outputs reach the model instead of being silently dropped when a follow-up turn omits the `tools[]` array (#4712).
- **Dashboard**: remove the dead, unconditional `useLiveRequests()` call from `HomePageClient.tsx` — it crashed the `/home` page in production builds with `ReferenceError: useLiveRequests is not defined` (#4759, #4745) and opened the live-dashboard WebSocket even when Provider Topology was hidden (#4596). The live feed remains owned by the settings-gated `HomeProviderTopologySection`.
---

View File

@@ -114,8 +114,11 @@ export default function HomePageClient({ machineId }: HomePageClientProps) {
Array<{ id?: string; prefix?: string; name?: string }>
>([]);
// Live in-flight requests for Provider Topology pulse animation (#3507)
const { activeRequests: liveActiveRequests } = useLiveRequests();
// The live in-flight request feed for the Provider Topology pulse animation is owned by
// <HomeProviderTopologySection>, which subscribes to it (gated by the `enabled` prop)
// only when the topology is actually shown. HomePageClient must NOT open its own
// unconditional live socket: the binding here was unused (ReferenceError in prod,
// #4759/#4745) and the socket opened even when topology was hidden (#4596).
const [versionInfo, setVersionInfo] = useState<VersionInfo | null>(null);
const [updating, setUpdating] = useState(false);

View File

@@ -0,0 +1,55 @@
// #4759 / #4745 — the /home dashboard crashed in production builds with
// "ReferenceError: useLiveRequests is not defined" because HomePageClient.tsx called the
// hook but never imported it (and the binding was unused). typecheck:core does not cover
// the Next dashboard .tsx files and ESLint's no-undef is off (TS owns that), so nothing
// but `next build` caught it.
//
// #4596 — that same top-level useLiveRequests() call opened the live-dashboard WebSocket
// unconditionally, even when Provider Topology was hidden. The live feed is owned by the
// settings-gated <HomeProviderTopologySection> (useLiveRequests({ enabled })), so
// HomePageClient must not open its own unconditional socket.
//
// Fix: remove the dead, unconditional useLiveRequests() call from HomePageClient. These
// static guards lock both regressions down.
import test from "node:test";
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
const src = readFileSync(
fileURLToPath(
new URL("../../src/app/(dashboard)/dashboard/HomePageClient.tsx", import.meta.url)
),
"utf8"
);
function collect(re: RegExp, group = 1): Set<string> {
return new Set([...src.matchAll(re)].map((m) => m[group]));
}
const called = collect(/\b(use[A-Z]\w*)\s*\(/g);
const importedNames = new Set(
[...src.matchAll(/import\s+(?:type\s+)?\{([^}]*)\}/g)].flatMap((m) =>
m[1].split(",").map((s) => s.trim().split(/\s+as\s+/).pop()!.trim())
)
);
const declared = collect(/(?:function|const|let|var)\s+(use[A-Z]\w*)/g);
test("every hook called in HomePageClient.tsx is imported or declared (#4759/#4745)", () => {
const missing = [...called].filter((h) => !importedNames.has(h) && !declared.has(h));
assert.deepEqual(
missing,
[],
`hooks used without import (ReferenceError in production build): ${missing.join(", ")}`
);
});
test("HomePageClient does not open its own unconditional live socket (#4596)", () => {
// The live feed belongs to the settings-gated <HomeProviderTopologySection>. A bare
// useLiveRequests( call at the page level would open the WebSocket even when topology
// is hidden — exactly the regression #4596 reports (and the dead binding behind #4759).
assert.ok(
!/\buseLiveRequests\s*\(/.test(src),
"HomePageClient.tsx must not call useLiveRequests directly; delegate it to HomeProviderTopologySection"
);
});