返回 DeepSeek-Reasonix
transcriptSessionBinding.ts
根目录 / desktop / frontend / src / lib / transcriptSessionBinding.ts
1 import type { SessionTranscript } from "./transcriptStoreTypes";
2
3 export type TranscriptTabBinding = {
4 key: string;
5 sessionPath: string;
6 bindingKey: string;
7 };
8
9 function legacySessionKeyFor(tabId: string, sessionPath: string): string {
10 return `${tabId}\n${sessionPath}`;
11 }
12
13 function stableSessionKeyFor(bindingKey: string): string | undefined {
14 return bindingKey.startsWith("s\0") ? `stable\0${bindingKey}` : undefined;
15 }
16
17 export function boundSessionKey(
18 bindings: Map<string, TranscriptTabBinding>,
19 tabId: string,
20 sessionPath: string,
21 ): string {
22 const binding = bindings.get(tabId);
23 return binding?.sessionPath === sessionPath ? binding.key : legacySessionKeyFor(tabId, sessionPath);
24 }
25
26 export function bindTranscriptSession(
27 bindings: Map<string, TranscriptTabBinding>,
28 sessions: Map<string, SessionTranscript>,
29 tabId: string,
30 sessionPath: string,
31 bindingKey: string,
32 create: (key: string) => SessionTranscript,
33 evict: (session: SessionTranscript) => void,
34 touch: (session: SessionTranscript) => void,
35 ): boolean {
36 const previous = bindings.get(tabId);
37 const key = stableSessionKeyFor(bindingKey) ?? legacySessionKeyFor(tabId, sessionPath);
38 if (previous?.key === key && previous.sessionPath === sessionPath && previous.bindingKey === bindingKey) return false;
39 const replaced = Boolean(previous);
40 bindings.delete(tabId);
41 if (previous && (previous.key !== key || (!key.startsWith("stable\0") && previous.bindingKey !== bindingKey))) {
42 const previousSession = sessions.get(previous.key);
43 if (previousSession && !previous.key.startsWith("stable\0")) evict(previousSession);
44 }
45 let session = sessions.get(key);
46 if (!session) {
47 session = create(key);
48 sessions.set(key, session);
49 } else if (session.tabId !== tabId || session.sessionPath !== sessionPath) {
50 session.generation += 1;
51 session.pendingContent.clear();
52 for (const [otherTabId, binding] of bindings) {
53 if (binding.key === key) bindings.delete(otherTabId);
54 }
55 session.tabId = tabId;
56 session.sessionPath = sessionPath;
57 }
58 session.bindingKey = bindingKey;
59 bindings.set(tabId, { key, sessionPath, bindingKey });
60 touch(session);
61 return replaced;
62 }
63
64 export function detachTranscriptTab(
65 bindings: Map<string, TranscriptTabBinding>,
66 sessions: Map<string, SessionTranscript>,
67 tabId: string,
68 evict: (session: SessionTranscript) => void,
69 ): void {
70 const binding = bindings.get(tabId);
71 bindings.delete(tabId);
72 if (binding && !binding.key.startsWith("stable\0")) {
73 const session = sessions.get(binding.key);
74 if (session) evict(session);
75 } else if (!binding) {
76 for (const session of Array.from(sessions.values())) {
77 if (session.tabId === tabId && !session.key.startsWith("stable\0")) evict(session);
78 }
79 }
80 }
81
81 lines TYPESCRIPT