Files
Agent-System/web/src/hooks/useWorkbenchPersistence.ts
T
weichenandCursor bfe8cb1407 refactor(web): persist the workbench from one hook
Session, project, and deliverable caches were written from scattered effects, and the legacy message migration ran twice on mount. One hook keeps that write path in a single place.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 11:01:44 +00:00

75 lines
2.0 KiB
TypeScript

import { useEffect, type Dispatch, type MutableRefObject, type SetStateAction } from 'react';
import {
migrateAndClearLegacyMessages,
saveActiveSessionId,
saveDeliverables,
saveProjects,
saveSessions,
saveUsers,
} from '../data/storage';
import { applyRestoredFileRaw, restoreFileRawToDeliverables } from '../data/fileStore';
import type { UserProfile } from '../types/docgov';
import type { DeliverableItem, ProjectInfo, ProjectSession } from '../types/workbench';
export interface WorkbenchPersistenceInput {
sessions: ProjectSession[];
activeSessionId: string;
allUsers: UserProfile[];
deliverables: DeliverableItem[];
deliverablesRef: MutableRefObject<DeliverableItem[]>;
setDeliverables: Dispatch<SetStateAction<DeliverableItem[]>>;
projects: ProjectInfo[];
}
/**
* 工作台本地缓存的写入与一次性迁移。
* 必须在对应 useState 初始化之后调用;demo seed 清理仍留在渲染前,不能放进 effect。
*/
export function useWorkbenchPersistence(input: WorkbenchPersistenceInput): void {
const {
sessions,
activeSessionId,
allUsers,
deliverables,
deliverablesRef,
setDeliverables,
projects,
} = input;
useEffect(() => {
saveSessions(sessions);
}, [sessions]);
useEffect(() => {
saveActiveSessionId(activeSessionId);
}, [activeSessionId]);
useEffect(() => {
saveUsers(allUsers);
}, [allUsers]);
useEffect(() => {
saveDeliverables(deliverables);
}, [deliverables]);
useEffect(() => {
saveProjects(projects);
}, [projects]);
useEffect(() => {
let cancelled = false;
const snapshot = deliverablesRef.current;
restoreFileRawToDeliverables(snapshot).then((restored) => {
if (cancelled || restored === snapshot) return;
setDeliverables((prev) => applyRestoredFileRaw(prev, restored));
});
return () => {
cancelled = true;
};
}, [deliverablesRef, setDeliverables]);
useEffect(() => {
void migrateAndClearLegacyMessages();
}, []);
}