返回 DeepSeek-Reasonix
openTopicCoalescing.ts
根目录 / desktop / frontend / src / lib / openTopicCoalescing.ts
1 export type PendingNavigationRequest<T extends object> = T & {
2 seq: number;
3 resolve: () => void;
4 };
5
6 export type NavigationCoalescingRefs<T extends object> = {
7 seqRef: { current: number };
8 runningRef: { current: boolean };
9 pendingRef: { current: PendingNavigationRequest<T> | null };
10 };
11
12 export function enqueueNavigationRequest<T extends object>(
13 refs: NavigationCoalescingRefs<T>,
14 input: T,
15 run: (request: PendingNavigationRequest<T>) => Promise<void>,
16 ): Promise<void> {
17 const seq = refs.seqRef.current + 1;
18 refs.seqRef.current = seq;
19
20 let resolve!: () => void;
21 const promise = new Promise<void>((res) => {
22 resolve = res;
23 });
24 const request: PendingNavigationRequest<T> = { ...input, seq, resolve };
25
26 const start = (next: PendingNavigationRequest<T>) => {
27 refs.runningRef.current = true;
28 void (async () => {
29 try {
30 await run(next);
31 } catch {
32 // run() is expected to handle user-visible failures. The scheduler keeps
33 // navigation promises non-rejecting so event handlers cannot leak
34 // unhandled rejections.
35 } finally {
36 next.resolve();
37 const pending = refs.pendingRef.current;
38 if (pending) {
39 refs.pendingRef.current = null;
40 start(pending);
41 } else {
42 refs.runningRef.current = false;
43 }
44 }
45 })();
46 };
47
48 if (refs.runningRef.current) {
49 refs.pendingRef.current?.resolve();
50 refs.pendingRef.current = request;
51 return promise;
52 }
53
54 start(request);
55 return promise;
56 }
57
58 export type PendingOpenTopicRequest = PendingNavigationRequest<{
59 scope: string;
60 workspaceRoot: string;
61 topicId: string;
62 sessionPath?: string;
63 }>;
64
65 export type OpenTopicRequestInput = Omit<PendingOpenTopicRequest, "seq" | "resolve">;
66
67 export type OpenTopicCoalescingRefs = NavigationCoalescingRefs<OpenTopicRequestInput>;
68
69 export function enqueueOpenTopicRequest(
70 refs: OpenTopicCoalescingRefs,
71 input: OpenTopicRequestInput,
72 run: (request: PendingOpenTopicRequest) => Promise<void>,
73 ): Promise<void> {
74 return enqueueNavigationRequest(refs, input, run);
75 }
76
76 lines TYPESCRIPT