feat(frontend): surfaces live web (workstate live, background, inbox, reconnect) (#13)

Lot F5 du chantier server/client mode : le client web consomme les frames
event.domain (B7) pour animer ses surfaces live.

- webLive.ts : consommation du flux event.domain (workstate, background,
  inbox).
- useLiveReconnect.ts : reconnexion du flux live.
- wsLiveClient.ts / index.ts : câblage du transport live.
- WebWorkspace.tsx : surfaces live branchées.
- Tests : WebWorkspaceLive.test.tsx, wsLiveClientReconnect.test.ts,
  WebApp.test.tsx.

Validé : frontend 753 tests verts, desktop non régressé.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 23:37:02 +02:00
parent 1bc5217dbc
commit dd1d083a1a
8 changed files with 457 additions and 112 deletions

View File

@ -0,0 +1,27 @@
/**
* `useLiveReconnect` — ticket #13, lot F5. Web-only hook that re-synchronises a
* live read-model when the shared WebSocket **reconnects** after an outage.
*
* During a disconnection, domain events emitted by the server are missed, so a
* plain event-driven refresh (the desktop `useProjectWorkState` mechanism) would
* leave the UI stale until the next event. This hook watches the web live
* client's connection state and calls `onReconnect` on each `reconnecting →
* connected` transition. It is inert outside web transport (no client
* registered), so it is safe to mount unconditionally.
*/
import { useEffect } from "react";
import { getWebLiveClient } from "@/adapters/http";
export function useLiveReconnect(onReconnect: () => void): void {
useEffect(() => {
const client = getWebLiveClient();
if (!client) return;
let previous = client.getConnectionState();
return client.onConnectionStateChange((state) => {
if (state === "connected" && previous === "reconnecting") onReconnect();
previous = state;
});
}, [onReconnect]);
}