chatccc 0.2.45 → 0.2.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,87 @@
1
+ // ---------------------------------------------------------------------------
2
+ // session ↔ chats 双向映射
3
+ // ---------------------------------------------------------------------------
4
+ // sessionChatsMap: sessionId → Set<chatId>
5
+ // 由 session.ts 在初始化时调用 rebuildSessionChatsFromRegistry 重建
6
+ // ---------------------------------------------------------------------------
7
+
8
+ const sessionChatsMap = new Map<string, Set<string>>();
9
+
10
+ /** 从 registry 数据重建映射(由 session.ts 调用,避免循环依赖) */
11
+ export function rebuildSessionChatsFromRegistry(registry: Record<string, { chatId: string; sessionId: string }>): void {
12
+ sessionChatsMap.clear();
13
+ for (const record of Object.values(registry)) {
14
+ if (!record.sessionId || !record.chatId) continue;
15
+ bindChatToSession(record.sessionId, record.chatId);
16
+ }
17
+ }
18
+
19
+ export function bindChatToSession(sessionId: string, chatId: string): void {
20
+ let chats = sessionChatsMap.get(sessionId);
21
+ if (!chats) {
22
+ chats = new Set();
23
+ sessionChatsMap.set(sessionId, chats);
24
+ }
25
+ chats.add(chatId);
26
+ }
27
+
28
+ export function unbindChatFromSession(sessionId: string, chatId: string): void {
29
+ const chats = sessionChatsMap.get(sessionId);
30
+ if (chats) {
31
+ chats.delete(chatId);
32
+ if (chats.size === 0) sessionChatsMap.delete(sessionId);
33
+ }
34
+ }
35
+
36
+ export function getChatsForSession(sessionId: string): string[] {
37
+ const chats = sessionChatsMap.get(sessionId);
38
+ return chats ? Array.from(chats) : [];
39
+ }
40
+
41
+ /** 检查 session 是否还有任何群绑定 */
42
+ export function hasChatsForSession(sessionId: string): boolean {
43
+ return (sessionChatsMap.get(sessionId)?.size ?? 0) > 0;
44
+ }
45
+
46
+ /** 检查 sessionId 是否正被其他 chatId 使用(有活跃 prompt) */
47
+ export function isSessionRunning(sessionId: string): boolean {
48
+ return activePrompts.has(sessionId);
49
+ }
50
+
51
+ // ---------------------------------------------------------------------------
52
+ // activePrompts: sessionId → 活跃 prompt 控制
53
+ // ---------------------------------------------------------------------------
54
+
55
+ export interface ActivePrompt {
56
+ controller: AbortController;
57
+ stopped: boolean;
58
+ startTime: number;
59
+ }
60
+
61
+ export const activePrompts = new Map<string, ActivePrompt>();
62
+
63
+ // ---------------------------------------------------------------------------
64
+ // displayCards: chatId → 展示卡片状态(display loop 用)
65
+ // ---------------------------------------------------------------------------
66
+
67
+ export interface DisplayCardState {
68
+ cardId: string;
69
+ sequence: number;
70
+ cardBusy: boolean;
71
+ cardCreatedAt: number;
72
+ lastSentContent: string;
73
+ streamErrorNotified: boolean;
74
+ }
75
+
76
+ export const displayCards = new Map<string, DisplayCardState>();
77
+
78
+ /** displayLoops: sessionId → 展示循环的 stop 函数 */
79
+ export const displayLoops = new Map<string, () => void>();
80
+
81
+ export function resetBindingState(): void {
82
+ sessionChatsMap.clear();
83
+ activePrompts.clear();
84
+ displayCards.clear();
85
+ for (const stop of displayLoops.values()) stop();
86
+ displayLoops.clear();
87
+ }