import type { Memento } from 'vscode' import type { KanbanSnapshot } from './kanbanSnapshot' import type { ExtensionToWebview } from './messages' import { logger } from '../logging/logger' import { applyIssueUpdate, isIssueUpdate } from '../shared/kanbanUpdates' import { KANBAN_SNAPSHOT_KEY, parseKanbanSnapshot } from './kanbanSnapshot' class KanbanState { private current: KanbanSnapshot | undefined private writes: Promise = Promise.resolve() constructor(private readonly workspaceState: Memento) { this.current = parseKanbanSnapshot(workspaceState.get(KANBAN_SNAPSHOT_KEY)) ?? undefined } get snapshot(): KanbanSnapshot | undefined { return this.current } apply(message: ExtensionToWebview): Promise { if (message.type === 'issues/update') { const { type: _, ...snapshot } = message this.current = snapshot } else if (isIssueUpdate(message) && this.current) { this.current = { ...this.current, issues: applyIssueUpdate(this.current.issues, message) } } else { return this.writes } return this.persist(this.current) } invalidate(): Promise { this.current = undefined return this.persist(undefined) } private persist(snapshot: KanbanSnapshot | undefined): Promise { this.writes = this.writes .then(() => this.workspaceState.update(KANBAN_SNAPSHOT_KEY, snapshot)) .catch((error: unknown) => { logger.add({ level: 'error', source: 'kanban', message: '保存看板快照失败', details: error instanceof Error ? error.message : String(error), }) }) return this.writes } } const states = new WeakMap() export function getKanbanState(workspaceState: Memento): KanbanState { let state = states.get(workspaceState) if (!state) { state = new KanbanState(workspaceState) states.set(workspaceState, state) } return state }