跳到主要内容

RxDBPluginSync

Defined in: rxdb-plugin-sync/src/plugin.ts:50

推拉同步 / 冲突 / 仓库依赖序插件。

Remarks​

声明 inject: ['plugin:history'],且只声明这一条:

  • 要历史插件,是因为一次往返结束时 undo 边界要作废、待拉计数要结算,而那些状态的主人 在历史侧。SyncManager 拿的是 rxdb.versionManager.syncBridge 这张窄接口, 没有它连构造都无从谈起。依赖缺失时宿主不装本插件、只告警一次,rxdb.syncManager 这个槽位于是不存在——没有历史就没有同步,这正是实情。
  • 不要 adapter:remote:同步入口本身是按调用发起的,装配阶段一条适配器读写都不发; 而 SyncManager.init 挂的 connected$ 自动回推订阅必须在第一次连接就位之前 就已经订阅上,声明适配器依赖会把安装推到引导链之后,第一次连接的那一跳回推就丢了。

六处宿主改动都登记在 scope 上,断开连接时由宿主逆序释放:

  1. rxdb.syncManager 这个实例槽位 —— 释放时连同 destroy() 一起撤掉,不给下一个纪元 留一个指向已拆事件总线的管理器;
  2. RxDB.syncState 上的「重算待拉数」跳板 —— 远端适配器在实时订阅恢复后按 syncState.requestPullableRefresh() 发信号,它不认识 SyncManager,接住这一跳 是本插件的活(US-025 阶段 D 之前这条绑定在历史插件上,随 refreshPullableCount 一起 搬过来)。没装插件时那个请求发进空里,正是「待拉数无人维护」的实情。
  3. RxDB.queryCacheOutbox 这个出站队列槽 —— QueryCache 实体的读引擎要靠它把 「远端没返回」和「本地离线写过」区分开。这一条没有缺席形态:槽空着时核心在 connect() 就抛 RxDBMissingPluginError,因为「当空集」等于把每条离线写都当孤儿删掉。
  4. 宿主的 online / offline 监听 —— ReachabilityMonitor 只在有人 watch() 时才往 globalThis 上挂,而这两个事件唯一的消费者是本包的同步监听器(wakeup$ 驱动回推 重试)。不同步的库不该因为 new RxDB() 就永久多一对活过实例的监听器(US-025 D2)。
  5. RxDB.branchMaterializationSource 这个分支物化来源槽 —— syncBranches() 拉下来的 分支只有元数据,工作树插件第一次切过去之前要按来源交出的分页快照物化。远端是本插件的, 来源于是也只能由本插件交;槽空着时那次切换稳定抛 branch_not_materialized, 不存在「没装同步也能物化」的形态。槽位至多一个来源,本插件登记即占住。

Extends​

Implements​

Constructors​

Constructor​

new RxDBPluginSync(rxdb): RxDBPluginSync;

Defined in: rxdb/dist/rxdb-plugin.d.ts:137

Parameters​

ParameterType
rxdbRxDB

Returns​

RxDBPluginSync

Inherited from​

RxDBPluginBase.constructor

Properties​

inject​

readonly inject: readonly ["plugin:history"];

Defined in: rxdb-plugin-sync/src/plugin.ts:52

声明本插件需要哪些依赖就绪之后才能安装。

Remarks​

不声明(或声明空数组)= 无依赖,init() 时立即安装,行为与本字段引入之前完全一致。

声明之后由宿主负责时序,插件不要在 install() 里再自己等一遍:宿主的 connect() 本身就在等插件安装,插件反过来等 connect() 会自等死锁。这正是本字段 存在的理由——在它之前,搜索插件只能靠「adapterConnected$ 在插件安装之前置位」 这条脆弱的时序约定绕开死锁。

依赖不满足时:该插件不安装、不产生作用域、不进入宿主的安装等待集合,因此 connect() 照常 resolve 而不是挂起;宿主另有一次 console.warn 列出缺失项,不静默。

依赖按实例引用记账而不是按名字或布尔位。同名适配器换了新实例(中途从未变为空) 同样算一次纪元变化:旧作用域被释放,插件以新实例重装并拿到全新的子作用域。 反过来,同一纪元内安装失败不会自动重试——重试只发生在纪元真的变了的时候。

阶段 A 只解析 adapter:*。此时声明 plugin:* 语法合法,但解析结果恒为「未就绪」, 插件会停在等待态并触发上述 warn,不会静默消失。

Example​

readonly inject = ['adapter:local'] as const;

async install(scope: LifecycleScope) {
// 到这里 adapter:local 一定已就绪,直接取用即可
const adapter = this.rxdb.localAdapterSync;
}

Implementation of​

IRxDBPlugin.inject


lifecycle​

readonly lifecycle: "scoped";

Defined in: rxdb-plugin-sync/src/plugin.ts:51

声明本插件已迁移到作用域拆卸。

Remarks​

取值为 'scoped' 时宿主释放完插件作用域就收手,不再调用 IRxDBPlugin.destroy。 双版本插件(既要能装进旧宿主又要能装进新宿主)两样都写:旧宿主不认识本字段、只会走 destroy();新宿主认识,于是只走作用域,两边都不会清理两次。

之所以要显式标记而不是去看 install.length 有没有形参:转译产物、Function.prototype.bind 与压缩器都会改写形参个数,把它当契约会误判。

Implementation of​

IRxDBPlugin.lifecycle


name​

name: Uncapitalize<string> = 'sync';

Defined in: rxdb-plugin-sync/src/plugin.ts:53

插件名,用于日志与宿主侧的错误归因

Implementation of​

IRxDBPlugin.name


rxdb​

protected readonly rxdb: RxDB;

Defined in: rxdb/dist/rxdb-plugin.d.ts:136

Inherited from​

RxDBPluginBase.rxdb

Methods​

install()​

install(scope): void;

Defined in: rxdb-plugin-sync/src/plugin.ts:55

安装插件。

Parameters​

ParameterTypeDescription
scopeLifecycleScope本次连接纪元的插件激活作用域;一次 acquire() 只包一步可能抛错的获取

Returns​

void

Remarks​

抛错(含 Promise reject)视为安装失败:宿主会先把已经登记进 scope 的部分 逆序释放掉,再把原错误传播给 connect()。回滚期间的清理错误只记日志,不会盖掉安装错误。

实现方不写形参不破坏契约——install() 与 install(scope) 同样满足本接口。

Implementation of​

IRxDBPlugin.install