Files
superwork/vscode/src/panel/kanbanState.ts
T

64 lines
1.9 KiB
TypeScript

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<void> = 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<void> {
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<void> {
this.current = undefined
return this.persist(undefined)
}
private persist(snapshot: KanbanSnapshot | undefined): Promise<void> {
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<Memento, KanbanState>()
export function getKanbanState(workspaceState: Memento): KanbanState {
let state = states.get(workspaceState)
if (!state) {
state = new KanbanState(workspaceState)
states.set(workspaceState, state)
}
return state
}