返回 DeepSeek-Reasonix
workspaceRefreshScheduler.ts
根目录 / desktop / frontend / src / lib / workspaceRefreshScheduler.ts
1 export interface WorkspaceRefreshTimer {
2 schedule(callback: () => void, delayMs: number): unknown;
3 cancel(handle: unknown): void;
4 }
5
6 export interface WorkspaceRefreshScheduler {
7 trigger(run: () => Promise<void> | void): void;
8 cancel(): void;
9 }
10
11 const browserTimer: WorkspaceRefreshTimer = {
12 schedule: (callback, delayMs) => window.setTimeout(callback, delayMs),
13 cancel: (handle) => window.clearTimeout(handle as number),
14 };
15
16 /**
17 * Creates a trailing quiet-window scheduler with at most one refresh in flight.
18 * A trigger while a refresh is running is retained and executes once the quiet
19 * window has elapsed and the prior refresh settles.
20 */
21 export function createWorkspaceRefreshScheduler(delayMs: number, timer: WorkspaceRefreshTimer = browserTimer): WorkspaceRefreshScheduler {
22 let handle: unknown = null;
23 let inFlight = false;
24 let trailing = false;
25 let latest: (() => Promise<void> | void) | null = null;
26 let cancelled = false;
27
28 const start = () => {
29 const run = latest;
30 if (!run || cancelled) return;
31 if (inFlight) {
32 trailing = true;
33 return;
34 }
35 inFlight = true;
36 void Promise.resolve().then(run).finally(() => {
37 inFlight = false;
38 if (cancelled || !trailing) return;
39 trailing = false;
40 start();
41 });
42 };
43
44 return {
45 trigger(run: () => Promise<void> | void): void {
46 cancelled = false;
47 latest = run;
48 trailing = false;
49 if (handle !== null) timer.cancel(handle);
50 handle = timer.schedule(() => {
51 handle = null;
52 start();
53 }, delayMs);
54 },
55 cancel(): void {
56 cancelled = true;
57 trailing = false;
58 latest = null;
59 if (handle !== null) timer.cancel(handle);
60 handle = null;
61 },
62 };
63 }
64
64 lines TYPESCRIPT