实现的文件:
brave-sync-notes/client/src/utils/storage/ClientStorage.js- 存储接口定义brave-sync-notes/client/src/utils/storage/IndexedDBStorage.js- IndexedDB 实现brave-sync-notes/client/src/utils/storage/LocalStorageAdapter.js- LocalStorage 降级方案brave-sync-notes/client/src/utils/storage/StorageManager.js- 存储管理器(自动切换)brave-sync-notes/client/src/utils/storage/index.js- 模块导出brave-sync-notes/client/src/utils/storage/README.md- 使用文档
功能特性:
- ✅ 完整的 IndexedDB 实现,支持笔记本、笔记、历史记录、离线队列
- ✅ LocalStorage 自动降级机制
- ✅ 存储配额检测和自动清理
- ✅ 数据迁移功能
- ✅ 版本管理和 schema 升级
- ✅ 统一的存储接口
数据结构:
- Notebooks(笔记本)
- Notes(笔记)
- History(历史记录)
- PendingOps(离线队列)
实现的文件:
brave-sync-notes/client/src/utils/conflict/ConflictDetector.js- 冲突检测器brave-sync-notes/client/src/utils/conflict/ConflictResolver.js- 冲突解决器brave-sync-notes/client/src/utils/conflict/ConflictManager.js- 冲突管理器brave-sync-notes/client/src/utils/conflict/index.js- 模块导出
功能特性:
- ✅ 基于时间戳和版本号的冲突检测
- ✅ 三路合并算法
- ✅ 多种自动解决策略:
- last-write-wins(最后写入获胜)
- first-write-wins(第一个写入获胜)
- auto-merge(自动合并)
- manual(手动解决)
- ✅ 冲突队列管理
- ✅ 冲突报告生成
实现的文件:
brave-sync-notes/client/src/components/Conflict/ConflictDialog.jsx- 冲突解决对话框brave-sync-notes/client/src/components/Conflict/ConflictIndicator.jsx- 冲突指示器brave-sync-notes/client/src/components/Conflict/index.js- 组件导出
功能特性:
- ✅ 并排对比本地和远程版本
- ✅ 选择版本或自定义合并
- ✅ 冲突类型显示
- ✅ 时间戳和设备信息
- ✅ 顶部冲突指示器
需要实现:
- 笔记本数据模型
- 笔记本管理器
- 笔记本 UI(选择、创建、设置)
- QR 码分享功能
需要实现:
- 离线操作队列(已有基础存储)
- 增强网络状态检测
- 离线状态指示器
- 自动同步逻辑
import { getStorageManager } from './utils/storage';
// 初始化
const storage = getStorageManager();
await storage.initialize();
// 保存笔记本
await storage.saveNotebook({
id: 'notebook-1',
name: 'My Notebook',
mnemonic: '...',
encryptionKey: '...',
roomId: '...'
});
// 保存笔记
await storage.saveNote('notebook-1', {
id: 'note-1',
title: 'My Note',
content: '# Hello',
tags: ['work']
});import { ConflictManager } from './utils/conflict';
// 创建管理器
const conflictManager = new ConflictManager({
autoResolveStrategy: 'last-write-wins', // 或 'manual'
onConflictDetected: (conflict) => {
console.log('Conflict detected:', conflict);
},
onConflictResolved: (conflict, resolved) => {
console.log('Conflict resolved:', resolved);
}
});
// 检查冲突
const result = await conflictManager.checkAndHandle(localData, remoteData);
if (result.hasConflict && !result.resolved) {
// 显示冲突解决 UI
showConflictDialog(result.conflict);
}import { ConflictDialog, ConflictIndicator } from './components/Conflict';
// 在 App 组件中
const [currentConflict, setCurrentConflict] = useState(null);
const [conflictCount, setConflictCount] = useState(0);
<ConflictIndicator
conflictCount={conflictCount}
onClick={() => showNextConflict()}
darkMode={darkMode}
/>
<ConflictDialog
conflict={currentConflict}
onResolve={(resolved) => handleResolve(resolved)}
onCancel={() => setCurrentConflict(null)}
darkMode={darkMode}
/>- 自动降级机制:IndexedDB → LocalStorage,确保在所有环境中都能工作
- 智能冲突检测:基于时间窗口和版本号的多维度检测
- 灵活的解决策略:支持自动和手动解决,适应不同场景
- 完整的数据管理:笔记本、笔记、历史、队列的统一管理
- 用户友好的 UI:直观的冲突对比和解决界面
// 测试 IndexedDB 存储
const storage = new IndexedDBStorage();
await storage.initialize();
await storage.saveNotebook(testNotebook);
const retrieved = await storage.getNotebook(testNotebook.id);
assert(retrieved.id === testNotebook.id);
// 测试降级机制
// 禁用 IndexedDB,验证自动切换到 LocalStorage// 测试并发编辑检测
const local = { content: 'A', version: 1, timestamp: 1000 };
const remote = { content: 'B', version: 1, timestamp: 1001 };
const conflict = detector.detectConflict(local, remote);
assert(conflict.type === 'concurrent_edit');
// 测试三路合并
const merged = detector.threeWayMerge(base, local, remote);
assert(merged.success === true);- IndexedDB 使用索引加速查询
- 历史记录自动清理,限制数量
- 批量操作使用事务
- 冲突检测使用哈希快速比较
- 所有存储的数据都应该是加密的
- 冲突解决不会泄露未加密的内容
- 存储配额检测防止滥用
- LocalStorage 有 5-10MB 限制
- IndexedDB 在某些浏览器的隐私模式下不可用
- 三路合并算法对复杂冲突可能需要手动介入
- 添加属性测试(Property-Based Tests)
- 实现数据压缩以节省空间
- 添加更智能的合并算法
- 实现冲突预防机制(乐观锁)