VersionManager
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:54
版本管理器
负责管理数据库的分支、撤销/重做与版本历史:
- 分支管理(创建、删除、切换、合并)
- 撤销/重做操作(数据库级别)
- Redo 栈的自动失效(当有新操作时)
Remarks
推拉同步不在这里。US-025 阶段 D 之后它住在 @aiao/rxdb-plugin-sync 的
SyncManager 上,两边只经 VersionManager.syncBridge 这一张窄接口相遇。
Properties
pushInFlight
readonly pushInFlight: PushInFlightRegistry;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:79
Internal
「哪些变更此刻正在飞往远端」的登记处。
Remarks
push 与 undo 唯一的会合点。push 在远端往返之前认领区间,undo 把认领区间当成已推 —— 没有它,往返窗口内的一次撤销会造成本地与远端永久分叉,见 PushInFlightRegistry。
挂在 VersionManager 上是因为两边都只经它相遇:pushRepository(vm, …) 直接拿到它,
HistoryManager 经 rxdb.versionManager 拿到它。生命周期跟随实例,不跨实例共享。
rxdb
readonly rxdb: RxDB;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:124
宿主实例
syncBridge
readonly syncBridge: SyncHistoryBridge;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:90
Internal
交给同步插件的那一小块历史能力。
Remarks
传闭包而不是 this.historyManager:init() 会在断连重连后重建管理器,
桥必须每次现取,见 createSyncHistoryBridge。
Accessors
pullableCount$
Get Signature
get pullableCount$(): Observable<number>;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:112
远程待 pull 的变更数量流
通过监听远程事件(INSERT/UPDATE/DELETE)累计:
- 收到远程变更事件时计数+1
- pull 完成后计数重置为 0
用于 UI 显示"有 N 条远程更新可拉取"
Returns
Observable<number>
pushableCount$
Get Signature
get pushableCount$(): Observable<number>;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:99
可 push 的变更数量流
实时追踪本地未推送的有效变更数量:
- 排除已撤销的变更(revertChangeId != null)
- 排除从远程 pull 来的变更(remoteId != null)
Returns
Observable<number>
Methods
createBranch()
createBranch(branchId, fromChangeId?): Promise<RxDBBranch>;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:250
创建新分支
Parameters
| Parameter | Type | Description |
|---|---|---|
branchId | string | 分支 id |
fromChangeId? | number | 从哪个 changeId 创建新分支 |
Returns
Promise<RxDBBranch>
destroy()
destroy(): void;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:219
摘掉全部事件监听与订阅,并销毁 HistoryManager。
Returns
void
Remarks
幂等。事务深度与代次一并清零:拆卸可能发生在事务中途,留着计数会让下一个纪元 以为自己开局就在一笔未结的事务里。
getCurrentBranch()
getCurrentBranch(): Promise<RxDBBranch>;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:495
取当前分支;没有激活分支时激活(或新建)main。
Returns
Promise<RxDBBranch>
Remarks
分两段是有意的:
- 热路径(已有激活分支)不开事务。同步插件的远端事件链路里每条事件都要调它
(
sync-listeners的filterByBranch),把整段包进事务能修好并发, 但会让每次读都去抢并发度 1 的写队列槽位。 - 冷路径(查不到激活分支)才开事务,并在事务内重做一遍检查(双重检查)。
否则两个并发调用会双双走到
create,第二个撞主键报错。
getLocalRepositories()
getLocalRepositories(): Promise<{
adapter: LocalRxDBAdapter;
branchRepository: LocalRxDBBranchRepository;
changeRepository: LocalRxDBChangeRepository;
}>;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:466
取本地适配器上的系统表仓库。
Returns
Promise<{
adapter: LocalRxDBAdapter;
branchRepository: LocalRxDBBranchRepository;
changeRepository: LocalRxDBChangeRepository;
}>
branchRepository / changeRepository 与它们所属的本地适配器
Remarks
每次都经 localAdapter$ 重新解析,不缓存:适配器随连接纪元换,缓下来的那一份
会在重连之后指向已拆的旧实例。
getRemoteRepositories()
getRemoteRepositories(): Promise<{
adapter: RemoteRxDBAdapter;
branchRepository: RemoteRxDBBranchRepository;
changeRepository: RemoteRxDBChangeRepository;
}>;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:479
取远端适配器上的系统表仓库。
Returns
Promise<{
adapter: RemoteRxDBAdapter;
branchRepository: RemoteRxDBBranchRepository;
changeRepository: RemoteRxDBChangeRepository;
}>
branchRepository / changeRepository 与它们所属的远端适配器
Remarks
未配置远端时 remoteAdapter$ 不发值,调用会一直挂着 —— 这是有意的:同步路径
本来就只在配了远端时才走,返回一个空壳只会把「没配远端」推迟到更深的地方才报。
history()
history<T>(options?): HistoryScopeAPI;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:436
获取特定作用域的历史记录 API
Type Parameters
| Type Parameter |
|---|
T extends EntityType |
Parameters
| Parameter | Type | Description |
|---|---|---|
options? | T | InstanceType<T> | 作用域选项: - 不传参数 → database 作用域(整个数据库) - EntityType 类 → repository 作用域(该实体的所有记录) - 实体实例 → entity 作用域(该实例的历史) |
Returns
统一的历史记录 API 接口
Example
// 数据库级别
const dbHistory = versionManager.history();
// 仓库级别(所有 User 记录)
const userHistory = versionManager.history(User);
// 实体级别(单个用户)
const entityHistory = versionManager.history(userInstance);
init()
init(): void;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:140
挂上事务与本地写入的事件监听,开始记历史。
Returns
void
Remarks
与 VersionManager.destroy 成对,可重入:上一轮 destroy() 过的
HistoryManager 已经拆掉了订阅,这里重建一个而不是复用 —— 复用等于把新纪元的
变更喂给一条已 complete 的流。
不发任何适配器读写,也不会把实例连起来(分支流等 connected$ 为真才查),因此可以
(也必须)早于引导链跑:HistoryManager 的分支流要赶在第一条 rxdb_change 事件之前
订阅上,装晚了那一批变更就不进历史。
mergeBranch()
mergeBranch(sourceBranchId, options?): Promise<MergeBranchResult>;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:391
合并分支
将源分支的变更合并到当前激活分支(目标分支)。
Parameters
| Parameter | Type | Description |
|---|---|---|
sourceBranchId | string | 源分支 ID |
options? | MergeBranchOptions | 合并选项 |
Returns
Promise<MergeBranchResult>
合并结果
Remarks
支持两种策略:
squash(默认):将源分支所有变更压缩为最小操作集后一次性应用,目标分支只产生一组变更记录normal:逐条应用源分支变更,每条变更在目标分支产生独立的变更记录(保留历史细节)
合并后会清空 undo/redo 历史,因为合并操作不可逆。
可选通过 deleteSource: true 在合并后删除源分支。
Example
// 压缩合并(默认)
const result = await rxdb.versionManager.mergeBranch('feature-x');
console.log(`Merged ${result.merged} changes`);
// 普通合并
const result = await rxdb.versionManager.mergeBranch('feature-x', {
strategy: 'normal'
});
// 合并后删除源分支
const result = await rxdb.versionManager.mergeBranch('feature-x', {
deleteSource: true
});
removeBranch()
removeBranch(branchId): Promise<void>;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:258
删除分支
Parameters
| Parameter | Type | Description |
|---|---|---|
branchId | string | 分支 id |
Returns
Promise<void>
resetSessionState()
resetSessionState(): void;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:239
作废本连接积累的历史上下文:清空全部分支的 undo 会话与待拉计数。
Returns
void
Remarks
供切库 / 重连这类「本地数据整体换了一份」的场景调用。清的是全部分支而不只是 当前分支 —— 换掉的是整个数据源,其它分支上那些 undo 条目指向的行同样已经不在了。
restoreEntity()
restoreEntity<T>(entity, options): Promise<InstanceType<T>>;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:450
恢复被删除的实体
根据 RxDBChange 记录中的 inversePatch 重新插入实体, 恢复操作本身会生成新的 RxDBChange 记录(可被 push 到远程)。
Type Parameters
| Type Parameter |
|---|
T extends EntityType |
Parameters
| Parameter | Type | Description |
|---|---|---|
entity | InstanceType<T> | 被删除的实体实例(需要包含 metadata 信息) |
options | RestoreEntityOptions | 恢复选项,包含 changeId(DELETE 类型的 RxDBChange 记录 ID) |
Returns
Promise<InstanceType<T>>
恢复后的实体实例
switchBranch()
switchBranch(branchId, preconditions?): Promise<void>;
Defined in: packages/rxdb-plugin-history/src/VersionManager.ts:280
切换到指定分支
Parameters
| Parameter | Type | Description |
|---|---|---|
branchId | string | 目标分支 ID |
preconditions? | RxDBBranchSwitchPreconditions | 【可选】切换前要成立的条件;不传时行为与以往逐字节一致 |
Returns
Promise<void>
Remarks
切换分支后会自动清空 redo 栈,因为 redo 历史在新分支中不再有效。 如果目标分支与当前分支相同,则直接返回,避免不必要的操作。
第二形参是纯扩展:既有调用点一个都不用改,不传即不表态。做成默认开启的话,
switchBranch(id) 会在任何有未提交改动的库上开始抛错——而历史子系统自己就在调它
(undo/redo 回放、redo 失效),那些路径上工作树恒非空,默认开启等于让 undo 在有改动时不可用。
条件由能力插件校验,本方法一个字段都不读:判据是
@aiao/rxdb-plugin-working-tree 贡献的那几张表,这里既不认识也不该认识它们。
反方向(本包 import 那个插件)是条依赖环,nx 的图插件会把 run-many 当场拒掉。