返回 DeepSeek-Reasonix
controllerEventRecovery.ts
根目录 / desktop / frontend / src / lib / controllerEventRecovery.ts
1 import type { ControllerRecoveryPorts } from "./controllerEventRecoveryWorker";
2 import { desktopHost } from "./desktopHost";
3 import { recordFrontendDiagnostic } from "./frontendDiagnosticBridge";
4
5 export type { ControllerRecoveryPorts } from "./controllerEventRecoveryWorker";
6
7 /** Listen immediately; recovery-only machinery loads after the first signal. */
8 export function startControllerEventRecovery(ports: ControllerRecoveryPorts): () => void {
9 let disposed = false, loading = false, failures = 0;
10 let recover: (() => void) | undefined, stop: (() => void) | undefined;
11 let retry: ReturnType<typeof setTimeout> | undefined;
12 const request = () => {
13 if (disposed) return;
14 if (recover) { recover(); return; }
15 if (loading || retry !== undefined) return;
16 loading = true;
17 void import("./controllerEventRecoveryWorker").then(worker => {
18 if (disposed) return;
19 stop = worker.startControllerEventRecovery(ports, callback => {
20 recover = callback;
21 // All signals received during loading are covered by this fresh read.
22 callback();
23 return () => { recover = undefined; };
24 });
25 }).catch((error: unknown) => {
26 if (disposed) return;
27 loading = false;
28 recordFrontendDiagnostic("runtime", "desktop-event-recovery-load-failed", { error: String(error) });
29 retry = setTimeout(() => { retry = undefined; request(); }, Math.min(30000, 1000 * 2 ** Math.min(failures++, 5)));
30 });
31 };
32 const off = desktopHost().events.on("desktop:resync", request);
33 return () => { disposed = true; clearTimeout(retry); off(); stop?.(); };
34 }
35
35 lines TYPESCRIPT