mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-12 12:39:52 +08:00
feat(mcp-server): history entries name their maker, and /api/history the entry on the canvas
Each History entry records who made it (a user edit, a recovering tab's copy, a restored copy; none for the AI's writes), when, and its page count. GET /api/history now also returns each entry's XML, the first entry with the same content (a restore adds a copy of an older one), the state the ids belong to, and the entry whose content the canvas shows, by the rule restore_version uses. The shell's version cards read these; the classic page keeps using index, id and svg.
This commit is contained in:
@@ -50,6 +50,8 @@ import { contentFingerprint } from "./edit-gate.ts"
|
||||
import {
|
||||
addHistory,
|
||||
clearHistory,
|
||||
currentEntryId,
|
||||
firstCopyIds,
|
||||
getHistory,
|
||||
getHistoryEntry,
|
||||
updateLastHistorySvg,
|
||||
@@ -335,7 +337,7 @@ export function keepInHistory(sessionId: string, xml: string, svg = ""): void {
|
||||
if (state && !state.userEdited && last && last.xml === state.serverXml) {
|
||||
return
|
||||
}
|
||||
addHistory(sessionId, xml, svg)
|
||||
addHistory(sessionId, xml, svg, state?.userEdited ? "user" : undefined)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -741,7 +743,12 @@ function handleStateApi(
|
||||
!!data.xml &&
|
||||
data.xml !== current.xml
|
||||
if (saved) {
|
||||
addHistory(sessionId, data.xml, data.svg || "")
|
||||
addHistory(
|
||||
sessionId,
|
||||
data.xml,
|
||||
data.svg || "",
|
||||
"recover",
|
||||
)
|
||||
// Saved with the History, as after any change
|
||||
stateListener?.(sessionId, current.xml)
|
||||
}
|
||||
@@ -778,7 +785,7 @@ function handleStateApi(
|
||||
} else if (typeof data.xml === "string" && data.xml) {
|
||||
// A user edit lost the race with an AI write. Keep
|
||||
// it in history so the user can restore it.
|
||||
addHistory(sessionId, data.xml, data.svg || "")
|
||||
addHistory(sessionId, data.xml, data.svg || "", "user")
|
||||
savedToHistory = true
|
||||
if (current) stateListener?.(sessionId, current.xml)
|
||||
}
|
||||
@@ -832,7 +839,12 @@ function handleHistoryApi(
|
||||
return
|
||||
}
|
||||
|
||||
// The classic page reads index, id and svg; the shell's version cards
|
||||
// the rest: the document, who made it, which earlier entry it is a copy
|
||||
// of, the state the ids belong to, and the entry the canvas shows
|
||||
const history = getHistory(sessionId)
|
||||
const firstIds = firstCopyIds(sessionId)
|
||||
const state = stateStore.get(sessionId)
|
||||
res.writeHead(200, { "Content-Type": "application/json" })
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
@@ -840,8 +852,15 @@ function handleHistoryApi(
|
||||
index: i,
|
||||
id: entry.id,
|
||||
svg: entry.svg,
|
||||
xml: entry.xml,
|
||||
source: entry.source ?? null,
|
||||
time: entry.time,
|
||||
pages: entry.pages,
|
||||
firstId: firstIds.get(entry.id),
|
||||
})),
|
||||
count: history.length,
|
||||
stateId: state?.stateId ?? null,
|
||||
currentId: state ? currentEntryId(sessionId, state.xml) : null,
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -870,7 +889,7 @@ export function restoreHistoryEntry(
|
||||
keepInHistory(sessionId, current.xml, current.svg)
|
||||
}
|
||||
const newVersion = setState(sessionId, entry.xml)
|
||||
addHistory(sessionId, entry.xml, entry.svg)
|
||||
addHistory(sessionId, entry.xml, entry.svg, "restore")
|
||||
|
||||
log.info(`Restored session ${sessionId} to history entry ${entryId}`)
|
||||
return newVersion
|
||||
|
||||
Reference in New Issue
Block a user