分支管理
RxDB 提供类似 Git 的分支管理能力,让你可以在本地创建多个数据分支,安全地进行实验性修改,然后选择性地合并或切换分支。
快速开始
分支与历史由 @aiao/rxdb-plugin-history 提供,不在 core 里:
pnpm add @aiao/rxdb-plugin-history
import { RxDB, SyncType } from '@aiao/rxdb';
import { rxDBPluginHistory } from '@aiao/rxdb-plugin-history';
const rxdb = new RxDB({
dbName: 'myApp',
entities: [Todo],
sync: { local: { adapter: 'wa-sqlite' }, type: SyncType.None }
});
rxdb.use(rxDBPluginHistory);
await rxdb.connect('wa-sqlite');
// 创建分支
await rxdb.versionManager.createBranch('feature-1');
// 切换分支
await rxdb.versionManager.switchBranch('feature-1');
// 删除分支
await rxdb.versionManager.removeBranch('feature-1');
:::warning versionManager 的可用时机
rxdb.versionManager 由历史插件在连接纪元内挂载,await connect() 之后才存在。没装插件时读它拿到的是 undefined——core 不做 fallback 兜底。
同步方法(syncRepository / bulkSync / push / pull 等)已经从 versionManager 搬到 @aiao/rxdb-plugin-sync 的 rxdb.syncManager,见历史与同步拆包。
:::
分支管理 API
创建分支
// 从当前状态创建分支
await rxdb.versionManager.createBranch('feature-1');
// 从指定 changeId 创建分支
await rxdb.versionManager.createBranch('feature-2', 12345);
切换分支
await rxdb.versionManager.switchBranch('feature-1');
await rxdb.versionManager.switchBranch('main');
删除分支
await rxdb.versionManager.removeBranch('feature-1');
注意
删除分支会同时删除该分支的所有变更历史。
获取当前分支
import { RxDBBranch } from '@aiao/rxdb';
const currentBranch = await RxDBBranch.findOne({
where: {
combinator: 'and',
rules: [{ field: 'activated', operator: '=', value: true }]
}
});
使用场景
测试新功能
await rxdb.versionManager.createBranch('test-feature');
await rxdb.versionManager.switchBranch('test-feature');
const todo = new Todo();
todo.title = '测试任务';
await todo.save();
// 测试完成,切换回主分支
await rxdb.versionManager.switchBranch('main');
await rxdb.versionManager.removeBranch('test-feature');
离线编辑
await rxdb.versionManager.createBranch('offline-work');
await rxdb.versionManager.switchBranch('offline-work');
// 离线修改...
// 恢复网络后切换回主分支
await rxdb.versionManager.switchBranch('main');
系统表结构
系统表 RxDBChange 会通过数据库触发器(Trigger) 记录所有数据库的数据变化(插入,修改,删除),RxDBBranch 表会记录当前分支,这样我们就可以通过历史记录来计算出任何时刻的数据,再去修改其他表的数据达到切换版本的需求。
关键字段
RxDBBranch
id: 分支标识符fromChangeId: 分支起始点activated: 是否为当前分支
RxDBChange
id: 变更序号(自增)remoteId: 远程变更IDbranchId: 所属分支type:insert|update|deletepatch: 正向变更(JSON Patch)inversePatch: 逆向变更(用于回滚)revertChangeId: 撤销时的变更IDredoInvalidatedAt: redo 失效时间
分支合并
把源分支的变更合并进当前激活分支(目标分支由当前激活分支决定,不作为参数传入):
// 压缩合并(默认):源分支全部变更压成目标分支上的一组事务记录
const result = await rxdb.versionManager.mergeBranch('feature-1');
console.log(`合并了 ${result.merged} 条变更,策略 ${result.strategy}`);
// 普通合并:逐条复制,保留历史细节
await rxdb.versionManager.mergeBranch('feature-1', { strategy: 'normal' });
// 合并后删除源分支
const merged = await rxdb.versionManager.mergeBranch('feature-1', { deleteSource: true });
if (!merged.sourceDeleted) console.warn('合并已落库,但删源分支没做成', merged.sourceDeleteError);
合并有变更时会清空 undo/redo 历史——合并本身不可逆。deleteSource 的删除是合并落库之后的收尾动作,失败不回滚合并、也不抛错,只在 sourceDeleted / sourceDeleteError 上如实报告。