@aiao/rxdb-plugin-history 0.0.0-stage → 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.
Files changed (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -2
  3. package/dist/HistoryManager.d.ts +87 -0
  4. package/dist/HistoryManager.d.ts.map +1 -0
  5. package/dist/VersionManager.d.ts +243 -0
  6. package/dist/VersionManager.d.ts.map +1 -0
  7. package/dist/create-branch.d.ts +35 -0
  8. package/dist/create-branch.d.ts.map +1 -0
  9. package/dist/detached-event-error.d.ts +28 -0
  10. package/dist/detached-event-error.d.ts.map +1 -0
  11. package/dist/find-switch-branch-step.d.ts +94 -0
  12. package/dist/find-switch-branch-step.d.ts.map +1 -0
  13. package/dist/history-filters.d.ts +78 -0
  14. package/dist/history-filters.d.ts.map +1 -0
  15. package/dist/history-item-builder.d.ts +25 -0
  16. package/dist/history-item-builder.d.ts.map +1 -0
  17. package/dist/history-scope-api.d.ts +41 -0
  18. package/dist/history-scope-api.d.ts.map +1 -0
  19. package/dist/history-undo-session.types.d.ts +32 -0
  20. package/dist/history-undo-session.types.d.ts.map +1 -0
  21. package/dist/index.d.ts +39 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +1565 -0
  24. package/dist/merge-branch.d.ts +22 -0
  25. package/dist/merge-branch.d.ts.map +1 -0
  26. package/dist/plugin.d.ts +58 -0
  27. package/dist/plugin.d.ts.map +1 -0
  28. package/dist/pullable-count.d.ts +37 -0
  29. package/dist/pullable-count.d.ts.map +1 -0
  30. package/dist/push-inflight.d.ts +60 -0
  31. package/dist/push-inflight.d.ts.map +1 -0
  32. package/dist/redo-stack.d.ts +56 -0
  33. package/dist/redo-stack.d.ts.map +1 -0
  34. package/dist/remove-branch.d.ts +16 -0
  35. package/dist/remove-branch.d.ts.map +1 -0
  36. package/dist/restore-entity.d.ts +15 -0
  37. package/dist/restore-entity.d.ts.map +1 -0
  38. package/dist/scope-selection.d.ts +56 -0
  39. package/dist/scope-selection.d.ts.map +1 -0
  40. package/dist/switch-branch-actions.d.ts +87 -0
  41. package/dist/switch-branch-actions.d.ts.map +1 -0
  42. package/dist/sync-history-bridge.d.ts +87 -0
  43. package/dist/sync-history-bridge.d.ts.map +1 -0
  44. package/dist/undo-redo-apply.d.ts +47 -0
  45. package/dist/undo-redo-apply.d.ts.map +1 -0
  46. package/dist/version-manager.utils.d.ts +30 -0
  47. package/dist/version-manager.utils.d.ts.map +1 -0
  48. package/package.json +59 -3
  49. package/src/HistoryManager.ts +800 -0
  50. package/src/VersionManager.ts +617 -0
  51. package/src/create-branch.ts +178 -0
  52. package/src/detached-event-error.ts +43 -0
  53. package/src/find-switch-branch-step.ts +313 -0
  54. package/src/history-filters.ts +157 -0
  55. package/src/history-item-builder.ts +101 -0
  56. package/src/history-scope-api.ts +189 -0
  57. package/src/history-undo-session.types.ts +37 -0
  58. package/src/index.ts +61 -0
  59. package/src/merge-branch.ts +192 -0
  60. package/src/plugin.ts +93 -0
  61. package/src/pullable-count.ts +67 -0
  62. package/src/push-inflight.ts +91 -0
  63. package/src/redo-stack.ts +79 -0
  64. package/src/remove-branch.ts +100 -0
  65. package/src/restore-entity.ts +124 -0
  66. package/src/scope-selection.ts +133 -0
  67. package/src/switch-branch-actions.ts +319 -0
  68. package/src/sync-history-bridge.ts +131 -0
  69. package/src/undo-redo-apply.ts +270 -0
  70. package/src/version-manager.utils.ts +43 -0
package/dist/index.js ADDED
@@ -0,0 +1,1565 @@
1
+ import { ENTITY_LOCAL_CREATE_EVENT as e, MAIN_BRANCH_ID as t, MergeBranchBeginEvent as n, MergeBranchCommitEvent as r, MergeBranchFailedEvent as i, REPOSITORY_SYNC_COMPLETE_EVENT as a, RxDBBranch as o, RxDBChange as s, RxDBError as c, RxDBPluginBase as l, RxDBSync as u, SKIP_BRANCH_SWITCH_PREPARE as d, SwitchBranchBeginEvent as f, SwitchBranchCommitEvent as p, SwitchBranchRollbackEvent as m, TRANSACTION_BEGIN as h, TRANSACTION_COMMIT as g, TRANSACTION_ROLLBACK as _, TrustedWriteIntent as v, assertUsableBranchId as ee, buildPushableRepositoryRules as te, declareTrustedWrite as y, getCurrentBranch as ne, getEntityMetadata as b, getLocalSystemRepositories as re, getRemoteSystemRepositories as ie, getRxDBChangeKey as x, getRxDBEntityIdentityKey as S, isAdapterShutdownError as C, resolve_current_branch as ae, takeDeclaredWrite as oe } from "@aiao/rxdb";
2
+ import { BehaviorSubject as w, EMPTY as se, NEVER as ce, Observable as le, ReplaySubject as ue, Subject as de, catchError as fe, combineLatest as T, filter as E, firstValueFrom as D, map as O, shareReplay as k, switchMap as A, takeUntil as j } from "rxjs";
3
+ import { isNil as M } from "@aiao/utils";
4
+ //#region src/create-branch.ts
5
+ var pe = async (e, t, n) => {
6
+ ee(t);
7
+ let { branchRepository: r, adapter: i } = await e.getLocalRepositories();
8
+ if ((await r.find({
9
+ where: {
10
+ combinator: "and",
11
+ rules: [{
12
+ field: "id",
13
+ operator: "=",
14
+ value: t
15
+ }]
16
+ },
17
+ limit: 1
18
+ })).length) throw new c(`Branch id (${t}) already exists`);
19
+ if (e.rxdb.config.sync?.remote?.adapter) {
20
+ let { adapter: n } = await e.getRemoteRepositories();
21
+ if (n.branchExists && await n.branchExists(t)) throw new c(`Branch id (${t}) already exists on remote`);
22
+ }
23
+ let a = await i.transaction(async (r) => {
24
+ let i = r.getRepository(o), a = r.getRepository(s);
25
+ if ((await i.find({
26
+ where: {
27
+ combinator: "and",
28
+ rules: [{
29
+ field: "id",
30
+ operator: "=",
31
+ value: t
32
+ }]
33
+ },
34
+ limit: 1
35
+ })).length) return `Branch id (${t}) already exists`;
36
+ let c, l;
37
+ if (n) {
38
+ let e = (await a.find({
39
+ where: {
40
+ combinator: "and",
41
+ rules: [{
42
+ field: "id",
43
+ operator: "=",
44
+ value: n
45
+ }]
46
+ },
47
+ limit: 1
48
+ }))[0];
49
+ if (!e) return `Change ID (${n}) not found`;
50
+ l = e, c = (await i.find({
51
+ where: {
52
+ combinator: "and",
53
+ rules: [{
54
+ field: "id",
55
+ operator: "=",
56
+ value: e.branchId
57
+ }]
58
+ },
59
+ limit: 1
60
+ }))[0];
61
+ } else c = await ae(i, e.rxdb), l = await me(a, c.id);
62
+ if (!c) return "Source branch not found";
63
+ let u = e.rxdb.entityManager.instantiate(o);
64
+ u.id = t, u.activated = !1, u.activeKey = null, u.local = !0, u.remote = !1, u.fromChangeId = l?.id ?? null, u.parentId = c.id, await i.create(u);
65
+ for (let n of e.rxdb.systemContributions) await n.writeBranchRows(e.rxdb.entityManager, {
66
+ executor: r,
67
+ branchId: t
68
+ });
69
+ return u;
70
+ });
71
+ if (typeof a == "string") throw new c(a);
72
+ return a;
73
+ }, me = async (e, t) => (await e.find({
74
+ where: {
75
+ combinator: "and",
76
+ rules: [t ? {
77
+ field: "branchId",
78
+ operator: "=",
79
+ value: t
80
+ } : {
81
+ field: "branch.activated",
82
+ operator: "=",
83
+ value: !0
84
+ }, {
85
+ field: "revertChangeId",
86
+ operator: "=",
87
+ value: null
88
+ }]
89
+ },
90
+ orderBy: [{
91
+ field: "id",
92
+ sort: "desc"
93
+ }],
94
+ limit: 1
95
+ }))[0], N = (e) => {
96
+ if (!e || typeof e != "object") return !1;
97
+ let t = "name" in e ? String(e.name) : "";
98
+ return ("errno" in e ? Number(e.errno) : void 0) === 44 || t === "AbortError" || C(e);
99
+ };
100
+ //#endregion
101
+ //#region src/history-item-builder.ts
102
+ function P(e) {
103
+ if (e.length === 1) {
104
+ let t = e[0];
105
+ return `${t.type === "INSERT" ? "创建" : t.type === "UPDATE" ? "更新" : "删除"} ${t.entity}`;
106
+ }
107
+ let t = {};
108
+ for (let n of e) {
109
+ let e = n.type.toLowerCase();
110
+ t[e] = (t[e] ?? 0) + 1;
111
+ }
112
+ let n = [];
113
+ return t.insert && n.push(`创建${t.insert}条`), t.update && n.push(`更新${t.update}条`), t.delete && n.push(`删除${t.delete}条`), `事务: ${n.join(", ")}`;
114
+ }
115
+ function F(e) {
116
+ let t = e[0], n = e.length, r = t.transactionId ?? null, i = t.createdAt, a = t.namespace, o = t.entity, s = r ? "TRANSACTION" : t.type, c = [
117
+ s,
118
+ S(t.entityId),
119
+ i.getTime()
120
+ ].join(":"), l = e.some((e) => M(e.revertChangeId) === !1), u = e.some((e) => M(e.redoInvalidatedAt) === !1);
121
+ return {
122
+ transactionId: r,
123
+ changeId: e.reduce((e, t) => t.id > e ? t.id : e, e[0].id),
124
+ fingerprint: c,
125
+ changes: e,
126
+ type: s,
127
+ count: n,
128
+ createdAt: i,
129
+ description: P(e),
130
+ namespace: a,
131
+ entity: o,
132
+ reverted: l,
133
+ redoInvalidated: u
134
+ };
135
+ }
136
+ function I(e) {
137
+ let t = [], n = [], r;
138
+ return e.forEach((e) => {
139
+ e.transactionId && e.transactionId === r ? n.push(e) : (r = e.transactionId, n.length &&= (t.push(F([...n])), 0), e.transactionId ? n.push(e) : t.push(F([e])));
140
+ }), n.length && t.push(F([...n])), t;
141
+ }
142
+ //#endregion
143
+ //#region src/history-filters.ts
144
+ var L = (e) => `${e.namespace}:${e.entity}`;
145
+ function R(e, t) {
146
+ let n = new Map(t);
147
+ for (let t of e) {
148
+ if (t.lastPushedChangeId === null) continue;
149
+ let e = L(t), r = n.get(e);
150
+ r !== void 0 && r >= t.lastPushedChangeId || n.set(e, t.lastPushedChangeId);
151
+ }
152
+ return n;
153
+ }
154
+ function z(e, t) {
155
+ return t.type === "database" ? e : e.map((e) => {
156
+ let n = e.changes.filter((e) => t.type === "repository" ? e.namespace === t.namespace && e.entity === t.entity : e.namespace === t.namespace && e.entity === t.entity && e.entityId === t.entityId);
157
+ return n.length === 0 ? null : {
158
+ ...e,
159
+ changes: n,
160
+ count: n.length,
161
+ description: P(n)
162
+ };
163
+ }).filter((e) => e !== null);
164
+ }
165
+ function B(e, t, n = 0, r = null) {
166
+ return e.filter((e) => !e.reverted && e.changes.every((e) => {
167
+ let i = e.remoteId == null, a = t.get(L(e)), o = a == null || e.id > a, s = e.id > n, c = r === null || e.createdAt.getTime() > r.getTime();
168
+ return i && o && s && c;
169
+ }));
170
+ }
171
+ function he(e) {
172
+ return e.type === "database" ? "database" : e.type === "repository" ? `${e.namespace}:${e.entity}` : `${e.namespace}:${e.entity}:${S(e.entityId)}`;
173
+ }
174
+ //#endregion
175
+ //#region src/history-scope-api.ts
176
+ function ge(e) {
177
+ if (!e) return { type: "database" };
178
+ if (Object.getPrototypeOf(e) === Object.prototype && "type" in e) return e;
179
+ let t = b(e), n = "id" in e ? e.id : void 0, r = typeof n == "string" || typeof n == "number" || typeof n == "bigint" ? n : void 0;
180
+ return r === void 0 ? {
181
+ type: "repository",
182
+ namespace: t.namespace,
183
+ entity: t.name
184
+ } : {
185
+ type: "entity",
186
+ namespace: t.namespace,
187
+ entity: t.name,
188
+ entityId: r
189
+ };
190
+ }
191
+ function _e(e, t) {
192
+ let n = ge(t), r = he(n), i = e.history_cache.get(r);
193
+ if (i) return i;
194
+ let a = () => {
195
+ let t = (e.history_ref_counts.get(r) || 0) - 1;
196
+ t <= 0 ? (e.history_cache.delete(r), e.history_ref_counts.delete(r)) : e.history_ref_counts.set(r, t);
197
+ }, o = () => {
198
+ let t = (e.history_ref_counts.get(r) || 0) + 1;
199
+ e.history_ref_counts.set(r, t), e.history_cache.set(r, h);
200
+ }, s = (e) => new le((t) => {
201
+ o();
202
+ let n = e.subscribe(t);
203
+ return () => {
204
+ n.unsubscribe(), a();
205
+ };
206
+ }), c = e.histories$.pipe(O((e) => z(e, n)), k({
207
+ bufferSize: 1,
208
+ refCount: !0
209
+ })), l = s(c), u = s(e.undoHistories$.pipe(O((e) => z(e, n)), k({
210
+ bufferSize: 1,
211
+ refCount: !0
212
+ }))), d = s(e.redoHistories$.pipe(O((e) => z(e, n)), k({
213
+ bufferSize: 1,
214
+ refCount: !0
215
+ }))), f = s(c.pipe(O((e) => e.length), k({
216
+ bufferSize: 1,
217
+ refCount: !0
218
+ }))), p = s(u.pipe(O((e) => e.length), k({
219
+ bufferSize: 1,
220
+ refCount: !0
221
+ }))), m = s(d.pipe(O((e) => e.length), k({
222
+ bufferSize: 1,
223
+ refCount: !0
224
+ }))), h = {
225
+ type: n.type,
226
+ histories$: l,
227
+ undoHistories$: u,
228
+ redoHistories$: d,
229
+ count$: f,
230
+ undoCount$: p,
231
+ redoCount$: m,
232
+ undo: (t = 1) => e.runSerialized(async () => {
233
+ let r = e.undoSession$.value;
234
+ if (r.state === "cleared") return;
235
+ let { histories: i, lastPushedMap: a } = await e.fetchLatestHistories(r.boundary);
236
+ if (!e.isUndoSessionCurrent(r)) return;
237
+ let o = B(i, a, r.boundary.changeId, r.boundary.createdAfter), s = e.selectWholeTransactions(o, n, t);
238
+ s.length !== 0 && await e.applyUndoRedoHistories("undo", s, r);
239
+ }),
240
+ redo: (t = 1) => e.runSerialized(async () => {
241
+ let r = await D(e.redoHistories$), i = e.selectWholeTransactions(r, n, t);
242
+ i.length !== 0 && await e.applyUndoRedoHistories("redo", i);
243
+ })
244
+ };
245
+ return h;
246
+ }
247
+ //#endregion
248
+ //#region src/history-undo-session.types.ts
249
+ var V = {
250
+ changeId: 0,
251
+ createdAfter: null
252
+ };
253
+ //#endregion
254
+ //#region src/pullable-count.ts
255
+ function ve(e, t) {
256
+ return e?.repositoryFilter !== void 0 && e.repositoryFilter.length > 0 ? !1 : !t.hasMore && t.failures.length === 0;
257
+ }
258
+ function ye(e, t) {
259
+ return t.complete && !t.concurrent ? 0 : Math.max(0, e - t.pulled);
260
+ }
261
+ //#endregion
262
+ //#region src/redo-stack.ts
263
+ var be = 1e3, xe = class {
264
+ #e = new w([]);
265
+ get items$() {
266
+ return this.#e.asObservable();
267
+ }
268
+ get value() {
269
+ return this.#e.value;
270
+ }
271
+ push(e) {
272
+ let t = [...e, ...this.#e.value], n = t.length > 1e3 ? t.slice(0, be) : t;
273
+ this.#e.next(n);
274
+ }
275
+ remove(e) {
276
+ let t = new Set(e.map((e) => e.fingerprint)), n = this.#e.value, r = n.filter((e) => t.has(e.fingerprint));
277
+ return r.length === 0 || this.#e.next(n.filter((e) => !t.has(e.fingerprint))), r;
278
+ }
279
+ clear() {
280
+ this.#e.next([]);
281
+ }
282
+ };
283
+ //#endregion
284
+ //#region src/scope-selection.ts
285
+ function H(e, t) {
286
+ return t.type === "database" ? !0 : e.namespace !== t.namespace || e.entity !== t.entity ? !1 : t.type === "repository" || e.entityId === t.entityId;
287
+ }
288
+ function Se(e, t) {
289
+ return e.changes.some((e) => H(e, t));
290
+ }
291
+ function Ce(e, t) {
292
+ return e.changes.every((e) => H(e, t));
293
+ }
294
+ function we(e, t, n) {
295
+ let r = e.filter((e) => Se(e, t)).slice(0, Math.max(0, n)), i = [], a = [];
296
+ for (let e of r) Ce(e, t) ? a.push(e) : i.push(e);
297
+ return {
298
+ crossScope: i,
299
+ selected: a
300
+ };
301
+ }
302
+ var Te = (e) => e.type === "database" ? "database" : e.type === "repository" ? `${e.namespace}:${e.entity}` : `${e.namespace}:${e.entity}#${String(e.entityId)}`, Ee = (e, t) => {
303
+ let n = /* @__PURE__ */ new Set();
304
+ for (let r of e) for (let e of r.changes) H(e, t) || n.add(t.type === "entity" ? `${e.namespace}:${e.entity}#${String(e.entityId)}` : `${e.namespace}:${e.entity}`);
305
+ return [...n].join(", ");
306
+ }, U = class e extends c {
307
+ scope;
308
+ histories;
309
+ constructor(t, n) {
310
+ super(`Scoped history operation would split a transaction: scope ${Te(t)} also changes ${Ee(n, t)}. Use the database scope to apply the whole transaction.`), this.scope = t, this.histories = n, this.name = "RxDBCrossScopeTransactionError", Object.setPrototypeOf(this, e.prototype);
311
+ }
312
+ }, W = (e) => e.fromChangeId ?? 0, G = (e, t) => {
313
+ let n = [e], r = /* @__PURE__ */ new Set([e.id]), i = e;
314
+ for (; i.parentId;) {
315
+ if (r.has(i.parentId)) throw new c(`Branch history is corrupt: cycle detected at branch '${i.id}' (parentId '${i.parentId}' already visited)`);
316
+ let e = t.get(i.parentId);
317
+ if (!e) throw new c(`Branch history is corrupt: branch '${i.id}' references missing parent '${i.parentId}'`);
318
+ r.add(e.id), n.push(e), i = e;
319
+ }
320
+ return n;
321
+ }, K = (e) => {
322
+ let { branches: t, currentBranch: n, nextBranch: r } = e, i = e.currentChangeId ?? W(n), a = e.nextChangeId ?? W(r);
323
+ if (i === a) return [];
324
+ if (n.id === r.id) return [{
325
+ branch: n,
326
+ fromChangeId: i,
327
+ toChangeId: a
328
+ }];
329
+ let o = /* @__PURE__ */ new Map();
330
+ for (let e of t) o.set(e.id, e);
331
+ let s = G(n, o), c = G(r, o), l = null, u = -1;
332
+ for (let e = 0; e < s.length; e++) if (c.findIndex((t) => t.id === s[e].id) !== -1) {
333
+ l = s[e], u = e;
334
+ break;
335
+ }
336
+ let d = [];
337
+ if (l) {
338
+ for (let e = 0; e < u; e++) {
339
+ let t = s[e], n = e === 0 ? i : W(s[e - 1]), r = W(t);
340
+ n !== r && d.push({
341
+ branch: t,
342
+ fromChangeId: n,
343
+ toChangeId: r
344
+ });
345
+ }
346
+ let e = c.findIndex((e) => e.id === l.id);
347
+ if (e === 0) {
348
+ let e = u === 0 ? i : W(s[u - 1]), t = a;
349
+ e !== t && d.push({
350
+ branch: l,
351
+ fromChangeId: e,
352
+ toChangeId: t
353
+ });
354
+ } else if (e > 0) {
355
+ let t = u === 0 ? i : W(s[u - 1]), n = W(c[e - 1]);
356
+ t !== n && d.push({
357
+ branch: l,
358
+ fromChangeId: t,
359
+ toChangeId: n
360
+ });
361
+ }
362
+ let t = c.slice(0, e).reverse();
363
+ for (let e = 0; e < t.length; e++) {
364
+ let n = t[e], r = W(n), i = e === t.length - 1 ? a : W(t[e + 1]);
365
+ r !== i && d.push({
366
+ branch: n,
367
+ fromChangeId: r,
368
+ toChangeId: i
369
+ });
370
+ }
371
+ } else {
372
+ for (let e = 0; e < s.length; e++) {
373
+ let t = s[e], n = e === 0 ? i : W(s[e - 1]), r = W(t);
374
+ n !== r && d.push({
375
+ branch: t,
376
+ fromChangeId: n,
377
+ toChangeId: r
378
+ });
379
+ }
380
+ let e = s[s.length - 1], t = W(e);
381
+ t !== 0 && d.push({
382
+ branch: e,
383
+ fromChangeId: t,
384
+ toChangeId: 0
385
+ });
386
+ let n = c[c.length - 1], r = c.length > 1 ? W(c[c.length - 2]) : a;
387
+ r !== 0 && d.push({
388
+ branch: n,
389
+ fromChangeId: 0,
390
+ toChangeId: r
391
+ });
392
+ let o = c.slice(0, c.length - 1).reverse();
393
+ for (let e = 0; e < o.length; e++) {
394
+ let t = o[e], n = W(t), r = e === o.length - 1 ? a : W(o[e + 1]);
395
+ n !== r && d.push({
396
+ branch: t,
397
+ fromChangeId: n,
398
+ toChangeId: r
399
+ });
400
+ }
401
+ }
402
+ return d;
403
+ }, De = async (e, t) => q(await e.getLocalRepositories(), t), q = async (e, t) => {
404
+ let { branchRepository: n, changeRepository: r } = e, i = (await n.find({
405
+ where: {
406
+ combinator: "and",
407
+ rules: [{
408
+ field: "activated",
409
+ operator: "=",
410
+ value: !0
411
+ }]
412
+ },
413
+ limit: 1
414
+ }))[0];
415
+ if (!i) throw new c("Current branch not found");
416
+ let a = await n.find({ where: {
417
+ combinator: "and",
418
+ rules: []
419
+ } }), o = a.find((e) => e.id === t);
420
+ if (!o) throw new c(`Branch (${t}) not found`);
421
+ if (i.id === o.id) throw new c("Cannot switch to the same branch");
422
+ let s = await Y(r, i.id), l = await Y(r, o.id), u = K({
423
+ branches: a,
424
+ currentBranch: i,
425
+ currentChangeId: s ? s.id : null,
426
+ nextBranch: o,
427
+ nextChangeId: l ? l.id : null
428
+ }), d = {
429
+ deletes: /* @__PURE__ */ new Map(),
430
+ updates: /* @__PURE__ */ new Map(),
431
+ inserts: /* @__PURE__ */ new Map()
432
+ };
433
+ for (let e = 0; e < u.length; e++) {
434
+ let { branch: t, fromChangeId: n, toChangeId: i } = u[e], a = n < i, o = n > i, s = Math.min(n, i), c = Math.max(n, i), l = { where: {
435
+ combinator: "and",
436
+ rules: [
437
+ {
438
+ field: "branchId",
439
+ operator: "=",
440
+ value: t.id
441
+ },
442
+ {
443
+ field: "id",
444
+ operator: ">",
445
+ value: s
446
+ },
447
+ {
448
+ field: "id",
449
+ operator: "<=",
450
+ value: c
451
+ },
452
+ {
453
+ field: "revertChangeId",
454
+ operator: "=",
455
+ value: null
456
+ }
457
+ ]
458
+ } };
459
+ t.fromChangeId && s < t.fromChangeId && l.where.rules.push({
460
+ field: "id",
461
+ operator: ">",
462
+ value: t.fromChangeId
463
+ });
464
+ let f = await r.find(l);
465
+ o ? ke(f, d) : a && Oe(f, d);
466
+ }
467
+ return d;
468
+ }, Oe = (e, t) => J(e, !0, t), ke = (e, t) => J(e, !1, t), J = (e, t, n = {
469
+ deletes: /* @__PURE__ */ new Map(),
470
+ updates: /* @__PURE__ */ new Map(),
471
+ inserts: /* @__PURE__ */ new Map()
472
+ }) => {
473
+ if (t) {
474
+ let t = [...e].sort((e, t) => e.id - t.id);
475
+ for (let e of t) {
476
+ let t = x(e);
477
+ switch (e.type) {
478
+ case "INSERT":
479
+ n.inserts.set(t, {
480
+ patch: { ...e.patch },
481
+ inversePatch: null
482
+ });
483
+ break;
484
+ case "UPDATE":
485
+ {
486
+ let r = n.inserts.get(t) || n.updates.get(t);
487
+ r ? (r.patch && e.patch && Object.assign(r.patch, e.patch), r.inversePatch === null && e.inversePatch ? r.inversePatch = { ...e.inversePatch } : r.inversePatch && e.inversePatch && Object.assign(r.inversePatch, e.inversePatch)) : n.updates.set(t, {
488
+ patch: { ...e.patch },
489
+ inversePatch: { ...e.inversePatch }
490
+ });
491
+ }
492
+ break;
493
+ case "DELETE": n.deletes.set(t, {
494
+ patch: null,
495
+ inversePatch: { ...e.inversePatch }
496
+ }), n.inserts.delete(t), n.updates.delete(t);
497
+ }
498
+ }
499
+ } else {
500
+ let t = [...e].sort((e, t) => t.id - e.id);
501
+ for (let e of t) {
502
+ let t = x(e);
503
+ switch (e.type) {
504
+ case "INSERT":
505
+ n.deletes.set(t, {
506
+ patch: null,
507
+ inversePatch: { ...e.patch }
508
+ }), n.inserts.delete(t), n.updates.delete(t);
509
+ break;
510
+ case "UPDATE":
511
+ {
512
+ let r = n.inserts.get(t) || n.updates.get(t);
513
+ r ? (r.patch && e.inversePatch && Object.assign(r.patch, e.inversePatch), r.inversePatch && e.patch && Object.assign(r.inversePatch, e.patch)) : n.updates.set(t, {
514
+ patch: { ...e.inversePatch },
515
+ inversePatch: { ...e.patch }
516
+ });
517
+ }
518
+ break;
519
+ case "DELETE": n.inserts.set(t, {
520
+ patch: { ...e.inversePatch },
521
+ inversePatch: null
522
+ });
523
+ }
524
+ }
525
+ }
526
+ return n;
527
+ }, Y = async (e, t) => (await e.find({
528
+ where: {
529
+ combinator: "and",
530
+ rules: [{
531
+ field: "branchId",
532
+ operator: "=",
533
+ value: t
534
+ }, {
535
+ field: "revertChangeId",
536
+ operator: "=",
537
+ value: null
538
+ }]
539
+ },
540
+ orderBy: [{
541
+ field: "id",
542
+ sort: "desc"
543
+ }],
544
+ limit: 1
545
+ }))[0], X = (e) => e.getRepository(u);
546
+ async function Ae(e, t) {
547
+ let { changeRepository: n, branchRepository: r } = await e.rxdb.versionManager.getLocalRepositories(), i = await r.find({ where: {
548
+ combinator: "and",
549
+ rules: [{
550
+ field: "activated",
551
+ operator: "=",
552
+ value: !0
553
+ }]
554
+ } });
555
+ if (i.length === 0) return {
556
+ histories: [],
557
+ lastPushedMap: /* @__PURE__ */ new Map()
558
+ };
559
+ let a = i[0], o = R(await X(await D(e.rxdb.localAdapter$)).find({ where: {
560
+ combinator: "and",
561
+ rules: [{
562
+ field: "branchId",
563
+ operator: "=",
564
+ value: a.id
565
+ }]
566
+ } }), e.rxdb.versionManager.pushInFlight.snapshot()), s = [{
567
+ field: "branchId",
568
+ operator: "=",
569
+ value: a.id
570
+ }, {
571
+ field: "createdAt",
572
+ operator: ">=",
573
+ value: e.getFirstConnectedAt()
574
+ }];
575
+ return t.changeId > 0 && s.push({
576
+ field: "id",
577
+ operator: ">",
578
+ value: t.changeId
579
+ }), {
580
+ histories: I(await n.find({
581
+ where: {
582
+ combinator: "and",
583
+ rules: s
584
+ },
585
+ orderBy: [{
586
+ field: "id",
587
+ sort: "desc"
588
+ }]
589
+ })),
590
+ lastPushedMap: o
591
+ };
592
+ }
593
+ async function je(e, t, n, r) {
594
+ e.isUndoRedoInProgress = !0;
595
+ try {
596
+ let i = n.flatMap((e) => e.changes).sort((e, n) => t === "undo" ? n.id - e.id : e.id - n.id), a = J(i, t === "redo"), o = e.getNextRevertStateUpdatedAt(i);
597
+ if (t === "undo") {
598
+ let { adapter: t } = await e.rxdb.versionManager.getLocalRepositories(), n = await t.getRxDBChangeSequence(), r = /* @__PURE__ */ new Date();
599
+ i.forEach((e, t) => {
600
+ let i = `rxdb:RxDBChange:${e.id}`, s = a.updates.get(i) || {
601
+ patch: {},
602
+ inversePatch: null
603
+ };
604
+ a.updates.set(i, {
605
+ patch: {
606
+ ...s.patch,
607
+ revertChangeId: n + t + 1,
608
+ revertChangedAt: r,
609
+ updatedAt: o
610
+ },
611
+ inversePatch: s.inversePatch
612
+ });
613
+ }), a.updateRxDBChangeSequence = n + i.length, e.redoInvalidationFloor = n + i.length;
614
+ } else i.forEach((e) => {
615
+ let t = `rxdb:RxDBChange:${e.id}`, n = a.updates.get(t) || {
616
+ patch: {},
617
+ inversePatch: null
618
+ };
619
+ a.updates.set(t, {
620
+ patch: {
621
+ ...n.patch,
622
+ revertChangeId: null,
623
+ updatedAt: o
624
+ },
625
+ inversePatch: n.inversePatch
626
+ });
627
+ });
628
+ let { adapter: s } = await e.rxdb.versionManager.getLocalRepositories();
629
+ if (t === "undo" && (r === void 0 || !e.isUndoSessionCurrent(r))) return;
630
+ y(s, {
631
+ file: "undo-redo-apply.ts",
632
+ symbol: "applyUndoRedoHistories",
633
+ intent: v.undo_redo
634
+ }), await s.switchBranch({
635
+ actions: a,
636
+ prepare: d
637
+ }), e.pushableCountTrigger$.next(Date.now()), e.setRevertStateWatermarks(i, t === "undo", o), t === "undo" ? e.pushToRedoStack(n) : e.removeFromRedoStack(n);
638
+ } finally {
639
+ e.isUndoRedoInProgress = !1;
640
+ }
641
+ }
642
+ async function Me(e) {
643
+ let t = ++e.pushableGeneration, n = (n) => {
644
+ t === e.pushableGeneration && e.pushableCount$.next(n);
645
+ };
646
+ try {
647
+ if (!await D(e.rxdb.connected$)) {
648
+ n(0);
649
+ return;
650
+ }
651
+ let t = X(await D(e.rxdb.localAdapter$)), r = e.rxdb.entityManager.getRepository(s), i = await D(e.rxdb.entityManager.getRepository(o).findOne({ where: {
652
+ combinator: "and",
653
+ rules: [{
654
+ field: "activated",
655
+ operator: "=",
656
+ value: !0
657
+ }]
658
+ } }));
659
+ if (!i) {
660
+ n(0);
661
+ return;
662
+ }
663
+ let a = await t.find({ where: {
664
+ combinator: "and",
665
+ rules: [{
666
+ field: "branchId",
667
+ operator: "=",
668
+ value: i.id
669
+ }]
670
+ } }), c = te(e.rxdb.config.entities, e.rxdb.entitySync, a);
671
+ if (c.length === 0) {
672
+ n(0);
673
+ return;
674
+ }
675
+ n(await D(r.count({ where: {
676
+ combinator: "and",
677
+ rules: [
678
+ {
679
+ field: "branchId",
680
+ operator: "=",
681
+ value: i.id
682
+ },
683
+ {
684
+ field: "revertChangeId",
685
+ operator: "=",
686
+ value: null
687
+ },
688
+ {
689
+ field: "remoteId",
690
+ operator: "=",
691
+ value: null
692
+ },
693
+ {
694
+ combinator: "or",
695
+ rules: c
696
+ }
697
+ ]
698
+ } })));
699
+ } catch (t) {
700
+ !e.destroyed && !C(t) && (console.error("[#updatePushableCount] error", t), e.errors$.next(t instanceof Error ? t : Error(String(t)))), n(0);
701
+ }
702
+ }
703
+ //#endregion
704
+ //#region src/HistoryManager.ts
705
+ var Z = (e) => e.reduce((e, t) => t < e ? t : e, Infinity), Ne = class {
706
+ rxdb;
707
+ #e = [];
708
+ #t = !1;
709
+ #n;
710
+ #r;
711
+ #i = new ue(1);
712
+ #a = Promise.resolve();
713
+ #o = new w(0);
714
+ #s = 0;
715
+ #c = new w(0);
716
+ #l = 0;
717
+ #u = new w(0);
718
+ #d = /* @__PURE__ */ new Map();
719
+ #f = new w(0);
720
+ #p = 0;
721
+ #m;
722
+ #h = null;
723
+ #g = /* @__PURE__ */ new Date();
724
+ #_ = /* @__PURE__ */ new Map();
725
+ #v = null;
726
+ #y = 0;
727
+ #b = null;
728
+ #x = new w({
729
+ generation: 0,
730
+ state: "active",
731
+ boundary: V
732
+ });
733
+ isUndoRedoInProgress = !1;
734
+ isInvalidatingRedo = !1;
735
+ syncDepth = 0;
736
+ redoStack = new xe();
737
+ history_cache = /* @__PURE__ */ new Map();
738
+ history_ref_counts = /* @__PURE__ */ new Map();
739
+ histories$;
740
+ undoHistories$;
741
+ redoHistories$;
742
+ undoCount$;
743
+ redoCount$;
744
+ errors$ = new de();
745
+ pushableCount$;
746
+ pullableCount$;
747
+ count$;
748
+ get undoSessionGeneration() {
749
+ return this.#x.value.generation;
750
+ }
751
+ constructor(e) {
752
+ this.rxdb = e, this.#n = this.#R(), this.#r = this.#z();
753
+ let t = e.entityManager.getRepository(o), n = e.entityManager.getRepository(s), r = this.rxdb.connected$.pipe(A((e) => e ? t.findOne({ where: {
754
+ combinator: "and",
755
+ rules: [{
756
+ field: "activated",
757
+ operator: "=",
758
+ value: !0
759
+ }]
760
+ } }) : ce));
761
+ this.#e.push(r.pipe(j(this.#i)).subscribe({
762
+ next: (e) => this.#E(e?.id ?? null),
763
+ error: (e) => this.#T("undo session 分支跟随的活跃分支流已中断", e)
764
+ })), this.#m = T({
765
+ connected: this.rxdb.connected$,
766
+ branch: r
767
+ }).pipe(E(({ connected: e, branch: t }) => e && !!t), A(({ branch: e }) => {
768
+ let t = this.#M();
769
+ return n.findAll({
770
+ where: {
771
+ combinator: "and",
772
+ rules: [{
773
+ field: "branchId",
774
+ operator: "=",
775
+ value: e.id
776
+ }, {
777
+ field: "createdAt",
778
+ operator: ">=",
779
+ value: t
780
+ }]
781
+ },
782
+ orderBy: [{
783
+ field: "id",
784
+ sort: "desc"
785
+ }]
786
+ });
787
+ }), j(this.#i));
788
+ let i = this.#m.pipe(O((e) => I(e)), k({
789
+ bufferSize: 1,
790
+ refCount: !0
791
+ }));
792
+ this.histories$ = T([i, this.#f]).pipe(O(([e]) => this.#O(e)), k({
793
+ bufferSize: 1,
794
+ refCount: !0
795
+ })), this.count$ = this.histories$.pipe(O((e) => e.length), k({
796
+ bufferSize: 1,
797
+ refCount: !0
798
+ })), this.undoHistories$ = T({
799
+ histories: this.histories$,
800
+ undoSession: this.#x,
801
+ trigger: this.#u
802
+ }).pipe(A(async ({ histories: e, undoSession: t }) => {
803
+ if (t.state === "cleared") return [];
804
+ try {
805
+ let n = await D(this.rxdb.entityManager.getRepository(o).findOne({ where: {
806
+ combinator: "and",
807
+ rules: [{
808
+ field: "activated",
809
+ operator: "=",
810
+ value: !0
811
+ }]
812
+ } }));
813
+ return n ? B(e, R(await X(await D(this.rxdb.localAdapter$)).find({ where: {
814
+ combinator: "and",
815
+ rules: [{
816
+ field: "branchId",
817
+ operator: "=",
818
+ value: n.id
819
+ }]
820
+ } }), this.rxdb.versionManager.pushInFlight.snapshot()), t.boundary.changeId, t.boundary.createdAfter) : [];
821
+ } catch (e) {
822
+ let t = e instanceof Error ? e : Error(String(e));
823
+ return this.errors$.next(t), [];
824
+ }
825
+ }), k({
826
+ bufferSize: 1,
827
+ refCount: !0
828
+ })), this.redoHistories$ = this.redoStack.items$, this.undoCount$ = this.undoHistories$.pipe(O((e) => e.length), k({
829
+ bufferSize: 1,
830
+ refCount: !0
831
+ })), this.redoCount$ = this.redoHistories$.pipe(O((e) => e.length), k({
832
+ bufferSize: 1,
833
+ refCount: !0
834
+ })), this.pushableCount$ = this.#c.asObservable(), this.pullableCount$ = this.#o.asObservable();
835
+ let c = T({
836
+ connected: this.rxdb.connected$,
837
+ branch: r
838
+ }).pipe(E(({ connected: e, branch: t }) => e && !!t), A(({ branch: e }) => {
839
+ let t = [
840
+ {
841
+ field: "branchId",
842
+ operator: "=",
843
+ value: e.id
844
+ },
845
+ {
846
+ field: "revertChangeId",
847
+ operator: "=",
848
+ value: null
849
+ },
850
+ {
851
+ field: "remoteId",
852
+ operator: "=",
853
+ value: null
854
+ },
855
+ {
856
+ field: "rejectedAt",
857
+ operator: "=",
858
+ value: null
859
+ }
860
+ ];
861
+ return n.count({ where: {
862
+ combinator: "and",
863
+ rules: t
864
+ } }).pipe(fe((e) => (this.#T("pushableCount 的变更计数查询", e), se)));
865
+ })).subscribe({
866
+ next: () => {
867
+ this.#L();
868
+ },
869
+ error: (e) => this.#T("pushableCount 重算的活跃分支流已中断", e)
870
+ });
871
+ this.#e.push(c), this.rxdb.addEventListener(a, this.#F), this.#L();
872
+ }
873
+ destroy() {
874
+ this.#t = !0, this.#i.next(), this.#i.complete();
875
+ for (let e of this.#e) e.unsubscribe();
876
+ this.#e.length = 0, this.rxdb.removeEventListener(a, this.#F), this.#d.clear(), this.errors$.complete();
877
+ }
878
+ incrementPullableCount(e) {
879
+ this.#s++;
880
+ let t = this.#o.value + e;
881
+ this.#o.next(t);
882
+ }
883
+ resetPullableCount() {
884
+ this.#s++, this.#o.next(0);
885
+ }
886
+ beginPullableSettlement() {
887
+ return this.#s;
888
+ }
889
+ reconcilePullableCount(e, t) {
890
+ let n = e === this.#s ? t : Math.max(this.#o.value, t);
891
+ this.#o.next(n);
892
+ }
893
+ settlePullableCount(e, t) {
894
+ this.#o.next(ye(this.#o.value, {
895
+ complete: t.complete,
896
+ concurrent: e !== this.#s,
897
+ pulled: t.pulled
898
+ }));
899
+ }
900
+ pushToRedoStack(e) {
901
+ this.redoStack.push(e);
902
+ }
903
+ removeFromRedoStack(e) {
904
+ return this.redoStack.remove(e);
905
+ }
906
+ clearRedoStack() {
907
+ this.redoStack.clear();
908
+ }
909
+ setUndoBranch(e) {
910
+ this.#E(e);
911
+ }
912
+ clearUndoHistory() {
913
+ this.#w({
914
+ generation: this.#C(),
915
+ state: "cleared",
916
+ boundary: this.#x.value.boundary,
917
+ clearedAt: /* @__PURE__ */ new Date()
918
+ }), this.clearRedoStack();
919
+ }
920
+ clearAllUndoHistory() {
921
+ let e = /* @__PURE__ */ new Date(), t = (t) => ({
922
+ generation: this.#C(),
923
+ state: "cleared",
924
+ boundary: t.boundary,
925
+ clearedAt: e
926
+ });
927
+ for (let [e, n] of this.#_) this.#_.set(e, t(n));
928
+ this.#v = t(this.#v ?? {
929
+ generation: 0,
930
+ state: "active",
931
+ boundary: V
932
+ });
933
+ let n = this.#b === null ? void 0 : this.#_.get(this.#b);
934
+ this.#x.next(n ?? this.#v), this.clearRedoStack();
935
+ }
936
+ resetSyncCleared(e = [], t) {
937
+ let n = this.#x.value;
938
+ if (n.state === "active") return;
939
+ let r = e.filter((e) => Number.isSafeInteger(e) && e > 0);
940
+ if (t === void 0) {
941
+ if (r.length === 0) return;
942
+ let e = Z(r);
943
+ this.#w({
944
+ generation: n.generation,
945
+ state: "active",
946
+ boundary: {
947
+ changeId: Math.max(n.boundary.changeId, e - 1),
948
+ createdAfter: n.boundary.createdAfter
949
+ }
950
+ });
951
+ return;
952
+ }
953
+ if (!(t.generation === null ? t.recordAt !== null && Number.isFinite(t.recordAt.getTime()) && t.recordAt.getTime() > n.clearedAt.getTime() : t.generation === n.generation)) return;
954
+ let i = r.length > 0 ? Z(r) : null, a = i === null && (n.boundary.createdAfter === null || n.boundary.createdAfter.getTime() < n.clearedAt.getTime()) ? n.clearedAt : n.boundary.createdAfter;
955
+ this.#w({
956
+ generation: n.generation,
957
+ state: "active",
958
+ boundary: {
959
+ changeId: i === null ? n.boundary.changeId : Math.max(n.boundary.changeId, i - 1),
960
+ createdAfter: a
961
+ }
962
+ });
963
+ }
964
+ isExecutingUndoRedo() {
965
+ return this.isUndoRedoInProgress || this.isInvalidatingRedo || this.syncDepth > 0;
966
+ }
967
+ async syncing(e) {
968
+ this.syncDepth += 1;
969
+ try {
970
+ return await e();
971
+ } finally {
972
+ --this.syncDepth;
973
+ }
974
+ }
975
+ async invalidateRedoStack(e) {
976
+ return this.#j(async () => {
977
+ if (!(e?.length && e.every((e) => e <= this.#p))) {
978
+ this.isInvalidatingRedo = !0;
979
+ try {
980
+ let e = await D(this.redoHistories$);
981
+ if (e.length === 0) return;
982
+ let t = e.flatMap((e) => e.changes), n = /* @__PURE__ */ new Date(), r = J([], !1), { adapter: i } = await this.rxdb.versionManager.getLocalRepositories();
983
+ t.forEach((e) => {
984
+ let t = `rxdb:RxDBChange:${e.id}`;
985
+ r.updates.set(t, {
986
+ patch: { redoInvalidatedAt: n },
987
+ inversePatch: { redoInvalidatedAt: null }
988
+ });
989
+ }), y(i, {
990
+ file: "HistoryManager.ts",
991
+ symbol: "invalidateRedoStack",
992
+ intent: v.redo_invalidation
993
+ }), await i.switchBranch({
994
+ actions: r,
995
+ prepare: d
996
+ }), this.clearRedoStack();
997
+ } catch (e) {
998
+ throw console.error("[HistoryManager] Failed to invalidate redo stack:", e), e;
999
+ } finally {
1000
+ this.isInvalidatingRedo = !1;
1001
+ }
1002
+ }
1003
+ });
1004
+ }
1005
+ history(e) {
1006
+ return _e(this.#n, e);
1007
+ }
1008
+ #S(e, t, n) {
1009
+ let { crossScope: r, selected: i } = we(e, t, n);
1010
+ if (r.length > 0) throw new U(t, r);
1011
+ return i;
1012
+ }
1013
+ #C() {
1014
+ return ++this.#y;
1015
+ }
1016
+ #w(e) {
1017
+ this.#b !== null && this.#_.set(this.#b, e), this.#x.next(e);
1018
+ }
1019
+ #T(e, t) {
1020
+ this.#t || C(t) || (console.error(`[HistoryManager] ${e}:`, t), this.errors$.next(t instanceof Error ? t : Error(String(t))));
1021
+ }
1022
+ #E(e) {
1023
+ if (e === this.#b || (this.#b === null && e !== null && !this.#_.has(e) && this.#_.set(e, this.#x.value), this.#b = e, e === null)) return;
1024
+ let t = this.#_.get(e) ?? this.#D();
1025
+ this.#_.set(e, t), this.#x.next(t);
1026
+ }
1027
+ #D() {
1028
+ let e = this.#C(), t = this.#v;
1029
+ return t === null ? {
1030
+ generation: e,
1031
+ state: "active",
1032
+ boundary: V
1033
+ } : {
1034
+ ...t,
1035
+ generation: e
1036
+ };
1037
+ }
1038
+ #O(e) {
1039
+ return e.map((e) => {
1040
+ let t = !1;
1041
+ for (let n of e.changes) {
1042
+ let e = {
1043
+ reverted: n.revertChangeId != null,
1044
+ updatedAt: n.updatedAt.getTime()
1045
+ }, r = this.#d.get(n.id), i = r && r.updatedAt >= e.updatedAt ? r : e;
1046
+ r && e.updatedAt > r.updatedAt && this.#d.set(n.id, e), t ||= i.reverted;
1047
+ }
1048
+ return t === e.reverted ? e : {
1049
+ ...e,
1050
+ reverted: t
1051
+ };
1052
+ });
1053
+ }
1054
+ #k(e) {
1055
+ let t = Date.now();
1056
+ for (let n of e) {
1057
+ let e = this.#d.get(n.id)?.updatedAt ?? 0;
1058
+ t = Math.max(t, n.updatedAt.getTime() + 1, e + 1);
1059
+ }
1060
+ return new Date(t);
1061
+ }
1062
+ #A(e, t, n) {
1063
+ for (let r of e) this.#d.set(r.id, {
1064
+ reverted: t,
1065
+ updatedAt: n.getTime()
1066
+ });
1067
+ this.#f.next(this.#f.value + 1);
1068
+ }
1069
+ #j(e) {
1070
+ let t = this.#a.then(e, e);
1071
+ return this.#a = t.catch(() => void 0), t;
1072
+ }
1073
+ #M() {
1074
+ return this.#h ||= this.rxdb.firstConnectedAt ?? this.#g, this.#h;
1075
+ }
1076
+ #N(e) {
1077
+ return this.#x.value === e;
1078
+ }
1079
+ async #P(e) {
1080
+ return Ae(this.#r, e);
1081
+ }
1082
+ #F = () => {
1083
+ this.#L(), this.#u.next(Date.now());
1084
+ };
1085
+ async #I(e, t, n) {
1086
+ return je(this.#r, e, t, n);
1087
+ }
1088
+ async #L() {
1089
+ return Me(this.#r);
1090
+ }
1091
+ #R() {
1092
+ let e = this;
1093
+ return {
1094
+ get history_cache() {
1095
+ return e.history_cache;
1096
+ },
1097
+ get history_ref_counts() {
1098
+ return e.history_ref_counts;
1099
+ },
1100
+ get histories$() {
1101
+ return e.histories$;
1102
+ },
1103
+ get undoHistories$() {
1104
+ return e.undoHistories$;
1105
+ },
1106
+ get redoHistories$() {
1107
+ return e.redoHistories$;
1108
+ },
1109
+ get undoSession$() {
1110
+ return e.#x;
1111
+ },
1112
+ runSerialized: (t) => e.#j(t),
1113
+ fetchLatestHistories: (t) => e.#P(t),
1114
+ isUndoSessionCurrent: (t) => e.#N(t),
1115
+ selectWholeTransactions: (t, n, r) => e.#S(t, n, r),
1116
+ applyUndoRedoHistories: (t, n, r) => e.#I(t, n, r)
1117
+ };
1118
+ }
1119
+ #z() {
1120
+ let e = this;
1121
+ return {
1122
+ get rxdb() {
1123
+ return e.rxdb;
1124
+ },
1125
+ get destroyed() {
1126
+ return e.#t;
1127
+ },
1128
+ get isUndoRedoInProgress() {
1129
+ return e.isUndoRedoInProgress;
1130
+ },
1131
+ set isUndoRedoInProgress(t) {
1132
+ e.isUndoRedoInProgress = t;
1133
+ },
1134
+ get redoInvalidationFloor() {
1135
+ return e.#p;
1136
+ },
1137
+ set redoInvalidationFloor(t) {
1138
+ e.#p = t;
1139
+ },
1140
+ get pushableGeneration() {
1141
+ return e.#l;
1142
+ },
1143
+ set pushableGeneration(t) {
1144
+ e.#l = t;
1145
+ },
1146
+ get pushableCount$() {
1147
+ return e.#c;
1148
+ },
1149
+ get pushableCountTrigger$() {
1150
+ return e.#u;
1151
+ },
1152
+ get errors$() {
1153
+ return e.errors$;
1154
+ },
1155
+ getFirstConnectedAt: () => e.#M(),
1156
+ isUndoSessionCurrent: (t) => e.#N(t),
1157
+ getNextRevertStateUpdatedAt: (t) => e.#k(t),
1158
+ setRevertStateWatermarks: (t, n, r) => e.#A(t, n, r),
1159
+ pushToRedoStack: (t) => e.pushToRedoStack(t),
1160
+ removeFromRedoStack: (t) => e.removeFromRedoStack(t)
1161
+ };
1162
+ }
1163
+ }, Pe = async (e, n) => {
1164
+ let { adapter: r } = await e.getLocalRepositories();
1165
+ if (n === t) throw new c("Cannot remove main branch");
1166
+ let i = await r.transaction(async (t) => {
1167
+ let r = t.getRepository(o), i = t.getRepository(s), a = (await r.find({
1168
+ where: {
1169
+ combinator: "and",
1170
+ rules: [{
1171
+ field: "id",
1172
+ operator: "=",
1173
+ value: n
1174
+ }]
1175
+ },
1176
+ limit: 1
1177
+ }))[0];
1178
+ if (!a) return `Branch '${n}' not found`;
1179
+ if (a.activated) return `Cannot remove active branch '${n}'. Switch to another branch first.`;
1180
+ if ((await r.find({
1181
+ where: {
1182
+ combinator: "and",
1183
+ rules: [{
1184
+ field: "parentId",
1185
+ operator: "=",
1186
+ value: n
1187
+ }, {
1188
+ field: "id",
1189
+ operator: "!=",
1190
+ value: n
1191
+ }]
1192
+ },
1193
+ limit: 1
1194
+ }))?.length) return `Cannot remove branch '${n}' because it has child branches`;
1195
+ let c = await i.find({ where: {
1196
+ combinator: "and",
1197
+ rules: [{
1198
+ field: "branchId",
1199
+ operator: "=",
1200
+ value: n
1201
+ }]
1202
+ } });
1203
+ for (let r of e.rxdb.systemContributions) await r.removeBranchRows({
1204
+ executor: t,
1205
+ branchId: n
1206
+ });
1207
+ await t.removeMany([...c, a]);
1208
+ });
1209
+ if (i) throw new c(i);
1210
+ }, Fe = async (e, t, n, r) => {
1211
+ let i = r?.strategy ?? "squash", a = r?.deleteSource ?? !1, { branchRepository: o, changeRepository: s, adapter: l } = await e.getLocalRepositories();
1212
+ if (t === n) throw new c(`Cannot merge branch '${t}' into itself`);
1213
+ let u = (await o.find({
1214
+ where: {
1215
+ combinator: "and",
1216
+ rules: [{
1217
+ field: "id",
1218
+ operator: "=",
1219
+ value: t
1220
+ }]
1221
+ },
1222
+ limit: 1
1223
+ }))[0];
1224
+ if (!u) throw new c(`Branch '${t}' not found`);
1225
+ let d = await s.find({
1226
+ where: {
1227
+ combinator: "and",
1228
+ rules: [
1229
+ {
1230
+ field: "branchId",
1231
+ operator: "=",
1232
+ value: t
1233
+ },
1234
+ {
1235
+ field: "revertChangeId",
1236
+ operator: "=",
1237
+ value: null
1238
+ },
1239
+ ...u.fromChangeId == null ? [] : [{
1240
+ field: "id",
1241
+ operator: ">",
1242
+ value: u.fromChangeId
1243
+ }]
1244
+ ]
1245
+ },
1246
+ orderBy: [{
1247
+ field: "id",
1248
+ sort: "asc"
1249
+ }]
1250
+ }), f = async () => {
1251
+ if (!a) return { deleted: !1 };
1252
+ try {
1253
+ return await Pe(e, t), { deleted: !0 };
1254
+ } catch (e) {
1255
+ return {
1256
+ deleted: !1,
1257
+ error: e instanceof Error ? e : Error(String(e))
1258
+ };
1259
+ }
1260
+ }, p = (e, t) => ({
1261
+ merged: e,
1262
+ strategy: i,
1263
+ sourceDeleted: t.deleted,
1264
+ ...t.error ? { sourceDeleteError: t.error } : {}
1265
+ });
1266
+ if (d.length === 0) return p(0, await f());
1267
+ let m;
1268
+ if (i === "normal") await l.transaction(async (e) => {
1269
+ for (let t of d) {
1270
+ let n = {
1271
+ deletes: /* @__PURE__ */ new Map(),
1272
+ updates: /* @__PURE__ */ new Map(),
1273
+ inserts: /* @__PURE__ */ new Map()
1274
+ }, r = x(t);
1275
+ t.type === "INSERT" ? n.inserts.set(r, {
1276
+ patch: t.patch,
1277
+ inversePatch: null
1278
+ }) : t.type === "UPDATE" ? n.updates.set(r, {
1279
+ patch: t.patch,
1280
+ inversePatch: t.inversePatch
1281
+ }) : t.type === "DELETE" && n.deletes.set(r, {
1282
+ patch: null,
1283
+ inversePatch: t.inversePatch
1284
+ }), y(e, {
1285
+ file: "merge-branch.ts",
1286
+ symbol: "merge_branch",
1287
+ intent: v.merge_per_change
1288
+ }), await e.mergeChanges(n, void 0, !1);
1289
+ }
1290
+ }), m = d.length;
1291
+ else {
1292
+ let e = J(d, !0), t = new Set(d.filter((e) => e.type === "INSERT").map((e) => x(e)));
1293
+ for (let n of t) e.deletes.has(n) && e.deletes.delete(n);
1294
+ if (m = e.inserts.size + e.updates.size + e.deletes.size, m === 0) return p(0, await f());
1295
+ await l.transaction(async (t) => {
1296
+ y(t, {
1297
+ file: "merge-branch.ts",
1298
+ symbol: "merge_branch",
1299
+ intent: v.merge_squash
1300
+ }), await t.mergeChanges(e, void 0, !1);
1301
+ }, !1);
1302
+ }
1303
+ return p(m, await f());
1304
+ }, Q = class {
1305
+ #e = /* @__PURE__ */ new Map();
1306
+ #t = 0;
1307
+ session() {
1308
+ let e = ++this.#t, t = /* @__PURE__ */ new Map();
1309
+ return this.#e.set(e, t), {
1310
+ claim: (e, n) => {
1311
+ let r = t.get(e);
1312
+ r !== void 0 && r >= n || t.set(e, n);
1313
+ },
1314
+ release: () => {
1315
+ this.#e.delete(e);
1316
+ }
1317
+ };
1318
+ }
1319
+ snapshot() {
1320
+ let e = /* @__PURE__ */ new Map();
1321
+ for (let t of this.#e.values()) for (let [n, r] of t) {
1322
+ let t = e.get(n);
1323
+ t !== void 0 && t >= r || e.set(n, r);
1324
+ }
1325
+ return e;
1326
+ }
1327
+ };
1328
+ //#endregion
1329
+ //#region src/restore-entity.ts
1330
+ async function Ie(e, t, n) {
1331
+ let { changeRepository: r, adapter: i } = await e.getLocalRepositories(), a = await r.find({
1332
+ where: {
1333
+ combinator: "and",
1334
+ rules: [{
1335
+ field: "id",
1336
+ operator: "=",
1337
+ value: Number(n.changeId)
1338
+ }]
1339
+ },
1340
+ limit: 1
1341
+ });
1342
+ if (a.length === 0) throw new c(`RxDBChange not found: ${n.changeId}`);
1343
+ let o = a[0];
1344
+ if (o.type !== "DELETE") throw new c(`Cannot restore from non-DELETE change (type=${o.type})`);
1345
+ if (!o.inversePatch) throw new c(`RxDBChange ${n.changeId} has no inversePatch`);
1346
+ let s = t.constructor, l = b(s), u = await e.getCurrentBranch();
1347
+ if (o.namespace !== l.namespace || o.entity !== l.name) throw new c(`RxDBChange ${n.changeId} belongs to ${o.namespace}:${o.entity}, not ${l.namespace}:${l.name}`);
1348
+ if (o.branchId != null && o.branchId !== u.id) throw new c(`RxDBChange ${n.changeId} belongs to branch '${o.branchId}', current branch is '${u.id}'`);
1349
+ let d = J([o], !1);
1350
+ await i.transaction(async (e) => {
1351
+ y(e, {
1352
+ file: "restore-entity.ts",
1353
+ symbol: "restore_entity",
1354
+ intent: v.restore_entity
1355
+ }), await e.mergeChanges(d, void 0, !1);
1356
+ }, !1);
1357
+ let f = await i.getRepository(s).find({
1358
+ where: {
1359
+ combinator: "and",
1360
+ rules: [{
1361
+ field: "id",
1362
+ operator: "=",
1363
+ value: o.entityId
1364
+ }]
1365
+ },
1366
+ limit: 1
1367
+ });
1368
+ if (!f[0]) throw new c(`Restore produced no row for ${l.namespace}:${l.name} id=${String(o.entityId)}`);
1369
+ return f[0];
1370
+ }
1371
+ //#endregion
1372
+ //#region src/sync-history-bridge.ts
1373
+ var Le = (e, t) => ({
1374
+ pushInFlight: t,
1375
+ syncing: (t) => e().syncing(t),
1376
+ clearUndoHistory: () => e().clearUndoHistory(),
1377
+ beginPullableSettlement: () => e().beginPullableSettlement(),
1378
+ settlePull: (t, n, r) => e().settlePullableCount(t, {
1379
+ complete: ve(n, r),
1380
+ pulled: r.pulled
1381
+ }),
1382
+ settleAbortedPull: (t, n) => e().settlePullableCount(t, {
1383
+ complete: !1,
1384
+ pulled: n
1385
+ }),
1386
+ reconcilePullableCount: (t, n) => e().reconcilePullableCount(t, n),
1387
+ incrementPullableCount: (t) => e().incrementPullableCount(t)
1388
+ }), Re = (e) => typeof e == "number" && Number.isSafeInteger(e) && e > 0 ? e : null, ze = (e) => {
1389
+ let t = Re(e.id);
1390
+ return t === null ? typeof e.patch != "object" || e.patch === null || !("id" in e.patch) ? null : Re(e.patch.id) : t;
1391
+ }, Be = (e) => {
1392
+ let t = null;
1393
+ for (let n of e) n.recordAt instanceof Date && Number.isFinite(n.recordAt.getTime()) && (t === null || n.recordAt.getTime() < t.getTime()) && (t = n.recordAt);
1394
+ return t;
1395
+ }, Ve = class {
1396
+ rxdb;
1397
+ #e = [];
1398
+ #t = 0;
1399
+ #n = null;
1400
+ #r = !1;
1401
+ #i = !1;
1402
+ historyManager;
1403
+ pushInFlight = new Q();
1404
+ syncBridge = Le(() => this.historyManager, this.pushInFlight);
1405
+ get pushableCount$() {
1406
+ return this.historyManager.pushableCount$;
1407
+ }
1408
+ get pullableCount$() {
1409
+ return this.historyManager.pullableCount$;
1410
+ }
1411
+ constructor(e) {
1412
+ this.rxdb = e, this.historyManager = new Ne(this.rxdb);
1413
+ }
1414
+ init() {
1415
+ this.#i &&= (this.historyManager = new Ne(this.rxdb), !1);
1416
+ let t = () => {
1417
+ if (!this.#r) {
1418
+ this.#r = !0;
1419
+ let e = () => {
1420
+ if (this.#t > 1) {
1421
+ --this.#t;
1422
+ return;
1423
+ }
1424
+ this.#t = 0, this.#n = null;
1425
+ }, t = () => {
1426
+ this.#t = 0, this.#n = null;
1427
+ };
1428
+ this.rxdb.addEventListener(g, e), this.rxdb.addEventListener(_, t), this.#e.push(() => this.rxdb.removeEventListener(g, e), () => this.rxdb.removeEventListener(_, t));
1429
+ }
1430
+ this.#t === 0 && (this.#n = this.historyManager.undoSessionGeneration), this.#t += 1;
1431
+ };
1432
+ this.rxdb.addEventListener(h, t), this.#e.push(() => this.rxdb.removeEventListener(h, t));
1433
+ let n = (e) => {
1434
+ let t = e.entities?.filter((e) => e.namespace === "rxdb" && e.entity === "RxDBChange") ?? [];
1435
+ if (t.length > 0 && !this.historyManager.isExecutingUndoRedo()) {
1436
+ let e = t.flatMap((e) => {
1437
+ let t = ze(e);
1438
+ return t === null ? [] : [t];
1439
+ });
1440
+ this.#l(this.historyManager.invalidateRedoStack(e), "invalidateRedoStack");
1441
+ let n = Be(t);
1442
+ this.#n !== null || n !== null ? this.historyManager.resetSyncCleared(e, {
1443
+ generation: this.#n,
1444
+ recordAt: n
1445
+ }) : this.historyManager.resetSyncCleared(e);
1446
+ }
1447
+ };
1448
+ this.rxdb.addEventListener(e, n), this.#e.push(() => this.rxdb.removeEventListener(e, n));
1449
+ }
1450
+ destroy() {
1451
+ if (!this.#i) {
1452
+ this.#i = !0, this.historyManager.destroy();
1453
+ for (let e of this.#e) e();
1454
+ this.#e.length = 0, this.#t = 0, this.#n = null, this.#r = !1;
1455
+ }
1456
+ }
1457
+ resetSessionState() {
1458
+ this.historyManager.clearAllUndoHistory(), this.historyManager.resetPullableCount();
1459
+ }
1460
+ async createBranch(e, t) {
1461
+ return pe(this, e, t);
1462
+ }
1463
+ async removeBranch(e) {
1464
+ return Pe(this, e);
1465
+ }
1466
+ async switchBranch(e, t) {
1467
+ let n = await this.getCurrentBranch();
1468
+ if (n?.id === e) return;
1469
+ let r = !1, i, a = !1;
1470
+ try {
1471
+ if (this.rxdb.dispatchEvent(new f(e)), await this.#o(n?.id ?? null, e, t)) {
1472
+ r = !0, this.#a(e);
1473
+ return;
1474
+ }
1475
+ let { adapter: o } = await this.getLocalRepositories(), s = await De(this, e);
1476
+ y(o, {
1477
+ file: "VersionManager.ts",
1478
+ symbol: "switchBranch",
1479
+ intent: v.branch_materialization
1480
+ }), i = o;
1481
+ let l = await o.switchBranch({
1482
+ branchId: e,
1483
+ actions: s,
1484
+ prepare: async ({ executor: e, targetBranchId: r }) => {
1485
+ a = !0, await this.#c(e, n?.id ?? null, r, t);
1486
+ }
1487
+ });
1488
+ if (r = !0, this.#a(e), !a) throw new c(`适配器 ${o.constructor.name} 的 switchBranch 没有调用 options.prepare:分支已经切到 ${e},但这次切换一条前置条件都没校验过。适配器必须在解析出目标分支之后、动第一行之前 await 它(见 rxdb-adapter.ts › SwitchBranchOptions.prepare)。`);
1489
+ return l;
1490
+ } catch (t) {
1491
+ throw i && oe(i), r || (this.rxdb.dispatchEvent(new m(e)), await this.#s(n?.id ?? null, e, t)), t;
1492
+ }
1493
+ }
1494
+ async mergeBranch(e, t) {
1495
+ let a = await this.getCurrentBranch();
1496
+ if (!a) throw new c("No active branch found");
1497
+ let o = a.id;
1498
+ try {
1499
+ this.rxdb.dispatchEvent(new n(e, o));
1500
+ let i = await Fe(this, e, o, t);
1501
+ return i.merged > 0 && this.historyManager.clearUndoHistory(), this.rxdb.dispatchEvent(new r(e, o)), i;
1502
+ } catch (t) {
1503
+ throw this.rxdb.dispatchEvent(new i(e, o)), t;
1504
+ }
1505
+ }
1506
+ history(e) {
1507
+ return this.historyManager.history(e);
1508
+ }
1509
+ async restoreEntity(e, t) {
1510
+ return Ie(this, e, t);
1511
+ }
1512
+ async getLocalRepositories() {
1513
+ return re(this.rxdb);
1514
+ }
1515
+ async getRemoteRepositories() {
1516
+ return ie(this.rxdb);
1517
+ }
1518
+ async getCurrentBranch() {
1519
+ return ne(this.rxdb);
1520
+ }
1521
+ #a(e) {
1522
+ this.historyManager.clearRedoStack(), this.historyManager.setUndoBranch(e), this.rxdb.dispatchEvent(new p(e));
1523
+ }
1524
+ async #o(e, t, n) {
1525
+ for (let r of this.rxdb.systemContributions) if (await r.takeOverBranchSwitch({
1526
+ currentBranchId: e,
1527
+ targetBranchId: t,
1528
+ preconditions: n
1529
+ }) === "switched") return !0;
1530
+ return !1;
1531
+ }
1532
+ async #s(e, t, n) {
1533
+ for (let r of this.rxdb.systemContributions) await r.settleBranchSwitchFailure({
1534
+ currentBranchId: e,
1535
+ targetBranchId: t,
1536
+ error: n
1537
+ });
1538
+ }
1539
+ async #c(e, t, n, r) {
1540
+ for (let i of this.rxdb.systemContributions) await i.prepareBranchSwitch({
1541
+ executor: e,
1542
+ currentBranchId: t,
1543
+ targetBranchId: n,
1544
+ preconditions: r
1545
+ });
1546
+ }
1547
+ #l(e, t) {
1548
+ e.catch((e) => {
1549
+ N(e) || console.error(`[VersionManager] ${t} failed:`, e);
1550
+ });
1551
+ }
1552
+ }, $ = class extends l {
1553
+ lifecycle = "scoped";
1554
+ name = "history";
1555
+ install(e) {
1556
+ let t = new Ve(this.rxdb);
1557
+ e.acquire(() => (Object.defineProperty(this.rxdb, "versionManager", {
1558
+ value: t,
1559
+ configurable: !0,
1560
+ enumerable: !0
1561
+ }), () => void Reflect.deleteProperty(this.rxdb, "versionManager")), "history:slot"), e.acquire(() => () => t.destroy(), "history:versionManager"), t.init(), e.acquire(() => this.rxdb.syncState.bindPushableCount(t.pushableCount$), "history:pushableCount");
1562
+ }
1563
+ }, He = (e) => new $(e);
1564
+ //#endregion
1565
+ export { Q as PushInFlightRegistry, U as RxDBCrossScopeTransactionError, $ as RxDBPluginHistory, q as compute_switch_branch_actions, G as find_branch_path_to_root, K as find_switch_branch_step, Y as get_branch_max_change, N as isIgnorableDetachedVersionEventError, He as rxDBPluginHistory };