返回 DeepSeek-Reasonix
useTopicSummary.ts
根目录 / desktop / frontend / src / app-runtime / useTopicSummary.ts
1 import { useEffect, useMemo, useState } from "react";
2
3 import { useCommittedCommand } from "../lib/useCommittedCommand";
4 import { desktopBridge } from "./desktopBridgeAdapter";
5 import type { TabMeta } from "../lib/types";
6
7 type TopicSummary = Readonly<{ turns?: number }>;
8
9 /**
10 * Owns the topic summary chain: the target memo keyed by topic identity, the
11 * GetTopicSummary bridge command, the single-flight fetch (an identity or
12 * revision change cancels the superseded request) and the resulting
13 * activeTopicTurns state. Presentation reads only the returned turns.
14 */
15 export function useTopicSummary(input: {
16 activeTab: TabMeta | undefined;
17 revision: number;
18 }): { activeTopicTurns: number | undefined } {
19 const { activeTab, revision } = input;
20 const [activeTopicTurns, setActiveTopicTurns] = useState<number | undefined>(undefined);
21
22 const scope = activeTab?.scope;
23 const workspaceRoot = activeTab?.workspaceRoot;
24 const topicId = activeTab?.topicId;
25 const target = useMemo(() => (topicId === undefined ? null : { scope, workspaceRoot, topicId }),
26 [scope, workspaceRoot, topicId]);
27
28 const getSummary = useCommittedCommand((request: { scope: "global" | "project"; workspaceRoot: string; topicId: string }) => desktopBridge.getTopicSummary(request));
29 const commitTurns = useCommittedCommand((turns: number | undefined) => setActiveTopicTurns(turns));
30
31 useEffect(() => {
32 const currentTarget = target;
33 const topicId = currentTarget?.topicId?.trim();
34 if (!topicId) {
35 commitTurns(undefined);
36 return;
37 }
38 let current = true;
39 void getSummary({
40 scope: currentTarget?.scope === "global" ? "global" : "project",
41 workspaceRoot: currentTarget?.scope === "global" ? "" : currentTarget?.workspaceRoot ?? "",
42 topicId,
43 }).then((summary: TopicSummary) => {
44 if (current) commitTurns(summary.turns);
45 }).catch(() => {
46 if (current) commitTurns(undefined);
47 });
48 return () => { current = false; };
49 }, [getSummary, commitTurns, revision, target]);
50
51 return { activeTopicTurns };
52 }
53
53 lines TYPESCRIPT