返回 DeepSeek-Reasonix
inboxQueueDrafts.ts
根目录 / desktop / frontend / src / lib / inboxQueueDrafts.ts
1 import type { InboxQueueEdit } from "./inboxQueueCommands";
2 import type { InboxTarget } from "./pendingFollowup";
3
4 export type QueueEditDraft = InboxQueueEdit & { target: InboxTarget; value: string; reason?: string };
5 export type QueueDraftState = { edit?: QueueEditDraft; recovered: QueueEditDraft[] };
6 const empty: QueueDraftState = { recovered: [] };
7 const states = new Map<string, QueueDraftState>();
8 const listeners = new Set<() => void>();
9 const storageKey = (scope: string) => `reasonix.inbox-edit.v1:${scope}`;
10
11 // Separate from the main composer draft: switching tasks or closing the edit
12 // view cannot overwrite either piece of user input. No requests are replayed.
13 export const inboxQueueDrafts = {
14 subscribe(fn: () => void) { listeners.add(fn); return () => { listeners.delete(fn); }; },
15 get(scope: string): QueueDraftState {
16 if (!scope) return empty;
17 if (!states.has(scope)) {
18 let state = empty;
19 try {
20 const parsed = JSON.parse(sessionStorage.getItem(storageKey(scope)) || "null");
21 if (parsed && Array.isArray(parsed.recovered) && (!parsed.edit || (typeof parsed.edit.value === "string" && parsed.edit.target))) state = parsed;
22 } catch { /* The in-memory draft remains available when storage is disabled. */ }
23 states.set(scope, state);
24 }
25 return states.get(scope)!;
26 },
27 set(scope: string, state: QueueDraftState) {
28 if (!scope) return;
29 states.set(scope, state);
30 try { sessionStorage.setItem(storageKey(scope), JSON.stringify(state)); } catch { /* Keep the live draft. */ }
31 listeners.forEach(fn => fn());
32 },
33 };
34
34 lines TYPESCRIPT