@aiao/rxdb-plugin-sync 0.0.26 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SyncManager.d.ts +16 -2
- package/dist/SyncManager.d.ts.map +1 -1
- package/dist/branch-materialization-source.d.ts +22 -0
- package/dist/branch-materialization-source.d.ts.map +1 -0
- package/dist/branch-utils.d.ts +32 -0
- package/dist/branch-utils.d.ts.map +1 -1
- package/dist/bulk-sync.d.ts.map +1 -1
- package/dist/cleanup-expired.d.ts.map +1 -1
- package/dist/get-repository-sync-status.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1972 -1472
- package/dist/plugin.d.ts +5 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/pull-batch.d.ts.map +1 -1
- package/dist/pull-conflict-utils.d.ts.map +1 -1
- package/dist/pull-repository.d.ts +20 -1
- package/dist/pull-repository.d.ts.map +1 -1
- package/dist/pull-round.d.ts +41 -0
- package/dist/pull-round.d.ts.map +1 -0
- package/dist/push-branch.d.ts +1 -1
- package/dist/push-branch.d.ts.map +1 -1
- package/dist/push-repository.d.ts +18 -2
- package/dist/push-repository.d.ts.map +1 -1
- package/dist/push.d.ts.map +1 -1
- package/dist/query-cache-outbox.d.ts.map +1 -1
- package/dist/sync-branches.d.ts +51 -5
- package/dist/sync-branches.d.ts.map +1 -1
- package/dist/sync-listeners.d.ts.map +1 -1
- package/dist/sync-repository.d.ts +3 -2
- package/dist/sync-repository.d.ts.map +1 -1
- package/package.json +7 -5
- package/src/SyncManager.ts +28 -0
- package/src/branch-materialization-source.ts +445 -0
- package/src/branch-utils.ts +42 -5
- package/src/bulk-sync.ts +22 -11
- package/src/check-repository-updates.ts +1 -1
- package/src/cleanup-expired.ts +17 -3
- package/src/get-repository-sync-status.ts +7 -7
- package/src/index.ts +7 -2
- package/src/plugin.ts +9 -1
- package/src/pull-batch.ts +16 -40
- package/src/pull-conflict-utils.ts +4 -0
- package/src/pull-repository.ts +43 -44
- package/src/pull-round.ts +103 -0
- package/src/pull.ts +1 -1
- package/src/push-branch.ts +4 -3
- package/src/push-repository.ts +674 -135
- package/src/push.ts +3 -1
- package/src/query-cache-outbox.ts +82 -9
- package/src/sync-branches.ts +130 -10
- package/src/sync-listeners.ts +30 -10
- package/src/sync-repository.ts +11 -6
- package/dist/version.utils.d.ts +0 -3
- package/dist/version.utils.d.ts.map +0 -1
- package/src/version.utils.ts +0 -20
package/dist/plugin.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export type RxDBPluginSyncOptions = object;
|
|
|
17
17
|
* 而 {@link SyncManager.init} 挂的 `connected$` 自动回推订阅必须在第一次连接就位之前
|
|
18
18
|
* 就已经订阅上,声明适配器依赖会把安装推到引导链之后,第一次连接的那一跳回推就丢了。
|
|
19
19
|
*
|
|
20
|
-
*
|
|
20
|
+
* 六处宿主改动都登记在 `scope` 上,断开连接时由宿主逆序释放:
|
|
21
21
|
*
|
|
22
22
|
* 1. `rxdb.syncManager` 这个实例槽位 —— 释放时连同 `destroy()` 一起撤掉,不给下一个纪元
|
|
23
23
|
* 留一个指向已拆事件总线的管理器;
|
|
@@ -31,6 +31,10 @@ export type RxDBPluginSyncOptions = object;
|
|
|
31
31
|
* 4. 宿主的 `online` / `offline` 监听 —— `ReachabilityMonitor` 只在有人 `watch()` 时才往
|
|
32
32
|
* `globalThis` 上挂,而这两个事件唯一的消费者是本包的同步监听器(`wakeup$` 驱动回推
|
|
33
33
|
* 重试)。不同步的库不该因为 `new RxDB()` 就永久多一对活过实例的监听器(US-025 D2)。
|
|
34
|
+
* 5. {@link RxDB.branchMaterializationSource} 这个分支物化来源槽 —— `syncBranches()` 拉下来的
|
|
35
|
+
* 分支只有元数据,工作树插件第一次切过去之前要按来源交出的分页快照物化。远端是本插件的,
|
|
36
|
+
* 来源于是也只能由本插件交;槽空着时那次切换稳定抛 `branch_not_materialized`,
|
|
37
|
+
* 不存在「没装同步也能物化」的形态。槽位至多一个来源,本插件登记即占住。
|
|
34
38
|
*/
|
|
35
39
|
export declare class RxDBPluginSync extends RxDBPluginBase implements IRxDBPlugin {
|
|
36
40
|
readonly lifecycle: "scoped";
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAQ,cAAc,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAQ,cAAc,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,mBAAmB;AACnB,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,cAAe,SAAQ,cAAe,YAAW,WAAW;IACvE,QAAQ,CAAC,SAAS,EAAG,QAAQ,CAAU;IACvC,QAAQ,CAAC,MAAM,8BAA+B;IAC9C,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,CAAU;IAEpC,OAAO,CAAC,KAAK,EAAE,cAAc;CA8C9B;AAED,OAAO,QAAQ,YAAY,CAAC;IAC1B,UAAU,IAAI;QACZ;;;;;;;WAOG;QACH,WAAW,EAAE,WAAW,CAAC;KAC1B;CACF;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,qBAAqB,CAAwC,CAAC"}
|
package/dist/pull-batch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull-batch.d.ts","sourceRoot":"","sources":["../src/pull-batch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,KAAK,gBAAgB,
|
|
1
|
+
{"version":3,"file":"pull-batch.d.ts","sourceRoot":"","sources":["../src/pull-batch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,KAAK,gBAAgB,EASrB,KAAK,UAAU,EAQhB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AA+BpD;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAC7B,EAAE,EAAE,WAAW,EACf,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CAAE,GACpF,OAAO,CAAC,UAAU,CAAC,CA8CrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull-conflict-utils.d.ts","sourceRoot":"","sources":["../src/pull-conflict-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EAGrB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,UAAU,EAEV,KAAK,YAAY,EAEjB,KAAK,SAAS,EACd,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACzB,MAAM,YAAY,CAAC;AACpB,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,YAAY,CAAC;IACvB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,wBAAgB,kBAAkB,IAAI,oBAAoB,CAMzD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAElE;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAYzF;AAED,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,YAAY,EAAE,EAC5B,OAAO,EAAE,oBAAoB,GAC5B,mBAAmB,EAAE,CAwCvB;AAED,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,WAAW,CAAC,OAAO,UAAU,CAAC,EAC1C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,MAAM,GAAG,IAAI,EACjC,SAAS,EAAE,YAAY,EAAE,GACxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"pull-conflict-utils.d.ts","sourceRoot":"","sources":["../src/pull-conflict-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EAGrB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,UAAU,EAEV,KAAK,YAAY,EAEjB,KAAK,SAAS,EACd,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACzB,MAAM,YAAY,CAAC;AACpB,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,YAAY,CAAC;IACvB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,wBAAgB,kBAAkB,IAAI,oBAAoB,CAMzD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAElE;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAYzF;AAED,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,YAAY,EAAE,EAC5B,OAAO,EAAE,oBAAoB,GAC5B,mBAAmB,EAAE,CAwCvB;AAED,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,WAAW,CAAC,OAAO,UAAU,CAAC,EAC1C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,MAAM,GAAG,IAAI,EACjC,SAAS,EAAE,YAAY,EAAE,GACxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAwCpC;AAED,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,WAAW,CAAC,OAAO,UAAU,CAAC,EAC1C,YAAY,EAAE,UAAU,EAAE,EAC1B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,WAAW,CAAC,OAAO,UAAU,CAAC,CAAC;IAC3C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,aAAa,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,oBAAoB,CAAC;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,wBAAwB,EAAE,uBAAuB,EAAE,CAAC;CACrD;AAcD,wBAAsB,+BAA+B,CACnD,aAAa,EAAE,mBAAmB,EAAE,EACpC,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,EAC9C,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,sBAAsB,CAAC,CA8EjC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PullRepositoryOptions, PullRepositoryResult } from '@aiao/rxdb';
|
|
1
|
+
import { PullRepositoryOptions, PullRepositoryResult, RepositorySyncType, RuleGroup, SyncOptions } from '@aiao/rxdb';
|
|
2
2
|
import { SyncManager } from './SyncManager.js';
|
|
3
3
|
export type { PullRepositoryOptions, PullRepositoryResult };
|
|
4
4
|
/**
|
|
@@ -33,4 +33,23 @@ export declare function partialRepositoryProgressOf(error: Error): PullRepositor
|
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
35
|
export declare function pullRepository(sm: SyncManager, namespace: string, entity: string, options?: PullRepositoryOptions): Promise<PullRepositoryResult>;
|
|
36
|
+
/**
|
|
37
|
+
* 解析级联节点自己的 filter
|
|
38
|
+
*
|
|
39
|
+
* @param repoKey - 仓库键(`namespace:entity`),用于错误消息
|
|
40
|
+
* @param repoSync - 该仓库的**生效**同步配置(`getSyncConfig(metadata, rxdb.entitySync)`);
|
|
41
|
+
* 不能传装饰器原值 `metadata.sync`:实例覆盖可能换掉了 filter,也可能把 Full 覆盖成 Filter
|
|
42
|
+
* @param repoSyncType - 该仓库的有效同步类型
|
|
43
|
+
* @param inheritedFilter - 调用方显式传入的 filter
|
|
44
|
+
* @returns 该仓库实际生效的 filter
|
|
45
|
+
* @throws {RxDBError} filter 函数抛错或返回非法 RuleGroup 时
|
|
46
|
+
*
|
|
47
|
+
* @remarks
|
|
48
|
+
* fail-closed:filter 表达的是租户/用户数据边界,抛错或返回非法值一律终止本次同步。
|
|
49
|
+
* 此前这里只 console.warn 再把 filter 置为 undefined —— 后续请求会拉取**全部**远端行,
|
|
50
|
+
* 把一个配置错误变成过量数据落地。与单仓路径保持同一口径。
|
|
51
|
+
*
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveCascadeFilter(repoKey: string, repoSync: SyncOptions | undefined, repoSyncType: RepositorySyncType, inheritedFilter: RuleGroup | undefined): RuleGroup | undefined;
|
|
36
55
|
//# sourceMappingURL=pull-repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull-repository.d.ts","sourceRoot":"","sources":["../src/pull-repository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"pull-repository.d.ts","sourceRoot":"","sources":["../src/pull-repository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EASL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAOzB,KAAK,kBAAkB,EAEvB,KAAK,SAAS,EAQd,KAAK,WAAW,EAEjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AA2BpD,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;AAsB5D;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,KAAK,GAAG,oBAAoB,GAAG,SAAS,CAQ1F;AAcD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,WAAW,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CA0B/B;AAkQD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,WAAW,GAAG,SAAS,EACjC,YAAY,EAAE,kBAAkB,EAChC,eAAe,EAAE,SAAS,GAAG,SAAS,GACrC,SAAS,GAAG,SAAS,CAyBvB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { IRepository, RemoteChange, RxDBChange } from '@aiao/rxdb';
|
|
2
|
+
/** {@link splitRemoteChangesByOrigin} 的结果 */
|
|
3
|
+
export interface RemoteChangeOrigins {
|
|
4
|
+
/** 本客户端自己 push 上去、这轮又拉回来的变更 */
|
|
5
|
+
ownChanges: RemoteChange[];
|
|
6
|
+
/** 其他客户端产生的变更,只有这一批进 apply / conflict 链路 */
|
|
7
|
+
otherChanges: RemoteChange[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 按 `clientId` 把一批远端变更拆成「自己推的」与「他人的」
|
|
11
|
+
*
|
|
12
|
+
* @param changes - 本轮拉到的远端变更
|
|
13
|
+
* @param clientId - 本客户端 id
|
|
14
|
+
* @returns 两个互斥的子集,顺序与入参一致
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* **只认 `clientId`,不拿 `localId` 当替补**:push 走 actions-only 路径时远端记录不带 `localId`,
|
|
18
|
+
* 若用「有 localId 就是自己的」去判,这类记录会被判成他人的而重复应用一遍;反过来,若把
|
|
19
|
+
* 「没有 clientId」也算成自己的,那这批数据拉下来了却永远不进 apply 链路——静默丢数据。
|
|
20
|
+
* 所以缺 `clientId` 一律算他人的:多走一遍幂等的 apply,好过整批不落库。
|
|
21
|
+
*/
|
|
22
|
+
export declare const splitRemoteChangesByOrigin: (changes: RemoteChange[], clientId: string | undefined) => RemoteChangeOrigins;
|
|
23
|
+
/**
|
|
24
|
+
* 把自推变更拿到的远端 id 回填到对应的本地 `RxDBChange` 行上
|
|
25
|
+
*
|
|
26
|
+
* @param changeRepo - 变更表仓库;在事务里调用时必须是经 executor 取到的那一个
|
|
27
|
+
* @param ownChanges - {@link splitRemoteChangesByOrigin} 分出的自推变更
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* 只回填 `remoteId` 还空着的行,判据写在 SQL 里(`= null` 由适配器编译成 `IS NULL`)而不是
|
|
31
|
+
* 取回来再用 JS 挑:少取一批行是次要的,主要是让「只写没映射过的」成为查询本身的一部分,
|
|
32
|
+
* 而不是一条可以被下一次改动顺手删掉的 `if`。
|
|
33
|
+
*
|
|
34
|
+
* 覆盖已有映射不是小事:`cleanupExpired` 按 `remoteId` 判「这条已经同步出去了」,
|
|
35
|
+
* 把旧映射改写成本轮的 id 会让保留窗口整段错位——旧变更被当成刚同步的留下来,
|
|
36
|
+
* 而真正该留的那批反而先到期。
|
|
37
|
+
*
|
|
38
|
+
* 没有 `localId` 的自推变更直接跳过:对不上本地行,硬回填只能靠猜。
|
|
39
|
+
*/
|
|
40
|
+
export declare const backfillOwnChangeRemoteIds: (changeRepo: IRepository<typeof RxDBChange>, ownChanges: RemoteChange[]) => Promise<void>;
|
|
41
|
+
//# sourceMappingURL=pull-round.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull-round.d.ts","sourceRoot":"","sources":["../src/pull-round.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAElF,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,+BAA+B;IAC/B,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,4CAA4C;IAC5C,YAAY,EAAE,YAAY,EAAE,CAAC;CAC9B;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,0BAA0B,GACrC,SAAS,YAAY,EAAE,EACvB,UAAU,MAAM,GAAG,SAAS,KAC3B,mBAaF,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,0BAA0B,GACrC,YAAY,WAAW,CAAC,OAAO,UAAU,CAAC,EAC1C,YAAY,YAAY,EAAE,KACzB,OAAO,CAAC,IAAI,CAuBd,CAAC"}
|
package/dist/push-branch.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push-branch.d.ts","sourceRoot":"","sources":["../src/push-branch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"push-branch.d.ts","sourceRoot":"","sources":["../src/push-branch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;OAKG;IACH,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAqC3E"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PushRepositoryResult } from '@aiao/rxdb';
|
|
1
|
+
import { PushRepositoryResult, SyncRejection } from '@aiao/rxdb';
|
|
2
2
|
import { SyncManager } from './SyncManager.js';
|
|
3
3
|
/**
|
|
4
4
|
* 推送仓库选项
|
|
@@ -44,8 +44,15 @@ export declare function partialPushProgressOf(error: Error): PushRepositoryResul
|
|
|
44
44
|
* @param namespace - 实体命名空间
|
|
45
45
|
* @param entity - 实体名称
|
|
46
46
|
* @param options - 推送选项
|
|
47
|
+
* @param rejectionSink - 被拒清单收集器。传入时本次调用只往里追加、不上报,由调用方在整次操作结束时
|
|
48
|
+
* 统一上报(`push()` / `bulkSync` 一轮多仓);不传时本次调用结束即自行上报。
|
|
47
49
|
* @returns 推送结果
|
|
48
50
|
*
|
|
51
|
+
* @remarks
|
|
52
|
+
* `reportRejections` 是整体替换语义:一轮操作里多次 `pushRepository` 各自上报会互相覆盖,
|
|
53
|
+
* 只剩最后一个仓库的清单,所以上报边界必须由整次操作的发起者持有。
|
|
54
|
+
* 无论成功、部分失败还是抛错,已落库的被拒都会交出去(追加进收集器或自行上报)。
|
|
55
|
+
*
|
|
49
56
|
* @example
|
|
50
57
|
* ```ts
|
|
51
58
|
* // 在不进行级联的情况下推送 Todo 仓库
|
|
@@ -59,5 +66,14 @@ export declare function partialPushProgressOf(error: Error): PushRepositoryResul
|
|
|
59
66
|
* });
|
|
60
67
|
* ```
|
|
61
68
|
*/
|
|
62
|
-
export declare function pushRepository(sm: SyncManager, namespace: string, entity: string, options?: PushRepositoryOptions): Promise<PushRepositoryResult>;
|
|
69
|
+
export declare function pushRepository(sm: SyncManager, namespace: string, entity: string, options?: PushRepositoryOptions, rejectionSink?: SyncRejection[]): Promise<PushRepositoryResult>;
|
|
70
|
+
/**
|
|
71
|
+
* 整次推送结束后把收集到的被拒清单上报一次;没有被拒就不报(不清掉上一轮的清单)。
|
|
72
|
+
*
|
|
73
|
+
* @param sm - SyncManager 实例
|
|
74
|
+
* @param rejections - 整次操作已落库的被拒清单
|
|
75
|
+
*
|
|
76
|
+
* @internal
|
|
77
|
+
*/
|
|
78
|
+
export declare function reportPushRejections(sm: SyncManager, rejections: readonly SyncRejection[]): void;
|
|
63
79
|
//# sourceMappingURL=push-repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push-repository.d.ts","sourceRoot":"","sources":["../src/push-repository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"push-repository.d.ts","sourceRoot":"","sources":["../src/push-repository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAWL,KAAK,oBAAoB,EAkBzB,KAAK,aAAa,EAGnB,MAAM,YAAY,CAAC;AAMpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;;;;;;OAaG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAKD,YAAY,EAAE,oBAAoB,EAAE,CAAC;AAgBrC;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,KAAK,GAAG,oBAAoB,GAAG,SAAS,CAQpF;AAiCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,WAAW,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,EAC/B,aAAa,CAAC,EAAE,aAAa,EAAE,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CA+C/B;AA6sCD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAEhG"}
|
package/dist/push.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,UAAU,EAMX,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;GASG;AACH,wBAAsB,IAAI,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,UAAU,EAMX,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;GASG;AACH,wBAAsB,IAAI,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAkFtF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-cache-outbox.d.ts","sourceRoot":"","sources":["../src/query-cache-outbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAGL,KAAK,gBAAgB,EAUrB,cAAc,
|
|
1
|
+
{"version":3,"file":"query-cache-outbox.d.ts","sourceRoot":"","sources":["../src/query-cache-outbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAGL,KAAK,gBAAgB,EAUrB,cAAc,EAKd,KAAK,IAAI,EAQV,MAAM,YAAY,CAAC;AAgBpB;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,yCAAyC;IACzC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,oBAAoB;IACpB,KAAK,EAAE,KAAK,CAAC;CACd;AAED;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,cAAc;IACd,UAAU,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,gBAAgB;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,0BAA0B;IAC1B,QAAQ,EAAE,uBAAuB,EAAE,CAAC;IACpC,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAwFD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CAAE,GAChD,OAAO,CAAC,sBAAsB,CAAC,CAoBjC;AAuID;;;;;;;;;;;;;GAaG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAiCvE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAe9B;AA0cD,uCAAuC;AACvC,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
package/dist/sync-branches.d.ts
CHANGED
|
@@ -1,18 +1,64 @@
|
|
|
1
1
|
import { SyncManager } from './SyncManager.js';
|
|
2
|
+
/**
|
|
3
|
+
* {@link SyncManager.syncBranches} 一轮的结果。
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* `created + updated + skipped.length` 不一定等于 `total`:本地已有、且早已标了 `remote` 的
|
|
7
|
+
* 分支既不计 `updated`,也不进 `skipped`。
|
|
8
|
+
*/
|
|
2
9
|
export interface SyncBranchesResult {
|
|
10
|
+
/** 本轮在本地新建的远端分支数。 */
|
|
3
11
|
created: number;
|
|
12
|
+
/** 本地已有、本轮补上 `remote: true` 标记的分支数。 */
|
|
4
13
|
updated: number;
|
|
14
|
+
/** 远端本轮交回的分支总数,含被跳过的。 */
|
|
5
15
|
total: number;
|
|
6
16
|
/**
|
|
7
|
-
*
|
|
17
|
+
* 本轮**未创建**的远端分支 id —— 具体原因见同一个 id 在 {@link skipReasons} 里的条目。
|
|
18
|
+
*
|
|
19
|
+
* 一条分支被跳过,可能是它自己的问题(id 不可用、或分叉点变更还没拉到本地翻译不出本地
|
|
20
|
+
* id),也可能单纯因为它的父本轮被跳过——后一种情形下这条分支自身完全合格,但父本轮
|
|
21
|
+
* 不会落库,若仍然照常创建,它的 `parentId` 就是一条指向「本轮不存在的父」的悬空外键
|
|
22
|
+
* (`rxdb_branch.parentId` 是 `PRAGMA defer_foreign_keys` 延迟到 COMMIT 才检查的外键,
|
|
23
|
+
* 届时会回滚整个事务,连同本轮所有本该成功的分支)。三种成因统一走同一条 `skipped`
|
|
24
|
+
* 通道,因为对调用方而言处理方式是一样的:这个 id 本轮没有对应的本地分支,仅此而已。
|
|
8
25
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
26
|
+
* **跳过不留持久标记**:每轮都全量重拉远端分支、从头再判一遍,`skipped` 与
|
|
27
|
+
* {@link skipReasons} 只报这一轮。`unresolved-from-change-id` 在分叉点变更拉到本地后自愈,
|
|
28
|
+
* 挂在它下面的 `ancestor-skipped` 随之自愈;`invalid-id` 则远端不改就每轮重拉、重跳,
|
|
29
|
+
* 一直占位——调用方要区分这两类,看 {@link skipReasons}。要不要记一个持久的「已知坏行」
|
|
30
|
+
* 标记,登记在 `requirements/roadmap.md`「epic-006 评审顺延的架构项」。
|
|
13
31
|
*/
|
|
14
32
|
skipped: string[];
|
|
33
|
+
/**
|
|
34
|
+
* `skipped` 里每一个 id 对应的具体跳过原因;key 覆盖 `skipped` 的每一项,一一对应。
|
|
35
|
+
*
|
|
36
|
+
* 单开一个字段而不是把原因塞进 `skipped` 数组本身:`skipped: string[]` 这个形状已经被
|
|
37
|
+
* 外部当「id 列表」消费,改成对象数组是破坏性变更;`Record<id, reason>` 是纯增量,
|
|
38
|
+
* 只读 `skipped` 的既有调用方不受影响。
|
|
39
|
+
*/
|
|
40
|
+
skipReasons: Record<string, SyncBranchSkipReason>;
|
|
15
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* 一条远端分支本轮被跳过的具体原因。
|
|
44
|
+
*
|
|
45
|
+
* @remarks
|
|
46
|
+
* 三种成因互斥——处理顺序保证每条被跳过的分支只会落进其中一种:
|
|
47
|
+
* - `invalid-id`:分支自己的 id 落不进本地 `rxdb_branch.id`(见 {@link isUsableBranchId})。
|
|
48
|
+
* - `unresolved-from-change-id`:分叉点变更还没拉到本地,`fromChangeId` 翻译不出本地 id。
|
|
49
|
+
* - `ancestor-skipped`:分支自身没有问题,但它的**直接父**本轮已经被跳过(不管父是因为
|
|
50
|
+
* 哪一种成因被跳的)。`ancestorId` 记的是那个直接父的 id,不是链路最顶端的根因——
|
|
51
|
+
* 要追根因,沿 `skipReasons[ancestorId]` 递归上溯,直到查到的原因不再是
|
|
52
|
+
* `ancestor-skipped` 为止。
|
|
53
|
+
*/
|
|
54
|
+
export type SyncBranchSkipReason = {
|
|
55
|
+
readonly cause: 'invalid-id';
|
|
56
|
+
} | {
|
|
57
|
+
readonly cause: 'unresolved-from-change-id';
|
|
58
|
+
} | {
|
|
59
|
+
readonly cause: 'ancestor-skipped';
|
|
60
|
+
readonly ancestorId: string;
|
|
61
|
+
};
|
|
16
62
|
/**
|
|
17
63
|
* 从远程拉取所有分支信息并同步到本地
|
|
18
64
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-branches.d.ts","sourceRoot":"","sources":["../src/sync-branches.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sync-branches.d.ts","sourceRoot":"","sources":["../src/sync-branches.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;;;;;;;;;;OAeG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CACnD;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GAChC;IAAE,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAA;CAAE,GAC/C;IAAE,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAgFxE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4G/E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-listeners.d.ts","sourceRoot":"","sources":["../src/sync-listeners.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAyC,YAAY,EAAE,MAAM,MAAM,CAAC;AAG3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-listeners.d.ts","sourceRoot":"","sources":["../src/sync-listeners.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAyC,YAAY,EAAE,MAAM,MAAM,CAAC;AAG3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAqNpD;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,WAAW,GAAG;IACnD,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;CAC7B,CA4DA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SyncProgress } from '@aiao/rxdb';
|
|
1
|
+
import { SyncProgress, SyncRejection } from '@aiao/rxdb';
|
|
2
2
|
import { SyncManager } from './SyncManager.js';
|
|
3
3
|
import { PullRepositoryOptions, PullRepositoryResult } from './pull-repository.js';
|
|
4
4
|
import { PushRepositoryOptions, PushRepositoryResult } from './push-repository.js';
|
|
@@ -45,6 +45,7 @@ export interface SyncRepositoryResult extends SyncProgress {
|
|
|
45
45
|
* @param namespace - 实体命名空间
|
|
46
46
|
* @param entity - 实体名称
|
|
47
47
|
* @param options - 同步选项
|
|
48
|
+
* @param rejectionSink - 推送被拒清单收集器,语义同 {@link pushRepository} 的同名参数
|
|
48
49
|
* @returns 同步结果
|
|
49
50
|
*
|
|
50
51
|
* @example
|
|
@@ -59,5 +60,5 @@ export interface SyncRepositoryResult extends SyncProgress {
|
|
|
59
60
|
* });
|
|
60
61
|
* ```
|
|
61
62
|
*/
|
|
62
|
-
export declare function syncRepository(sm: SyncManager, namespace: string, entity: string, options?: SyncRepositoryOptions): Promise<SyncRepositoryResult>;
|
|
63
|
+
export declare function syncRepository(sm: SyncManager, namespace: string, entity: string, options?: SyncRepositoryOptions, rejectionSink?: SyncRejection[]): Promise<SyncRepositoryResult>;
|
|
63
64
|
//# sourceMappingURL=sync-repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-repository.d.ts","sourceRoot":"","sources":["../src/sync-repository.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"sync-repository.d.ts","sourceRoot":"","sources":["../src/sync-repository.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAC9B;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAErC;;OAEG;IACH,IAAI,CAAC,EAAE,qBAAqB,CAAC;IAE7B;;OAEG;IACH,IAAI,CAAC,EAAE,qBAAqB,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD;;OAEG;IACH,UAAU,EAAE,oBAAoB,CAAC;IAEjC;;OAEG;IACH,UAAU,EAAE,oBAAoB,CAAC;CAClC;AAmGD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,WAAW,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,EAC/B,aAAa,CAAC,EAAE,aAAa,EAAE,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CA+B/B"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiao/rxdb-plugin-sync",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.28",
|
|
4
4
|
"description": "Push/pull synchronization, conflict resolution and offline outbox for Aiao RxDB.",
|
|
5
|
-
"homepage": "https://rxdb.
|
|
5
|
+
"homepage": "https://rxdb.aiao.io/docs/plugins",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/aiao-io/rxdb/issues"
|
|
8
8
|
},
|
|
@@ -54,8 +54,10 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"rxjs": "^7.8.2",
|
|
57
|
-
"@aiao/
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
"@aiao/utils": "^0.0.28"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"@aiao/rxdb": "^0.0.28",
|
|
61
|
+
"@aiao/rxdb-plugin-history": "^0.0.28"
|
|
60
62
|
}
|
|
61
63
|
}
|
package/src/SyncManager.ts
CHANGED
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
PushResult,
|
|
10
10
|
RxDB,
|
|
11
11
|
RxDBPartialSyncError,
|
|
12
|
+
SWITCH_BRANCH_BEGIN,
|
|
13
|
+
SWITCH_BRANCH_COMMIT,
|
|
12
14
|
SyncResult
|
|
13
15
|
} from '@aiao/rxdb';
|
|
14
16
|
import type { PushInFlightRegistry, SyncHistoryBridge } from '@aiao/rxdb-plugin-history';
|
|
@@ -50,6 +52,7 @@ import { topologicalSort, type SortDirection } from './topological-sort.js';
|
|
|
50
52
|
export class SyncManager {
|
|
51
53
|
#event_removers: Array<() => void> = [];
|
|
52
54
|
#subscriptions: Subscription[] = [];
|
|
55
|
+
#branch_switch_generation = 0;
|
|
53
56
|
|
|
54
57
|
/**
|
|
55
58
|
* 「哪些变更此刻正在飞往远端」的登记处。
|
|
@@ -65,6 +68,23 @@ export class SyncManager {
|
|
|
65
68
|
return this.history.pushInFlight;
|
|
66
69
|
}
|
|
67
70
|
|
|
71
|
+
/**
|
|
72
|
+
* 本地分支激活代际:每次分支切换开始与提交各加一。
|
|
73
|
+
*
|
|
74
|
+
* @remarks
|
|
75
|
+
* 推送在规划时记下它,回执提交事务里再比一次。只比分支 id 不够:远端往返期间
|
|
76
|
+
* main→feature→main 之后 id 又对上了,但 main 的业务投影已经被切走又切回重建过。
|
|
77
|
+
* 开始与提交都加一,是为了让「规划时恰好撞上一次进行中的切换」也被识别出来。
|
|
78
|
+
*
|
|
79
|
+
* 只覆盖本实例内的切换;跨标签页的切换由提交事务里读到的持久化 active 分支兜住
|
|
80
|
+
* (A→B→A 在跨标签页时不可见,属已知限制)。
|
|
81
|
+
*
|
|
82
|
+
* @internal
|
|
83
|
+
*/
|
|
84
|
+
get branchSwitchGeneration(): number {
|
|
85
|
+
return this.#branch_switch_generation;
|
|
86
|
+
}
|
|
87
|
+
|
|
68
88
|
/**
|
|
69
89
|
* @param rxdb - 宿主实例
|
|
70
90
|
* @param history - 历史侧借来的那一小块面,由 `rxdb.versionManager.syncBridge` 提供
|
|
@@ -79,6 +99,14 @@ export class SyncManager {
|
|
|
79
99
|
const { subscriptions, removers } = setupSyncListeners(this);
|
|
80
100
|
this.#subscriptions.push(...subscriptions);
|
|
81
101
|
this.#event_removers.push(...removers);
|
|
102
|
+
|
|
103
|
+
const bumpBranchSwitchGeneration = (): void => {
|
|
104
|
+
this.#branch_switch_generation += 1;
|
|
105
|
+
};
|
|
106
|
+
for (const type of [SWITCH_BRANCH_BEGIN, SWITCH_BRANCH_COMMIT] as const) {
|
|
107
|
+
this.rxdb.addEventListener(type, bumpBranchSwitchGeneration);
|
|
108
|
+
this.#event_removers.push(() => this.rxdb.removeEventListener(type, bumpBranchSwitchGeneration));
|
|
109
|
+
}
|
|
82
110
|
}
|
|
83
111
|
|
|
84
112
|
/** 拆掉 {@link init} 装上的全部监听与订阅 */
|