@aiao/rxdb-plugin-sync 0.0.0-stage → 0.0.26

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.
Files changed (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +81 -2
  3. package/dist/SyncManager.d.ts +412 -0
  4. package/dist/SyncManager.d.ts.map +1 -0
  5. package/dist/branch-change-id.d.ts +31 -0
  6. package/dist/branch-change-id.d.ts.map +1 -0
  7. package/dist/branch-utils.d.ts +8 -0
  8. package/dist/branch-utils.d.ts.map +1 -0
  9. package/dist/bulk-sync.d.ts +117 -0
  10. package/dist/bulk-sync.d.ts.map +1 -0
  11. package/dist/cascade-blocking.d.ts +38 -0
  12. package/dist/cascade-blocking.d.ts.map +1 -0
  13. package/dist/check-repository-updates.d.ts +47 -0
  14. package/dist/check-repository-updates.d.ts.map +1 -0
  15. package/dist/cleanup-expired.d.ts +56 -0
  16. package/dist/cleanup-expired.d.ts.map +1 -0
  17. package/dist/dependency-graph.d.ts +128 -0
  18. package/dist/dependency-graph.d.ts.map +1 -0
  19. package/dist/get-all-repository-sync-status.d.ts +58 -0
  20. package/dist/get-all-repository-sync-status.d.ts.map +1 -0
  21. package/dist/get-repository-sync-status.d.ts +68 -0
  22. package/dist/get-repository-sync-status.d.ts.map +1 -0
  23. package/dist/index.d.ts +39 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +3273 -0
  26. package/dist/plugin.d.ts +70 -0
  27. package/dist/plugin.d.ts.map +1 -0
  28. package/dist/pull-ancestor-changes.d.ts +41 -0
  29. package/dist/pull-ancestor-changes.d.ts.map +1 -0
  30. package/dist/pull-batch.d.ts +16 -0
  31. package/dist/pull-batch.d.ts.map +1 -0
  32. package/dist/pull-conflict-utils.d.ts +43 -0
  33. package/dist/pull-conflict-utils.d.ts.map +1 -0
  34. package/dist/pull-repository.d.ts +36 -0
  35. package/dist/pull-repository.d.ts.map +1 -0
  36. package/dist/pull.d.ts +16 -0
  37. package/dist/pull.d.ts.map +1 -0
  38. package/dist/push-branch.d.ts +22 -0
  39. package/dist/push-branch.d.ts.map +1 -0
  40. package/dist/push-repository.d.ts +63 -0
  41. package/dist/push-repository.d.ts.map +1 -0
  42. package/dist/push.d.ts +14 -0
  43. package/dist/push.d.ts.map +1 -0
  44. package/dist/query-cache-outbox.d.ts +120 -0
  45. package/dist/query-cache-outbox.d.ts.map +1 -0
  46. package/dist/sync-branches.d.ts +35 -0
  47. package/dist/sync-branches.d.ts.map +1 -0
  48. package/dist/sync-listeners.d.ts +20 -0
  49. package/dist/sync-listeners.d.ts.map +1 -0
  50. package/dist/sync-manager.utils.d.ts +36 -0
  51. package/dist/sync-manager.utils.d.ts.map +1 -0
  52. package/dist/sync-repository.d.ts +63 -0
  53. package/dist/sync-repository.d.ts.map +1 -0
  54. package/dist/topological-sort.d.ts +126 -0
  55. package/dist/topological-sort.d.ts.map +1 -0
  56. package/dist/version.utils.d.ts +3 -0
  57. package/dist/version.utils.d.ts.map +1 -0
  58. package/package.json +58 -3
  59. package/src/SyncManager.ts +662 -0
  60. package/src/branch-change-id.ts +70 -0
  61. package/src/branch-utils.ts +37 -0
  62. package/src/bulk-sync.ts +338 -0
  63. package/src/cascade-blocking.ts +61 -0
  64. package/src/check-repository-updates.ts +143 -0
  65. package/src/cleanup-expired.ts +271 -0
  66. package/src/dependency-graph.ts +324 -0
  67. package/src/get-all-repository-sync-status.ts +115 -0
  68. package/src/get-repository-sync-status.ts +237 -0
  69. package/src/index.ts +53 -0
  70. package/src/plugin.ts +124 -0
  71. package/src/pull-ancestor-changes.ts +61 -0
  72. package/src/pull-batch.ts +410 -0
  73. package/src/pull-conflict-utils.ts +280 -0
  74. package/src/pull-repository.ts +701 -0
  75. package/src/pull.ts +204 -0
  76. package/src/push-branch.ts +61 -0
  77. package/src/push-repository.ts +1002 -0
  78. package/src/push.ts +104 -0
  79. package/src/query-cache-outbox.ts +866 -0
  80. package/src/sync-branches.ts +156 -0
  81. package/src/sync-listeners.ts +289 -0
  82. package/src/sync-manager.utils.ts +48 -0
  83. package/src/sync-repository.ts +302 -0
  84. package/src/topological-sort.ts +246 -0
  85. package/src/version.utils.ts +20 -0
@@ -0,0 +1,70 @@
1
+ import { IRxDBPlugin, Plugin, RxDBPluginBase } from '@aiao/rxdb';
2
+ import { LifecycleScope } from '@aiao/utils';
3
+ import { SyncManager } from './SyncManager.js';
4
+ /** 本插件当前不接受任何选项 */
5
+ export type RxDBPluginSyncOptions = object;
6
+ /**
7
+ * 推拉同步 / 冲突 / 仓库依赖序插件。
8
+ *
9
+ * @remarks
10
+ * **声明 `inject: ['plugin:history']`**,且只声明这一条:
11
+ *
12
+ * - 要历史插件,是因为一次往返结束时 undo 边界要作废、待拉计数要结算,而那些状态的主人
13
+ * 在历史侧。{@link SyncManager} 拿的是 `rxdb.versionManager.syncBridge` 这张窄接口,
14
+ * 没有它连构造都无从谈起。依赖缺失时宿主不装本插件、只告警一次,`rxdb.syncManager`
15
+ * 这个槽位于是不存在——没有历史就没有同步,这正是实情。
16
+ * - **不要 `adapter:remote`**:同步入口本身是按调用发起的,装配阶段一条适配器读写都不发;
17
+ * 而 {@link SyncManager.init} 挂的 `connected$` 自动回推订阅必须在第一次连接就位之前
18
+ * 就已经订阅上,声明适配器依赖会把安装推到引导链之后,第一次连接的那一跳回推就丢了。
19
+ *
20
+ * 五处宿主改动都登记在 `scope` 上,断开连接时由宿主逆序释放:
21
+ *
22
+ * 1. `rxdb.syncManager` 这个实例槽位 —— 释放时连同 `destroy()` 一起撤掉,不给下一个纪元
23
+ * 留一个指向已拆事件总线的管理器;
24
+ * 2. {@link RxDB.syncState} 上的「重算待拉数」跳板 —— 远端适配器在实时订阅恢复后按
25
+ * `syncState.requestPullableRefresh()` 发信号,它不认识 {@link SyncManager},接住这一跳
26
+ * 是本插件的活(US-025 阶段 D 之前这条绑定在历史插件上,随 `refreshPullableCount` 一起
27
+ * 搬过来)。没装插件时那个请求发进空里,正是「待拉数无人维护」的实情。
28
+ * 3. {@link RxDB.queryCacheOutbox} 这个出站队列槽 —— QueryCache 实体的读引擎要靠它把
29
+ * 「远端没返回」和「本地离线写过」区分开。这一条**没有**缺席形态:槽空着时核心在
30
+ * `connect()` 就抛 `RxDBMissingPluginError`,因为「当空集」等于把每条离线写都当孤儿删掉。
31
+ * 4. 宿主的 `online` / `offline` 监听 —— `ReachabilityMonitor` 只在有人 `watch()` 时才往
32
+ * `globalThis` 上挂,而这两个事件唯一的消费者是本包的同步监听器(`wakeup$` 驱动回推
33
+ * 重试)。不同步的库不该因为 `new RxDB()` 就永久多一对活过实例的监听器(US-025 D2)。
34
+ */
35
+ export declare class RxDBPluginSync extends RxDBPluginBase implements IRxDBPlugin {
36
+ readonly lifecycle: "scoped";
37
+ readonly inject: readonly ["plugin:history"];
38
+ name: Uncapitalize<string>;
39
+ install(scope: LifecycleScope): void;
40
+ }
41
+ declare module '@aiao/rxdb' {
42
+ interface RxDB {
43
+ /**
44
+ * 推拉同步子系统。
45
+ *
46
+ * @remarks
47
+ * 由 `@aiao/rxdb-plugin-sync` 在连接纪元内装配。**没装插件(或没装它依赖的
48
+ * `@aiao/rxdb-plugin-history`)时这个槽位不存在**:读它拿到 `undefined`,
49
+ * 而不是一个什么都不做的空壳——核心不做 fallback 兜底。
50
+ */
51
+ syncManager: SyncManager;
52
+ }
53
+ }
54
+ /**
55
+ * 同步插件工厂。
56
+ *
57
+ * @param db - 宿主实例
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * import { rxDBPluginHistory } from '@aiao/rxdb-plugin-history';
62
+ * import { rxDBPluginSync } from '@aiao/rxdb-plugin-sync';
63
+ *
64
+ * // 顺序随意:宿主按 `inject` 拓扑排序,历史插件一定先装完。
65
+ * rxdb.use(rxDBPluginSync);
66
+ * rxdb.use(rxDBPluginHistory);
67
+ * ```
68
+ */
69
+ export declare const rxDBPluginSync: Plugin<RxDBPluginSyncOptions>;
70
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +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;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,mBAAmB;AACnB,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;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;CA2C9B;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"}
@@ -0,0 +1,41 @@
1
+ import { RemoteChange, RuleGroup, RxDBAdapterRemoteBase } from '@aiao/rxdb';
2
+ /**
3
+ * 一个仓库跨祖先分支拉取变更所需的全部参数。
4
+ */
5
+ export interface AncestorPullRequest {
6
+ /** 仓库命名空间 */
7
+ namespace: string;
8
+ /** 实体名 */
9
+ entity: string;
10
+ /** 水位线:只拉 id 大于它的变更 */
11
+ sinceId: number;
12
+ /** 本轮最多消费多少条 */
13
+ limit: number;
14
+ /** 行级过滤条件,`SyncType.Filter` 用;批量路径不支持,故为可选 */
15
+ filter?: RuleGroup;
16
+ }
17
+ /**
18
+ * 跨祖先分支拉取**单个仓库**的远端变更,合并成一条按 id 递增、长度不超过 `limit` 的序列。
19
+ *
20
+ * @param remoteAdapter - 远端适配器
21
+ * @param request - 仓库标识、水位线、批量大小与可选行级过滤
22
+ * @param branchIds - 当前分支及其全部祖先,见 `getAncestorBranchIds`
23
+ * @returns 合并、排序、截断后的变更序列
24
+ *
25
+ * @remarks
26
+ * **为什么必须逐祖先分支拉。** 分支是 patch 模型,不是快照模型:建分支时只写
27
+ * `parentId` + `fromChangeId`,一条变更都不复制。所以 feature 分支上可见的数据 =
28
+ * 父分支在分叉点之前的变更 + feature 自己的变更,而父分支那些记录**物理上仍然
29
+ * 归属 `branchId='main'`**。`pullChanges` 的 `branchId` 是精确匹配(见其接口契约),
30
+ * 只传当前分支就永远收不到别人推到 main 的更新 —— 且不会自愈:切回 main 时水位线
31
+ * 换成了 `${ns}:${entity}:main` 这条**另一个**记录,那段区间从此跳过。
32
+ *
33
+ * **为什么合并后必须全局排序再截断。** 每个分支各自取满 `limit` 条,直接拼接会让
34
+ * 某个分支的高 id 把共享水位线推过另一个分支尚未消费的低 id;那些变更此后都不再满足
35
+ * `id > lastPullRemoteChangeId`,被永久跳过。排序后只消费前 `limit` 条,其余留给下一轮 ——
36
+ * 调用方据 `length >= limit` 置 `hasMore` 继续循环。
37
+ *
38
+ * 单分支(在 main 上)时只发一次请求,与逐祖先的写法结果一致,不额外分支判断。
39
+ */
40
+ export declare function pullAncestorBranchChanges(remoteAdapter: RxDBAdapterRemoteBase, request: AncestorPullRequest, branchIds: readonly string[]): Promise<RemoteChange[]>;
41
+ //# sourceMappingURL=pull-ancestor-changes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull-ancestor-changes.d.ts","sourceRoot":"","sources":["../src/pull-ancestor-changes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAC3F;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,aAAa;IACb,SAAS,EAAE,MAAM,CAAC;IAElB,UAAU;IACV,MAAM,EAAE,MAAM,CAAC;IAEf,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAEhB,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC;IAEd,8CAA8C;IAC9C,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,yBAAyB,CAC7C,aAAa,EAAE,qBAAqB,EACpC,OAAO,EAAE,mBAAmB,EAC5B,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,YAAY,EAAE,CAAC,CAYzB"}
@@ -0,0 +1,16 @@
1
+ import { ConflictResolver, PullResult } from '@aiao/rxdb';
2
+ import { SyncManager } from './SyncManager.js';
3
+ /**
4
+ * 批量拉取所有实体的变更。
5
+ *
6
+ * @param sm - SyncManager 实例
7
+ * @param options.limit - 每个实体单轮的最大变更数,默认 1000
8
+ * @param options.fetchAll - 为真时循环拉取直到远端排空;默认只拉一轮并用 `hasMore` 告知还有剩余
9
+ * @returns 各轮累加后的拉取结果
10
+ */
11
+ export declare function pullBatch(sm: SyncManager, options?: {
12
+ limit?: number;
13
+ fetchAll?: boolean;
14
+ conflictResolver?: ConflictResolver;
15
+ }): Promise<PullResult>;
16
+ //# sourceMappingURL=pull-batch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull-batch.d.ts","sourceRoot":"","sources":["../src/pull-batch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,KAAK,gBAAgB,EAQrB,KAAK,UAAU,EAOhB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AA8BpD;;;;;;;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"}
@@ -0,0 +1,43 @@
1
+ import { ConflictResolver, IRepository, RemoteChange, RxDBChange, RxDBEntityId, RxDBEvent, SwitchVersionActions, SwitchVersionChange } from '@aiao/rxdb';
2
+ export type ActionType = 'INSERT' | 'UPDATE' | 'DELETE';
3
+ export interface ConflictActionEntry {
4
+ key: string;
5
+ entityId: RxDBEntityId;
6
+ type: ActionType;
7
+ change: SwitchVersionChange;
8
+ remote: RemoteChange;
9
+ }
10
+ export declare function createEmptyActions(): SwitchVersionActions;
11
+ export declare function countActions(actions: SwitchVersionActions): number;
12
+ export declare function setAction(actions: SwitchVersionActions, entry: ConflictActionEntry): void;
13
+ export declare function createConflictActionEntries(otherChanges: RemoteChange[], actions: SwitchVersionActions): ConflictActionEntry[];
14
+ export declare function queryPendingLocalChanges(changeRepo: IRepository<typeof RxDBChange>, namespace: string, entity: string, branchId: string, lastPushedChangeId: number | null, entityIds: RxDBEntityId[]): Promise<Map<string, RxDBChange[]>>;
15
+ export declare function markLocalChangesSuperseded(changeRepo: IRepository<typeof RxDBChange>, localChanges: RxDBChange[], remoteId: number): Promise<void>;
16
+ export interface ResolveConflictsContext {
17
+ changeRepo: IRepository<typeof RxDBChange>;
18
+ conflictResolver: ConflictResolver;
19
+ dispatchEvent: (event: RxDBEvent) => void;
20
+ repoLabel: string;
21
+ deferLocalChangeSupersession?: boolean;
22
+ /**
23
+ * 当前客户端 id,用于给冲突的本地侧打戳。
24
+ *
25
+ * @remarks
26
+ * `RxDBChange` 表没有 clientId 列,直接把本地行交给解决器时 `conflict.local.clientId`
27
+ * 恒为 `undefined`,LWW 的 tie-breaker 永不触发、永远退回 KEEP_LOCAL —— 两个副本各自
28
+ * 保留自己,永久分叉。本地未同步的 change 按定义就是本客户端产生的,
29
+ * 在这里打戳与加列等价,且不需要持久化格式变更。
30
+ */
31
+ localClientId?: string;
32
+ }
33
+ export interface LocalChangeSupersession {
34
+ localChanges: RxDBChange[];
35
+ remoteId: number;
36
+ }
37
+ export interface ResolveConflictsResult {
38
+ applyActions: SwitchVersionActions;
39
+ conflictsResolved: number;
40
+ localChangeSupersessions: LocalChangeSupersession[];
41
+ }
42
+ export declare function resolveConflictsAndBuildActions(actionEntries: ConflictActionEntry[], pendingLocalChanges: Map<string, RxDBChange[]>, context: ResolveConflictsContext): Promise<ResolveConflictsResult>;
43
+ //# sourceMappingURL=pull-conflict-utils.d.ts.map
@@ -0,0 +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,CAoCpC;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"}
@@ -0,0 +1,36 @@
1
+ import { PullRepositoryOptions, PullRepositoryResult } from '@aiao/rxdb';
2
+ import { SyncManager } from './SyncManager.js';
3
+ export type { PullRepositoryOptions, PullRepositoryResult };
4
+ /**
5
+ * 从中断错误里取出仓库级的部分进度。
6
+ *
7
+ * 结构化校验而非直接断言类型:`RxDBPartialSyncError` 的 `result` 是泛型,
8
+ * 拿一个 `as PullRepositoryResult` 硬转会在别处抛出别的形状时静默出错。
9
+ *
10
+ * @internal
11
+ */
12
+ export declare function partialRepositoryProgressOf(error: Error): PullRepositoryResult | undefined;
13
+ /**
14
+ * 为单个仓库拉取变更
15
+ *
16
+ * @param sm - SyncManager 实例
17
+ * @param namespace - 实体命名空间
18
+ * @param entity - 实体名称
19
+ * @param options - 拉取选项
20
+ * @returns 拉取结果
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * // 在不进行级联的情况下拉取 Todo 仓库
25
+ * const result = await pullRepository(sm, 'public', 'Todo', {
26
+ * includeRelated: false
27
+ * });
28
+ *
29
+ * // 拉取 Todo 及其所有依赖项(如 User)
30
+ * const result = await pullRepository(sm, 'public', 'Todo', {
31
+ * includeRelated: true
32
+ * });
33
+ * ```
34
+ */
35
+ export declare function pullRepository(sm: SyncManager, namespace: string, entity: string, options?: PullRepositoryOptions): Promise<PullRepositoryResult>;
36
+ //# sourceMappingURL=pull-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull-repository.d.ts","sourceRoot":"","sources":["../src/pull-repository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAQL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAiB1B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AA0BpD,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"}
package/dist/pull.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { PullOptions, PullResult } from '@aiao/rxdb';
2
+ import { SyncManager } from './SyncManager.js';
3
+ /**
4
+ * Pull 功能实现
5
+ *
6
+ * 从远程拉取变更并应用到本地实体表
7
+ *
8
+ * 默认使用 pullBatch 单次 HTTP 请求拉取所有实体的变更。
9
+ * 当指定 repositoryFilter 时,降级为 bulkSync 逐实体拉取。
10
+ *
11
+ * @param sm - SyncManager 实例
12
+ * @param options - Pull 选项
13
+ * @returns Pull 结果
14
+ */
15
+ export declare function pull(sm: SyncManager, options?: PullOptions): Promise<PullResult>;
16
+ //# sourceMappingURL=pull.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../src/pull.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,WAAW,EAEX,UAAU,EAMX,MAAM,YAAY,CAAC;AAIpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,wBAAsB,IAAI,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAyCtF"}
@@ -0,0 +1,22 @@
1
+ import { SyncManager } from './SyncManager.js';
2
+ export interface PushBranchResult {
3
+ synced: number;
4
+ skipped: string[];
5
+ /**
6
+ * 分叉点变更还没有 `remoteId`,本次只能带 `fromChangeId: null` 上行。
7
+ *
8
+ * 调用方应在实体变更推送完成、分叉点拿到 `remoteId` 之后重推一次分支,
9
+ * 把远端那一行补全。
10
+ */
11
+ forkPointPending: boolean;
12
+ }
13
+ /**
14
+ * 将当前激活分支推送到远程
15
+ *
16
+ * 规则:
17
+ * 1. 不推送 id='main' 的分支
18
+ * 2. 不修改远程分支的 activated 属性(由 SQL 函数保证)
19
+ * 3. `fromChangeId` 翻译成远端 id 后再上行(见 {@link toRemoteFromChangeId})
20
+ */
21
+ export declare function pushBranch(sm: SyncManager): Promise<PushBranchResult>;
22
+ //# sourceMappingURL=push-branch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push-branch.d.ts","sourceRoot":"","sources":["../src/push-branch.ts"],"names":[],"mappings":"AACA,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"}
@@ -0,0 +1,63 @@
1
+ import { PushRepositoryResult } from '@aiao/rxdb';
2
+ import { SyncManager } from './SyncManager.js';
3
+ /**
4
+ * 推送仓库选项
5
+ */
6
+ export interface PushRepositoryOptions {
7
+ /**
8
+ * 每批次推送的最大变更数量
9
+ * @default 1000
10
+ */
11
+ batchSize?: number;
12
+ /**
13
+ * 是否包含相关实体(级联同步)
14
+ *
15
+ * 当为 true 时:
16
+ * - 自动推送所有子实体(引用当前实体的实体)
17
+ * - 遵循反向拓扑顺序:子 -> 父
18
+ * - 示例:推送 User 时会自动推送 Post
19
+ *
20
+ * 当为 false 时:
21
+ * - 仅同步指定仓库
22
+ * - 可能会导致远端数据不完整
23
+ *
24
+ * @default true
25
+ */
26
+ includeRelated?: boolean;
27
+ }
28
+ export type { PushRepositoryResult };
29
+ /**
30
+ * 从异常里取出推送侧的部分进度。
31
+ *
32
+ * 与 `partialRepositoryProgressOf`(pull 侧)对称:按 `PushRepositoryResult` 独有的
33
+ * `pushed` + `originalCount` 两个数值字段判形,`PullRepositoryResult` /
34
+ * `SyncRepositoryResult` 都没有它们,不会误判。
35
+ *
36
+ * @param error - 任意异常
37
+ * @returns 携带的推送结果;异常不是 `RxDBPartialSyncError` 或负载形状不符时返回 `undefined`
38
+ */
39
+ export declare function partialPushProgressOf(error: Error): PushRepositoryResult | undefined;
40
+ /**
41
+ * 为单个仓库推送变更
42
+ *
43
+ * @param sm - SyncManager 实例
44
+ * @param namespace - 实体命名空间
45
+ * @param entity - 实体名称
46
+ * @param options - 推送选项
47
+ * @returns 推送结果
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * // 在不进行级联的情况下推送 Todo 仓库
52
+ * const result = await pushRepository(sm, 'public', 'Todo', {
53
+ * includeRelated: false
54
+ * });
55
+ *
56
+ * // 推送 Todo 以及所有依赖它的实体(如 Comment)
57
+ * const result = await pushRepository(sm, 'public', 'Todo', {
58
+ * includeRelated: true
59
+ * });
60
+ * ```
61
+ */
62
+ export declare function pushRepository(sm: SyncManager, namespace: string, entity: string, options?: PushRepositoryOptions): Promise<PushRepositoryResult>;
63
+ //# sourceMappingURL=push-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push-repository.d.ts","sourceRoot":"","sources":["../src/push-repository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAOL,KAAK,oBAAoB,EAiB1B,MAAM,YAAY,CAAC;AAKpB,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;;;;;;;;;;;;;;;;;;;;;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,CAoC/B"}
package/dist/push.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { PushOptions, PushResult } from '@aiao/rxdb';
2
+ import { SyncManager } from './SyncManager.js';
3
+ /**
4
+ * Push 功能实现
5
+ *
6
+ * 将本地未同步的变更推送到远程
7
+ * 先同步分支数据,再使用 bulkSync 批量推送所有 repositories
8
+ *
9
+ * @param sm - SyncManager 实例
10
+ * @param options - Push 选项
11
+ * @returns Push 结果
12
+ */
13
+ export declare function push(sm: SyncManager, options?: PushOptions): Promise<PushResult>;
14
+ //# sourceMappingURL=push.d.ts.map
@@ -0,0 +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,CAgFtF"}
@@ -0,0 +1,120 @@
1
+ import { ConflictResolver, isNetworkError, RxDB } from '@aiao/rxdb';
2
+ /**
3
+ * 一次重放失败。
4
+ *
5
+ * @remarks
6
+ * 出现在 {@link QueryCacheOutboxResult.failures} 里:一轮重放**不因单行失败而中止**,
7
+ * 失败的行留在队列里等下一轮,成功的行照常推进水位线。
8
+ */
9
+ export interface QueryCacheOutboxFailure {
10
+ /** 失败的实体 id;整批性失败(例如元数据探测失败)时为 `null` */
11
+ entityId: string | null;
12
+ /** 失败原因,原样透传,不包装 */
13
+ error: Error;
14
+ }
15
+ /**
16
+ * 一轮出站重放的结果,{@link flushQueryCacheOutbox} 的返回值。
17
+ *
18
+ * @remarks
19
+ * 四个净操作计数(`replayed` / `discarded` / `noop` 与 `failures.length`)互斥且穷尽:
20
+ * 压缩之后的每一个净操作恰好落进其中一类。`originalCount - compacted` 是净操作总数。
21
+ */
22
+ export interface QueryCacheOutboxResult {
23
+ /** 本轮处理的仓库 */
24
+ repository: {
25
+ namespace: string;
26
+ entity: string;
27
+ };
28
+ /** 读到的原始变更行数 */
29
+ originalCount: number;
30
+ /** 被本地压缩抵消掉的原始变更行数 */
31
+ compacted: number;
32
+ /** 真的发出去并成功的净操作数 */
33
+ replayed: number;
34
+ /** LWW 判负、本地改动被丢弃的净操作数 */
35
+ discarded: number;
36
+ /** 远端状态已经满足意图、一个请求都没发的净操作数 */
37
+ noop: number;
38
+ /** 水位线推进到的 change id;本轮没有推进时为 `null` */
39
+ watermark: number | null;
40
+ /**
41
+ * 冲突判定中远端胜出的实体 id —— 也就是离线期间的本地改动被丢掉的那批。
42
+ *
43
+ * @remarks
44
+ * 只收解决器明确判 `KEEP_REMOTE` 的。「远端这行已经不在了」不算冲突:那种情况没有
45
+ * 竞争写可比,本地意图是被收敛掉而不是被判负(见 `MISSING_REMOTE`)。
46
+ */
47
+ conflicts: string[];
48
+ /** 本轮的失败;非空即意味着水位线没有推进 */
49
+ failures: QueryCacheOutboxFailure[];
50
+ /** 整轮被跳过时的原因(例如同步开关被关掉) */
51
+ skipped?: string;
52
+ }
53
+ /**
54
+ * 把某个 QueryCache 仓库积压的离线改动重放回远端。
55
+ *
56
+ * @param rxdb - RxDB 实例,用来取分支、本地/远端适配器与实体配置
57
+ * @param namespace - 实体命名空间
58
+ * @param entity - 实体名
59
+ * @param options - 可选的冲突解决器;默认 {@link LWWConflictResolver}
60
+ * @returns 本轮的重放结果
61
+ * @throws {@link RxDBError} 该仓库不存在,或它的 `syncType` 不是 `'querycache'`
62
+ *
63
+ * @remarks
64
+ * 同一仓库上的并发调用会复用同一个在飞的 Promise(见 {@link inflight})。
65
+ *
66
+ * **失败即整轮中止、水位线不推进**:REST 没有批级原子性,也没有 per-change 的确认回执。
67
+ * 已经成功发出去的那几条因此会在下一轮被重发 —— 这与 `pushRepository` 在批次中途失败时
68
+ * 的暴露面相同。用一个哨兵值去写 `RxDBChange.remoteId` 能消除重发,但那个字段的语义是
69
+ * 「本地变更对应的远端 changelog 行」,REST 路径根本没有这个 id,写进去会让
70
+ * `pull-conflict-utils` 与待推计数读到一个不存在的引用。
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * const result = await flushQueryCacheOutbox(rxdb, 'public', 'Recipe');
75
+ * if (result.failures.length === 0) {
76
+ * console.log(`replayed ${result.replayed}, watermark → ${result.watermark}`);
77
+ * }
78
+ * ```
79
+ */
80
+ export declare function flushQueryCacheOutbox(rxdb: RxDB, namespace: string, entity: string, options?: {
81
+ conflictResolver?: ConflictResolver;
82
+ }): Promise<QueryCacheOutboxResult>;
83
+ /**
84
+ * 数一遍所有 QueryCache 仓库在当前分支上还没推回远端的变更行。
85
+ *
86
+ * @param rxdb - RxDB 实例
87
+ * @returns 待重放的变更行数;没有这类仓库时为 0
88
+ *
89
+ * @remarks
90
+ * 口径与 {@link flushQueryCacheOutbox} 的取行条件一致(同分支、未推送、未回滚、
91
+ * 水位线之后),只是一次把所有 `offlineWrite && !push` 的仓库并成一个 OR 组来数,
92
+ * 不必逐仓库往返。
93
+ *
94
+ * 与 `HistoryManager.pushableCount$` **不重叠**:那一侧按 `capability.push` 取仓库,
95
+ * 这一侧取它的补集,因此 {@link SyncStateHub} 把两个数直接相加是安全的。
96
+ */
97
+ export declare function countQueryCacheOutbox(rxdb: RxDB): Promise<number>;
98
+ /**
99
+ * 取出某个 QueryCache 仓库当前**被出站队列占着**的实体 id。
100
+ *
101
+ * @param rxdb - RxDB 实例
102
+ * @param namespace - 命名空间
103
+ * @param entity - 实体名
104
+ * @returns 队列里还没推回远端的那些实体 id;队列为空时是空集
105
+ *
106
+ * @remarks
107
+ * 取行条件与 {@link flushQueryCacheOutbox} 逐字同源(同分支、`remoteId = null`、
108
+ * `revertChangeId = null`、水位线之后),因为「谁归队列管」和「谁会被重放」必须是
109
+ * 同一个集合 —— 两边各写一份过滤条件,漂移的那一刻就是数据被误删的那一刻。
110
+ *
111
+ * **不**看 `RxDBSync.enabled`:仓库关掉同步时队列永远不会 flush,那些行于是永远留在本地。
112
+ * 它们仍然是只有本地有的用户数据,按「远端没返回 = 孤儿」删掉就再也找不回来了。
113
+ *
114
+ * 没有 `RxDBSync` 记录时按「没有水位线」读全量,不新建记录:这是一次纯读,
115
+ * 给一个还没同步过的仓库建记录会凭空多出一条水位线为 0 的同步状态。
116
+ */
117
+ export declare function pendingQueryCacheWriteIds(rxdb: RxDB, namespace: string, entity: string): Promise<ReadonlySet<string>>;
118
+ /** 重导出,方便调用方按同一口径判断 flush 失败是不是网络原因 */
119
+ export { isNetworkError };
120
+ //# sourceMappingURL=query-cache-outbox.d.ts.map
@@ -0,0 +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,EAId,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;AAkID;;;;;;;;;;;;;GAaG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BvE;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;AA0YD,uCAAuC;AACvC,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { SyncManager } from './SyncManager.js';
2
+ export interface SyncBranchesResult {
3
+ created: number;
4
+ updated: number;
5
+ total: number;
6
+ /**
7
+ * 因分叉点变更尚未拉到本地而**本轮未创建**的分支 id。
8
+ *
9
+ * 远端分支行上的 `fromChangeId` 是远端 change id,落到本地必须翻译成本地 id
10
+ * (见 {@link toLocalFromChangeId})。翻译不出来时既不能写远端 id(本地会当自己的 id 消费,
11
+ * 分叉点变成一个无关变更),也不能写 `null`(`find-switch-branch-step` 会当「分叉于根」,
12
+ * 切换分支时从第一条变更起算)。唯一无损的选择是本轮跳过,等分叉点变更拉到本地后再建。
13
+ */
14
+ skipped: string[];
15
+ }
16
+ /**
17
+ * 从远程拉取所有分支信息并同步到本地
18
+ *
19
+ * 规则:
20
+ * 1. 远程新分支 → 在本地创建(local: false, remote: true)
21
+ * 2. 本地已有的远程分支 → 更新 remote 标记为 true
22
+ * 3. 纯本地分支(remote=false)→ 不受影响
23
+ *
24
+ * @remarks
25
+ * 读本地、排序、落库全部在**同一个事务窗口**内完成:
26
+ *
27
+ * - 无事务时中途失败会留下半批已提交的分支,下次重试撞主键,同步就此永久卡死;
28
+ * - 读若在事务外做,快照与写之间存在窗口,并发建分支会让「本地已有」的判断过时,
29
+ * 重复 create 同样撞主键。
30
+ *
31
+ * 事务体内只能用 `executor` 作用域的仓库。绑在适配器上的那一份走并发度 1 的写队列,
32
+ * 在事务体内调用会排到自己这个事务后面 —— 直接死锁。
33
+ */
34
+ export declare function syncBranches(sm: SyncManager): Promise<SyncBranchesResult>;
35
+ //# sourceMappingURL=sync-branches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-branches.d.ts","sourceRoot":"","sources":["../src/sync-branches.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;;OAOG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AA4DD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA2D/E"}
@@ -0,0 +1,20 @@
1
+ import { Subscription } from 'rxjs';
2
+ import { SyncManager } from './SyncManager.js';
3
+ /**
4
+ * 设置 SyncManager 的同步监听器
5
+ *
6
+ * 包含两条 reactive 链路:
7
+ * 1. 「已连接且网络可达」→ 自动重放 QueryCache 出站队列,离线期间由退避节拍驱动重试,
8
+ * 每个仓库失败仅吞错。changelog 的 `push` 不在其中,见 {@link resumeSync}
9
+ * 2. Remote 实体事件 → 累计 `pullableCount`(仅统计当前激活分支)
10
+ *
11
+ * 调用方负责管理返回的 subscriptions / removers 生命周期(destroy 时清理)。
12
+ *
13
+ * @param sm - 当前同步管理器
14
+ * @returns 已注册的 rxjs subscriptions 和事件解绑闭包
15
+ */
16
+ export declare function setupSyncListeners(sm: SyncManager): {
17
+ subscriptions: Subscription[];
18
+ removers: Array<() => void>;
19
+ };
20
+ //# sourceMappingURL=sync-listeners.d.ts.map
@@ -0,0 +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;AAiMpD;;;;;;;;;;;;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"}
@@ -0,0 +1,36 @@
1
+ import { SyncRepositoryResult } from './sync-repository.js';
2
+ /**
3
+ * 「这次同步已经改写了本地数据」的共同判据形状。
4
+ *
5
+ * @remarks
6
+ * 四个粒度的结果都满足它,所以判据只需要写一份:整库 / 单仓库的 `PullResult` 只有
7
+ * `historyInvalidated`,`SyncRepositoryResult` 还多一段 `pushResult`。两项都取可选,
8
+ * 缺哪一段就当那一段没有进度。
9
+ */
10
+ interface SyncedProgress {
11
+ readonly historyInvalidated?: boolean;
12
+ readonly pushResult?: {
13
+ readonly pushed: number;
14
+ };
15
+ }
16
+ /** 一次仓库同步是否改写了本地实体数据(undo 历史边界因此失效) */
17
+ export declare const hasSyncedData: (result: SyncedProgress | undefined) => boolean;
18
+ /**
19
+ * 中断的同步里是否带着「已经落库 / 已经上行」的进度。
20
+ *
21
+ * @remarks
22
+ * 部分成功以 {@link RxDBPartialSyncError} 的形式抛出,进度只挂在它的 `result` 上。
23
+ * `pull` / `pullRepository` / `sync` / `syncRepository` 四个入口共用这一条判据 ——
24
+ * 各写各的 `instanceof` + 强转,迟早会有一个入口漏掉 `pushResult` 那一半。
25
+ */
26
+ export declare const partialSyncInvalidatesHistory: (error: unknown) => boolean;
27
+ /**
28
+ * 取出失败项里携带的部分进度。
29
+ *
30
+ * @remarks
31
+ * 仓库在失败前可能已经提交了部分结果,它只存在于 {@link RxDBPartialSyncError.result}。
32
+ * 忽略它会让「远端数据已落库但 undo 边界没推进」的状态逃过检查。
33
+ */
34
+ export declare const partialResultOf: (error: Error | undefined) => SyncRepositoryResult | undefined;
35
+ export {};
36
+ //# sourceMappingURL=sync-manager.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-manager.utils.d.ts","sourceRoot":"","sources":["../src/sync-manager.utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE;;;;;;;GAOG;AACH,UAAU,cAAc;IACtB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACnD;AAED,uCAAuC;AACvC,eAAO,MAAM,aAAa,GAAI,QAAQ,cAAc,GAAG,SAAS,KAAG,OACW,CAAC;AAE/E;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,GAAI,OAAO,OAAO,KAAG,OACyB,CAAC;AAEzF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,KAAK,GAAG,SAAS,KAAG,oBAAoB,GAAG,SACU,CAAC"}