delta-sync
Version:
A lightweight framework for bi-directional database synchronization with automatic version tracking and conflict resolution.
373 lines (294 loc) • 10.3 kB
Markdown
# DeltaSync
[](https://www.npmjs.com/package/delta-sync)
[](https://opensource.org/licenses/ISC)
**一个轻量级跨平台数据同步引擎**
DeltaSync 是一个专门为现代应用设计的数据同步框架,它能帮助开发者轻松实现数据的双向同步、离线存储和冲突处理。无论是 Web 应用、移动应用还是桌面应用,DeltaSync 都能提供一致的同步体验。
## 核心特性
- **轻量灵活**: 核心代码不到2000行,依赖极少
- **适配器模式**: 轻松对接任意数据库系统
- **版本控制**: 自动跟踪数据变更,使用基于时间戳的版本号
- **增量同步**: 通过检查点机制仅同步变更数据,大幅提升性能
- **离线支持**: 完整的离线工作能力,网络恢复后自动同步
- **类型安全**: 使用 TypeScript 编写,提供完整类型定义
- **批量处理**: 支持批量数据同步
- **完整事件**: 提供丰富的同步事件回调
- **墓碑机制**: 完善的删除追踪机制,支持保留策略
## 安装
```bash
npm install delta-sync
```
## 快速开始
1. 创建数据库适配器:
```typescript
import { DatabaseAdapter } from 'delta-sync';
class MyDatabaseAdapter implements DatabaseAdapter {
async readStore<T extends { id: string }>(
storeName: string,
limit?: number,
offset?: number
): Promise<{ items: T[]; hasMore: boolean }> {
// 实现数据读取逻辑
}
async listStoreItems(
storeName: string,
offset?: number,
since?: number,
before?: number
): Promise<{
items: Array<{ id: string; _ver: number; store?: string; deleted?: boolean }>;
hasMore?: boolean;
offset?: number;
}> {
// 实现列表项逻辑(用于同步视图)
}
async readBulk<T extends { id: string }>(
storeName: string,
ids: string[]
): Promise<T[]> {
// 实现批量读取逻辑
}
async putBulk<T extends { id: string }>(
storeName: string,
items: T[]
): Promise<T[]> {
// 实现批量写入逻辑
}
async deleteBulk(storeName: string, ids: string[]): Promise<void> {
// 实现批量删除逻辑
}
async clearStore(storeName: string): Promise<boolean> {
// 实现清空存储逻辑
}
}
```
2. 初始化同步引擎:
```typescript
import { SyncEngine } from 'delta-sync';
const localAdapter = new MyDatabaseAdapter();
const cloudAdapter = new MyCloudAdapter();
// 指定需要同步的存储
const storesToSync = ['notes', 'tasks', 'tombStones'];
const engine = new SyncEngine(localAdapter, storesToSync, {
autoSync: {
enabled: true,
pullInterval: 60000, // 每60秒自动同步
pushDebounce: 10000 // 本地更改10秒后推送
},
onStatusUpdate: (status) => {
console.log('同步状态:', status);
}
});
// 初始化引擎
await engine.initialize();
// 设置云端适配器
await engine.setCloudAdapter(cloudAdapter);
```
3. 数据操作:
```typescript
// 保存数据(单个或批量)
await engine.save('notes', {
id: '1',
title: '测试笔记',
content: '内容...'
});
// 保存多个项目
await engine.save('notes', [
{ id: '1', title: '笔记1', content: '...' },
{ id: '2', title: '笔记2', content: '...' }
]);
// 删除数据
await engine.delete('notes', '1');
// 或删除多个
await engine.delete('notes', ['1', '2']);
```
## 同步原理
DeltaSync 采用基于版本的增量同步机制:
1. **版本追踪**: 每个数据项都有一个 `_ver` 字段(基于时间戳的版本号)
2. **变更追踪**: 使用 `SyncView` 存储所有数据的最新版本信息,用于快速比对
3. **同步模式**:
- **全量同步**: 使用 SyncView 比对本地和云端的所有数据
- **增量同步**: 使用检查点机制,仅同步自上次同步以来的变更
- **推送**: 将本地新版本数据推送到云端
- **拉取**: 拉取云端新版本数据到本地
- **冲突处理**: 采用"最新版本胜出"策略(更高的 `_ver` 获胜)
4. **墓碑机制**:
- 已删除的项目会被追踪在特殊的 `tombStones` 存储中
- 墓碑默认保留180天
- 确保删除操作在所有设备间正确传播
5. **离线支持**:
- 离线时正常工作
- 变更会被缓存,网络恢复后自动同步
- 防止重复同步
## 高级功能
### 同步方法
```typescript
// 全量同步(先拉取后推送)
await engine.fullSync();
// 仅拉取远程更改(全量比对)
await engine.pull();
// 增量拉取(仅拉取自上次同步以来的变更)
await engine.incrementalPull();
// 仅推送本地更改
await engine.push();
```
### 自定义同步选项
```typescript
engine.updateSyncOptions({
maxRetries: 3, // 最大重试次数
timeout: 30000, // 超时时间(ms)
batchSize: 100, // 批量同步大小
maxFileSize: 10485760, // 最大文件大小(10MB)
fileChunkSize: 1048576, // 文件分片大小(1MB)
autoSync: {
enabled: true,
pullInterval: 60000, // 拉取间隔(ms)
pushDebounce: 10000, // 推送防抖延迟(ms)
retryDelay: 3000 // 重试延迟(ms)
}
});
```
### 同步事件监听
```typescript
const options = {
onStatusUpdate: (status: SyncStatus) => {
console.log('同步状态:', status);
},
onSyncProgress: (progress: { processed: number; total: number }) => {
console.log(`进度: ${progress.processed}/${progress.total}`);
},
onVersionUpdate: (version: number) => {
console.log('最新版本已更新到:', version);
},
onChangePushed: (changes: DataChangeSet) => {
console.log('推送变更:', changes);
},
onChangePulled: (changes: DataChangeSet) => {
console.log('拉取变更:', changes);
},
onPullAvailableCheck: () => {
// 返回 true 表示允许拉取
return navigator.onLine;
},
onPushAvailableCheck: () => {
// 返回 true 表示允许推送
return navigator.onLine;
}
};
```
### 存储管理
```typescript
// 清空本地存储
await engine.clearLocalStores('notes');
await engine.clearLocalStores(['notes', 'tasks']);
// 清空云端存储
await engine.clearCloudStores('notes');
await engine.clearCloudStores(['notes', 'tasks']);
```
### 自动同步控制
```typescript
// 启用自动同步
engine.enableAutoSync(60000); // 60秒间隔
// 禁用自动同步
engine.dispose(); // 同时清除定时器并重置状态
```
## 适配器开发
开发自定义适配器需实现 `DatabaseAdapter` 接口:
```typescript
export interface DatabaseAdapter {
readStore<T extends { id: string }>(
storeName: string,
limit?: number,
offset?: number
): Promise<{ items: T[]; hasMore: boolean }>;
listStoreItems(
storeName: string,
offset?: number,
since?: number,
before?: number
): Promise<{
items: SyncViewItem[];
hasMore?: boolean;
offset?: number;
}>;
readBulk<T extends { id: string }>(
storeName: string,
ids: string[]
): Promise<T[]>;
putBulk<T extends { id: string }>(
storeName: string,
items: T[]
): Promise<T[]>;
deleteBulk(storeName: string, ids: string[]): Promise<void>;
clearStore(storeName: string): Promise<boolean>;
}
```
**重要提示:**
- `listStoreItems` 应按 `_ver` 降序返回项目,以便高效的基于检查点的增量同步
- `listStoreItems` 中的 `since` 参数用于增量同步(仅返回 `_ver > since` 的项目)
- `before` 参数可用于过滤旧的墓碑数据
- 项目必须包含 `id` 和 `_ver` 字段
## 技术架构
### 核心组件
1. **SyncEngine**: 主同步控制器
- 管理同步生命周期
- 协调本地和云端操作
- 处理自动同步调度
- 提供数据操作方法(save, delete)
2. **SyncView**: 用于快速比对的数据视图
- 存储轻量级元数据(id、版本、存储、删除标志)
- 支持高效的差异计算
- 通过检查点支持增量同步
3. **DatabaseAdapter**: 数据库接口
- 提供统一的数据访问
- 抽象数据库操作
- 确保跨平台兼容性
4. **检查点机制**:
- 跟踪每个存储的最新版本
- 支持高效的增量同步
- 减少大数据集的数据传输
### 同步状态
```typescript
export enum SyncStatus {
REJECTED = -3, // 推送被可用性检查拒绝
ERROR = -2, // 错误状态
OFFLINE = -1, // 离线状态
IDLE = 0, // 空闲状态
UPLOADING = 1, // 上传进行中
DOWNLOADING = 2, // 下载进行中
OPERATING = 3, // 操作进行中(清空存储等)
CHECKING = 4, // 检查云端变更中
}
```
### 版本控制
- 每个数据项都有一个 `_ver`(版本)字段
- 版本号基于时间戳(自纪元以来的毫秒数)
- 支持冲突检测和解决(最新版本胜出)
- 版本在保存操作时自动分配
### 数据结构
所有数据项必须包含:
- `id: string` - 唯一标识符
- `_ver: number` - 版本号(时间戳)
示例:
```typescript
interface Note {
id: string;
_ver: number; // 由 SyncEngine 自动设置
title: string;
content: string;
// ... 其他字段
}
```
## 性能考虑
- **批量处理**: 所有操作都使用批量处理以提高效率
- **增量同步**: 检查点机制显著减少数据传输
- **防抖机制**: 本地更改在推送前会进行防抖处理,减少网络调用
- **内存高效**: SyncView 使用轻量级元数据而非完整数据
- **懒加载**: 数据在同步操作期间按需加载
## 最佳实践
1. **存储命名**: 如果需要删除追踪,请始终在 `storesToSync` 数组中包含 `'tombStones'`
2. **初始化**: 使用引擎前始终调用 `engine.initialize()`
3. **错误处理**: 在适配器中实现适当的错误处理
4. **版本管理**: 永远不要手动修改 `_ver` 字段 - 让 SyncEngine 处理它
5. **清理**: 完成后调用 `engine.dispose()` 以清理定时器和资源
## 许可证
ISC