返回 DeepSeek-Reasonix
previousDraftMock.ts
根目录 / desktop / frontend / src / lib / previousDraftMock.ts
1 import type { SessionDraftView, SessionDraftSubmissionView, SessionDraftSaveRequest, SessionDraftSubmissionRequest } from "../generated/desktopContract.generated";
2 import type { PreviousDraftBindings } from "./previousDraftBindings";
3
4 export function makePreviousDraftMock(): PreviousDraftBindings {
5 const mockDrafts = new Map<string, SessionDraftView>();
6 const mockDraftOperations = new Map<string, SessionDraftSubmissionView>();
7 const mockDraftForTarget = (scope: string, workspaceRoot: string): SessionDraftView => {
8 const normalizedScope = scope === "project" && workspaceRoot ? "project" : "global";
9 const normalizedRoot = normalizedScope === "project" ? workspaceRoot : "";
10 const workspaceId = normalizedScope === "global" ? "global" : `project-${normalizedRoot}`;
11 const prior = [...mockDrafts.values()].find((draft) => draft.workspaceId === workspaceId && draft.status === "active");
12 if (prior) return prior;
13 throw new Error("No previous draft exists; create a formal conversation");
14 };
15 return {
16 async OpenSessionDraft(workspaceId: string) {
17 const prior = [...mockDrafts.values()].find((draft) => draft.workspaceId === workspaceId && draft.status === "active");
18 if (prior) return structuredClone(prior);
19 return structuredClone(mockDraftForTarget(workspaceId === "global" ? "global" : "project", workspaceId === "global" ? "" : workspaceId));
20 },
21 async OpenSessionDraftForTarget(scope: string, workspaceRoot: string) {
22 return structuredClone(mockDraftForTarget(scope, workspaceRoot));
23 },
24 async RestoreSessionDraft() {
25 return structuredClone([...mockDrafts.values()].find((draft) => draft.status === "active") ?? null);
26 },
27 async SaveSessionDraft(request: SessionDraftSaveRequest) {
28 const current = mockDrafts.get(request.draftId);
29 if (!current || current.status !== "active") throw new Error("session draft not found");
30 if (current.revision !== request.revision) return { draft: structuredClone(current), conflict: true, outcome: "conflict" };
31 const next = { ...current, revision: current.revision + 1, contentJson: request.contentJson, settings: structuredClone(request.settings), updatedAt: Date.now() };
32 mockDrafts.set(next.id, next);
33 return { draft: structuredClone(next), conflict: false, outcome: "saved" };
34 },
35 async ListSessionDraftSummaries() {
36 return [...mockDrafts.values()].filter((draft) => draft.status === "active").map((draft) => ({
37 id: draft.id, workspaceId: draft.workspaceId, scope: draft.scope, workspaceRoot: draft.workspaceRoot,
38 revision: draft.revision, hasContent: draft.contentJson !== "{}", state: "saved", updatedAt: draft.updatedAt,
39 }));
40 },
41 async DiscardSessionDraft(draftId: string, revision: number) {
42 const current = mockDrafts.get(draftId);
43 if (!current || current.revision !== revision) throw new Error("session draft revision conflict");
44 mockDrafts.set(draftId, { ...current, status: "discarded", revision: current.revision + 1 });
45 },
46 async DismissSessionDraft(_draftId: string) {},
47 async SetSessionDraftRestoreTarget(_draftId: string) {},
48 async GetSessionDraft(draftId: string) {
49 const draft = mockDrafts.get(draftId);
50 if (!draft) throw new Error("session draft not found");
51 return structuredClone(draft);
52 },
53 async GetDraftContext(draftId: string) {
54 const draft = mockDrafts.get(draftId);
55 if (!draft) throw new Error("session draft not found");
56 return { draft: structuredClone(draft), commands: [], servers: [] };
57 },
58 async GetSessionDraftState(draftId: string) {
59 const draft = mockDrafts.get(draftId);
60 if (!draft) throw new Error("session draft not found");
61 const operation = [...mockDraftOperations.values()].reverse().find(item => item.draftId === draftId);
62 return structuredClone({ draft, operation });
63 },
64 async ResumeDraftSubmission(operationId: string, revision: number) {
65 const operation = mockDraftOperations.get(operationId);
66 if (!operation || operation.revision !== revision) throw new Error("operation revision conflict");
67 return structuredClone(operation);
68 },
69 async BeginDraftSubmission(request: SessionDraftSubmissionRequest) {
70 const draft = mockDrafts.get(request.draftId);
71 if (!draft || draft.revision !== request.revision) throw new Error("session draft revision conflict");
72 const operationId = `draft-op-mock-${mockDraftOperations.size + 1}`;
73 const sessionId = `draft-session-mock-${mockDraftOperations.size + 1}`;
74 const view: SessionDraftSubmissionView = { operationId, draftId: draft.id, requestId: request.requestId, revision: 1, canResume: false, canEdit: false, canCancel: false, canDiscard: false, phase: "accepted", submissionId: `draft-submit-mock-${mockDraftOperations.size + 1}`, session: { hostId: "local", sessionId }, updatedAt: Date.now() };
75 mockDraftOperations.set(operationId, view);
76 mockDrafts.set(draft.id, { ...draft, status: "converted", revision: draft.revision + 1 });
77 return structuredClone(view);
78 },
79 async GetDraftSubmission(operationId: string) {
80 const operation = mockDraftOperations.get(operationId);
81 if (!operation) throw new Error("session draft submission not found");
82 return structuredClone(operation);
83 },
84 async CancelDraftSubmission(operationId: string) {
85 const operation = mockDraftOperations.get(operationId);
86 if (!operation) throw new Error("session draft submission not found");
87 const next = { ...operation, phase: operation.phase === "accepted" ? "accepted" : "cancelled", updatedAt: Date.now() };
88 mockDraftOperations.set(operationId, next);
89 return structuredClone(next);
90 },
91 };
92 }
93
93 lines TYPESCRIPT