Files

102 lines
3.2 KiB
JavaScript

import { persistGet, persistSet } from './persistence';
import { getChapters, saveChapters } from './storage';
import { getSettingsNodes, saveSettingsNodes, getActiveWorkId } from './settings';
const SNAPSHOTS_KEY = 'author-snapshots';
/**
* 获取所有快照
* @returns {Promise<Array>} 快照列表(按时间倒序)
*/
export async function getSnapshots() {
try {
const snapshots = await persistGet(SNAPSHOTS_KEY);
return Array.isArray(snapshots) ? snapshots : [];
} catch (e) {
console.error('Failed to get snapshots:', e);
return [];
}
}
/**
* 创建新快照
* @param {string} label - 快照标签描述
* @param {string} type - 'auto' | 'manual'
* @returns {Promise<object>}
*/
export async function createSnapshot(label, type = 'auto') {
try {
const chapters = await getChapters(getActiveWorkId());
const settingsNodes = await getSettingsNodes();
const snapshot = {
id: `snap-${Date.now()}`,
timestamp: Date.now(),
label: label || (type === 'auto' ? '自动存档' : '手动存档'),
type,
stats: {
chapterCount: chapters.length,
totalWords: chapters.reduce((acc, ch) => acc + (ch.wordCount || 0), 0),
settingCount: settingsNodes.length,
},
data: {
chapters,
settingsNodes,
}
};
const existing = await getSnapshots();
existing.unshift(snapshot); // 最新在前
// 限制自动快照数量(例如最多保留 50 个自动快照,超出的按时间删除)
const maxAutoSnapshots = 50;
let finalSnapshots = existing;
const autoSnapshots = existing.filter(s => s.type === 'auto');
if (autoSnapshots.length > maxAutoSnapshots) {
const toRemove = autoSnapshots.slice(maxAutoSnapshots).map(s => s.id);
finalSnapshots = existing.filter(s => !toRemove.includes(s.id));
}
await persistSet(SNAPSHOTS_KEY, finalSnapshots);
return snapshot;
} catch (e) {
console.error('Failed to create snapshot:', e);
throw e;
}
}
/**
* 恢复到指定快照
* @param {string} snapshotId
* @returns {Promise<boolean>}
*/
export async function restoreSnapshot(snapshotId) {
try {
const snapshots = await getSnapshots();
const target = snapshots.find(s => s.id === snapshotId);
if (!target) throw new Error('Snapshot not found');
// 发起静默的当前状态备份,以防后悔
await createSnapshot('恢复前的备份', 'auto');
// 覆盖现有数据
await saveChapters(target.data.chapters || [], getActiveWorkId());
await saveSettingsNodes(target.data.settingsNodes || []);
return true;
} catch (e) {
console.error('Failed to restore snapshot:', e);
throw e;
}
}
/**
* 删除指定快照
*/
export async function deleteSnapshot(snapshotId) {
const snapshots = await getSnapshots();
const remaining = snapshots.filter(s => s.id !== snapshotId);
await persistSet(SNAPSHOTS_KEY, remaining);
return remaining;
}