chore(web): address Copilot review on #2153

- Publish `setupClientForServerRef` from a layout effect rather than during
  render. React runs every layout effect before any passive effect of the same
  commit, and the /oauth/callback effect is passive, so the seam is still
  published before its first read — without the render-phase ref mutation the
  compiler rule rejects. This was the one `react-hooks/refs` finding the PR
  introduced, so its suppression is gone rather than deferred to #2161 under a
  justification that did not describe it.
- Narrow the hook's `fetchLogRef` option to `FetchRequestSource`, the
  `getFetchRequests` slice it actually consumes, mirroring
  `InspectorClientEventSource` in useProgressToasts. That removes the test
  harness's `as unknown as` cast, and the narrowed contract is real: it
  immediately rejected the loosely-typed fixture, which is now a properly typed
  `FetchRequestEntry`.
- Make the test harness hold both refs across renders and publish them from a
  layout effect, as App.tsx does. The deferred-publication test previously
  passed because `Probe` built a fresh ref each render and the rerender also
  changed `servers`; it now asserts what the guard is actually for — a run that
  cannot exchange must not spend the single-use code — and re-triggers on the
  `servers` change that carries it in production.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hzwzS8UvBsr4yZm7o7sev
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-26 23:19:49 -04:00
commit 5f875e3393

View file

@ -101,6 +101,15 @@ export interface PrepareOAuthRedirectArgs {
client?: InspectorClient;
}
/**
* The only part of the Network log this hook touches: reading the entries to
* flush before a redirect. Naming that rather than the whole
* `FetchRequestLogState` states the real dependency, and lets a test supply a
* plain object instead of casting a partial one through `unknown` — the same
* shape `useProgressToasts` uses for its slice of `InspectorClient`.
*/
export type FetchRequestSource = Pick<FetchRequestLogState, "getFetchRequests">;
/** The one thing the `/oauth/callback` rebuild needs from the connect path. */
export type SetupClientForServer = (
server: ServerEntry,
@ -127,7 +136,7 @@ export interface UseOAuthRecoveryOptions {
setUi: TabUiStateSetters;
setActiveTab: (next: string) => void;
/** The live Network log, flushed to session storage before a redirect. */
fetchLogRef: RefObject<FetchRequestLogState | null>;
fetchLogRef: RefObject<FetchRequestSource | null>;
/** Handshake telemetry, cleared/started around the callback's reconnect. */
connectStartRef: RefObject<number | undefined>;
/**