@quereus/sync 3.3.0 → 4.1.0

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 (92) hide show
  1. package/README.md +17 -7
  2. package/dist/src/clock/hlc.d.ts +43 -3
  3. package/dist/src/clock/hlc.d.ts.map +1 -1
  4. package/dist/src/clock/hlc.js +60 -10
  5. package/dist/src/clock/hlc.js.map +1 -1
  6. package/dist/src/create-sync-module.d.ts +46 -9
  7. package/dist/src/create-sync-module.d.ts.map +1 -1
  8. package/dist/src/create-sync-module.js +11 -8
  9. package/dist/src/create-sync-module.js.map +1 -1
  10. package/dist/src/index.d.ts +10 -8
  11. package/dist/src/index.d.ts.map +1 -1
  12. package/dist/src/index.js +8 -5
  13. package/dist/src/index.js.map +1 -1
  14. package/dist/src/metadata/basis-lifecycle.d.ts +180 -0
  15. package/dist/src/metadata/basis-lifecycle.d.ts.map +1 -0
  16. package/dist/src/metadata/basis-lifecycle.js +211 -0
  17. package/dist/src/metadata/basis-lifecycle.js.map +1 -0
  18. package/dist/src/metadata/change-log.d.ts +1 -1
  19. package/dist/src/metadata/change-log.d.ts.map +1 -1
  20. package/dist/src/metadata/change-log.js +6 -6
  21. package/dist/src/metadata/change-log.js.map +1 -1
  22. package/dist/src/metadata/column-version.d.ts +14 -5
  23. package/dist/src/metadata/column-version.d.ts.map +1 -1
  24. package/dist/src/metadata/column-version.js +22 -12
  25. package/dist/src/metadata/column-version.js.map +1 -1
  26. package/dist/src/metadata/index.d.ts +2 -0
  27. package/dist/src/metadata/index.d.ts.map +1 -1
  28. package/dist/src/metadata/index.js +2 -0
  29. package/dist/src/metadata/index.js.map +1 -1
  30. package/dist/src/metadata/keys.d.ts +52 -2
  31. package/dist/src/metadata/keys.d.ts.map +1 -1
  32. package/dist/src/metadata/keys.js +99 -14
  33. package/dist/src/metadata/keys.js.map +1 -1
  34. package/dist/src/metadata/peer-state.d.ts +1 -1
  35. package/dist/src/metadata/peer-state.js +5 -5
  36. package/dist/src/metadata/quarantine.d.ts +90 -0
  37. package/dist/src/metadata/quarantine.d.ts.map +1 -0
  38. package/dist/src/metadata/quarantine.js +167 -0
  39. package/dist/src/metadata/quarantine.js.map +1 -0
  40. package/dist/src/metadata/schema-migration.d.ts +1 -1
  41. package/dist/src/metadata/schema-migration.js +7 -7
  42. package/dist/src/metadata/schema-version.d.ts +1 -1
  43. package/dist/src/metadata/schema-version.js +7 -7
  44. package/dist/src/metadata/tombstones.d.ts +26 -9
  45. package/dist/src/metadata/tombstones.d.ts.map +1 -1
  46. package/dist/src/metadata/tombstones.js +42 -19
  47. package/dist/src/metadata/tombstones.js.map +1 -1
  48. package/dist/src/sql/basis-lifecycle-tvf.d.ts +34 -0
  49. package/dist/src/sql/basis-lifecycle-tvf.d.ts.map +1 -0
  50. package/dist/src/sql/basis-lifecycle-tvf.js +101 -0
  51. package/dist/src/sql/basis-lifecycle-tvf.js.map +1 -0
  52. package/dist/src/sync/admission.d.ts +81 -0
  53. package/dist/src/sync/admission.d.ts.map +1 -0
  54. package/dist/src/sync/admission.js +94 -0
  55. package/dist/src/sync/admission.js.map +1 -0
  56. package/dist/src/sync/change-applicator.d.ts +65 -2
  57. package/dist/src/sync/change-applicator.d.ts.map +1 -1
  58. package/dist/src/sync/change-applicator.js +493 -68
  59. package/dist/src/sync/change-applicator.js.map +1 -1
  60. package/dist/src/sync/change-grouping.d.ts +43 -0
  61. package/dist/src/sync/change-grouping.d.ts.map +1 -0
  62. package/dist/src/sync/change-grouping.js +103 -0
  63. package/dist/src/sync/change-grouping.js.map +1 -0
  64. package/dist/src/sync/events.d.ts +159 -1
  65. package/dist/src/sync/events.d.ts.map +1 -1
  66. package/dist/src/sync/events.js +50 -0
  67. package/dist/src/sync/events.js.map +1 -1
  68. package/dist/src/sync/manager.d.ts +87 -0
  69. package/dist/src/sync/manager.d.ts.map +1 -1
  70. package/dist/src/sync/protocol.d.ts +174 -11
  71. package/dist/src/sync/protocol.d.ts.map +1 -1
  72. package/dist/src/sync/protocol.js +4 -1
  73. package/dist/src/sync/protocol.js.map +1 -1
  74. package/dist/src/sync/snapshot-stream.d.ts.map +1 -1
  75. package/dist/src/sync/snapshot-stream.js +89 -19
  76. package/dist/src/sync/snapshot-stream.js.map +1 -1
  77. package/dist/src/sync/snapshot.d.ts.map +1 -1
  78. package/dist/src/sync/snapshot.js +63 -44
  79. package/dist/src/sync/snapshot.js.map +1 -1
  80. package/dist/src/sync/store-adapter.d.ts +117 -15
  81. package/dist/src/sync/store-adapter.d.ts.map +1 -1
  82. package/dist/src/sync/store-adapter.js +247 -91
  83. package/dist/src/sync/store-adapter.js.map +1 -1
  84. package/dist/src/sync/sync-context.d.ts +44 -1
  85. package/dist/src/sync/sync-context.d.ts.map +1 -1
  86. package/dist/src/sync/sync-context.js +26 -0
  87. package/dist/src/sync/sync-context.js.map +1 -1
  88. package/dist/src/sync/sync-manager-impl.d.ts +247 -13
  89. package/dist/src/sync/sync-manager-impl.d.ts.map +1 -1
  90. package/dist/src/sync/sync-manager-impl.js +788 -193
  91. package/dist/src/sync/sync-manager-impl.js.map +1 -1
  92. package/package.json +9 -9
@@ -4,18 +4,29 @@
4
4
  * Coordinates CRDT metadata tracking and sync operations.
5
5
  * Delegates to focused sub-modules for snapshot, streaming, and change application.
6
6
  */
7
- import type { KVStore, StoreEventEmitter } from '@quereus/store';
8
- import type { GetTableSchemaCallback } from '../create-sync-module.js';
7
+ import type { KVStore } from '@quereus/store';
8
+ import type { Database, LensDeploymentSnapshot } from '@quereus/quereus';
9
+ import type { GetTableSchemaCallback, TransactionCommitSource } from '../create-sync-module.js';
9
10
  import { HLCManager, type HLC } from '../clock/hlc.js';
10
11
  import { type SiteId } from '../clock/site.js';
11
12
  import { ColumnVersionStore } from '../metadata/column-version.js';
12
13
  import { TombstoneStore } from '../metadata/tombstones.js';
13
14
  import { SchemaMigrationStore } from '../metadata/schema-migration.js';
14
15
  import { ChangeLogStore } from '../metadata/change-log.js';
16
+ import { QuarantineStore } from '../metadata/quarantine.js';
17
+ import { BasisLifecycleStore, type BasisTableLifecycleRecord } from '../metadata/basis-lifecycle.js';
15
18
  import type { SyncManager, SnapshotCheckpoint } from './manager.js';
16
- import type { SyncConfig, ChangeSet, ApplyResult, Snapshot, SnapshotChunk, SnapshotProgress, ApplyToStoreCallback } from './protocol.js';
19
+ import type { SyncConfig, ChangeSet, ApplyResult, Snapshot, SnapshotChunk, SnapshotProgress, ApplyToStoreCallback, DropLocalTableCallback, UnknownTableDisposition } from './protocol.js';
17
20
  import { SyncEventEmitterImpl } from './events.js';
18
21
  import type { SyncContext } from './sync-context.js';
22
+ /**
23
+ * Guard a transaction's running `opSeq` against the uint32 bound. `opSeq` is
24
+ * serialized as a big-endian uint32 in the HLC comparison key, so a fact count
25
+ * exceeding {@link MAX_OPSEQ} would silently wrap and corrupt ordering — throw
26
+ * instead. Practically unreachable (4 billion facts in one transaction); the
27
+ * write side telemeters the throw via an error sync-state event.
28
+ */
29
+ export declare function assertOpSeqInRange(opSeq: number): void;
19
30
  /**
20
31
  * Implementation of SyncManager.
21
32
  *
@@ -31,45 +42,268 @@ export declare class SyncManagerImpl implements SyncManager, SyncContext {
31
42
  private readonly peerStates;
32
43
  readonly changeLog: ChangeLogStore;
33
44
  readonly schemaMigrations: SchemaMigrationStore;
45
+ readonly quarantine: QuarantineStore;
46
+ readonly basisLifecycle: BasisLifecycleStore;
34
47
  readonly syncEvents: SyncEventEmitterImpl;
35
48
  readonly applyToStore?: ApplyToStoreCallback;
36
49
  private readonly getTableSchema?;
37
- private pendingChanges;
38
- private currentTransactionId;
50
+ /** Reclaim-by-name callback for the eviction sweep; absent ⇒ sweep is a no-op. */
51
+ private readonly dropLocalTable?;
52
+ private readonly lastBasisHash;
53
+ private unknownTableIgnored;
54
+ private unknownTableQuarantined;
55
+ private unknownTableForwarded;
56
+ private unknownTableRelayed;
57
+ private readonly unknownTableByTable;
39
58
  private constructor();
40
59
  /**
41
60
  * Create a new SyncManager, initializing or loading site identity.
42
61
  *
43
62
  * @param kv - KV store for sync metadata
44
- * @param storeEvents - Store event emitter to subscribe to local changes
63
+ * @param transactionSource - Engine transaction-commit source for local change
64
+ * capture (a `Database`, or any `onTransactionCommit` emitter). When provided,
65
+ * sync subscribes to `onTransactionCommit` and records CRDT metadata for each
66
+ * committed local transaction — one HLC per transaction. Pass `undefined` for a
67
+ * relay-only deployment (e.g. a coordinator) that captures no local DML.
45
68
  * @param config - Sync configuration
46
69
  * @param syncEvents - Sync event emitter for UI integration
47
70
  * @param applyToStore - Optional callback for applying remote changes to the store
48
71
  * @param getTableSchema - Optional callback for getting table schema by name
72
+ * @param dropLocalTable - Optional reclaim-by-name callback for the basis-table
73
+ * eviction sweep; when absent (e.g. a relay-only coordinator) the sweep is a no-op.
49
74
  */
50
- static create(kv: KVStore, storeEvents: StoreEventEmitter, config: SyncConfig, syncEvents: SyncEventEmitterImpl, applyToStore?: ApplyToStoreCallback, getTableSchema?: GetTableSchemaCallback): Promise<SyncManagerImpl>;
75
+ static create(kv: KVStore, transactionSource: TransactionCommitSource | undefined, config: SyncConfig, syncEvents: SyncEventEmitterImpl, applyToStore?: ApplyToStoreCallback, getTableSchema?: GetTableSchemaCallback, dropLocalTable?: DropLocalTableCallback): Promise<SyncManagerImpl>;
51
76
  getSiteId(): SiteId;
52
77
  getCurrentHLC(): HLC;
53
78
  /**
54
- * Handle a data change event from the store.
55
- * Records CRDT metadata for the change.
79
+ * Basis-membership oracle for unknown-table detection. `getTableSchema(s,t)
80
+ * === undefined` the table is outside the local basis. When no oracle was
81
+ * provided (e.g. a relay-only coordinator), detection is inert: every table
82
+ * reports in-basis and the store adapter's defensive throw governs.
83
+ */
84
+ isTableInBasis(schema: string, table: string): boolean;
85
+ /**
86
+ * Current column names for an in-basis table via the `getTableSchema` oracle, or
87
+ * `undefined` when the table is outside the basis (oracle returns nothing) OR no
88
+ * oracle was wired. Backs the drain path's basis gate + schema-drift filter (see
89
+ * {@link SyncContext.getTableColumnNames}). The no-oracle `undefined` makes drain
90
+ * a clean no-op on a relay-only coordinator, exactly as detection is inert there.
56
91
  */
57
- private handleDataChange;
92
+ getTableColumnNames(schema: string, table: string): readonly string[] | undefined;
58
93
  /**
59
- * Handle a schema change event from the store.
60
- * Records schema migrations for sync.
94
+ * Accumulate unknown-table disposition stats (called by the apply path after a
95
+ * diverted group is successfully admitted).
61
96
  */
62
- private handleSchemaChange;
97
+ recordUnknownTable(disposition: UnknownTableDisposition, schema: string, table: string, changeCount: number): void;
98
+ getUnknownTableStats(): {
99
+ ignored: number;
100
+ quarantined: number;
101
+ forwarded: number;
102
+ relayed: number;
103
+ byTable: Map<string, number>;
104
+ };
105
+ /**
106
+ * Record one logical schema's lens deployment over its basis, recomputing the
107
+ * durable per-basis-table lifecycle classification (`docs/migration.md`
108
+ * § 2 Converge). See {@link SyncManager.recordLensDeployment}.
109
+ *
110
+ * The snapshot is scoped to ONE logical schema, so this schema's directly-mapped
111
+ * contribution is stored per-schema (`mappedBy`) and the aggregate state ORs all
112
+ * schemas — a basis table stays `directly-mapped` until the last mapper drops it.
113
+ * The classification is a pure function of `(snapshot, basis schema)`, both
114
+ * reachable from `db`: the directly-mapped set is the union of every table
115
+ * snapshot's `relationBacking` keys (plus deferred surrogate-split members), and
116
+ * the basis membership / derivation sources come from enumerating the basis
117
+ * schema's tables.
118
+ */
119
+ recordLensDeployment(db: Database, logicalSchemaName: string, snapshot: LensDeploymentSnapshot): Promise<void>;
120
+ getBasisTableLifecycle(): Promise<BasisTableLifecycleRecord[]>;
121
+ /**
122
+ * Reclaim the local storage of every detached basis table that has been quiet
123
+ * past its effective retention horizon (`docs/migration.md` § 4 Contract).
124
+ * Host-driven (like {@link pruneTombstones} / {@link pruneQuarantine}) — the
125
+ * host schedules it; the library adds no timer. Returns the number of tables
126
+ * evicted.
127
+ *
128
+ * No-op when no `dropLocalTable` reclaim callback is wired (e.g. a relay-only
129
+ * coordinator with no store). For each evictable record it re-reads the record
130
+ * and re-checks eligibility immediately before dropping — guarding against a
131
+ * concurrent re-deploy that re-mapped the table between the scan and the drop —
132
+ * then drops the storage, emits `onBasisTableEvicted`, and clears the record. A
133
+ * `dropLocalTable` throw leaves the record in place to retry next sweep (the
134
+ * drop is idempotent).
135
+ */
136
+ evictExpiredBasisTables(now?: number): Promise<number>;
137
+ /**
138
+ * Record CRDT metadata for one committed local transaction.
139
+ *
140
+ * Driven by the engine's `onTransactionCommit` group — the authoritative
141
+ * "one transaction = one HLC" boundary. The clock is ticked exactly **once**;
142
+ * every fact of the transaction shares that base `(wallTime, counter, siteId)`
143
+ * and differs only in `opSeq` (a contiguous, 0-based sub-order). DDL is recorded
144
+ * before DML so migrations sort below the same transaction's data facts
145
+ * (docs/sync.md § DDL Application Order). All metadata for the transaction —
146
+ * schema migrations, column versions, tombstones, change-log entries, and the
147
+ * HLC clock state — lands in a single KV batch.
148
+ */
149
+ private handleTransactionCommit;
150
+ /**
151
+ * Record one local schema-change event as a migration. Allocates an `opSeq`
152
+ * (via `nextHlc`) only when the event maps to a tracked migration, so
153
+ * unsupported object types consume no sub-order. `versionCounters` carries the
154
+ * running per-table schema version across this transaction's migrations.
155
+ */
156
+ private recordSchemaMigration;
157
+ /**
158
+ * Record one local data-change event: a tombstone (delete) or the changed
159
+ * column versions (insert/update). Each recorded fact consumes one `opSeq`.
160
+ */
161
+ private recordDataEvent;
63
162
  private recordColumnVersions;
163
+ /**
164
+ * Extract changes for a peer as **one {@link ChangeSet} per source
165
+ * transaction** (grouped by HLC identity `(wallTime, counter, siteId)`),
166
+ * bounded at transaction granularity by `config.batchSize`. A transaction is
167
+ * never split across ChangeSets and two transactions are never merged, so a
168
+ * consumer that advances `lastSyncHLC = ChangeSet.hlc` always lands on a real
169
+ * commit boundary (docs/sync.md § Transaction-Based Change Grouping → Read side).
170
+ */
64
171
  getChangesSince(peerSiteId: SiteId, sinceHLC?: HLC): Promise<ChangeSet[]>;
172
+ /**
173
+ * Delta extraction: facts after `sinceHLC`, in change-log (HLC) order, bounded
174
+ * at **scan time** to whole transactions whose cumulative data-change count
175
+ * reaches `batchSize`.
176
+ *
177
+ * The change-log scan is keyed by `(wallTime, counter, siteId, opSeq)`, so a
178
+ * transaction's facts arrive contiguously and transactions arrive in commit
179
+ * order. That lets us stop scanning as soon as enough WHOLE transactions have
180
+ * accumulated, instead of draining the entire iterator into memory and letting
181
+ * {@link buildTransactionChangeSets} truncate afterward (the pre-
182
+ * `sync-getchangessince-bounded-extraction` behavior, where `batchSize` capped
183
+ * the response but not the scan). The bound here mirrors that grouping step
184
+ * exactly — whole transactions accumulate until the cumulative data-change count
185
+ * reaches `batchSize`, never splitting a transaction — so the grouped response
186
+ * is byte-identical; only the scan footprint shrinks.
187
+ *
188
+ * LOAD-BEARING INVARIANT: boundary detection keys off `logEntry.hlc`, but the
189
+ * grouper keys off the *resolved* version's HLC ({@link resolveLogEntry} returns
190
+ * `cv.hlc` / `tombstone.hlc`). These agree only when each non-null-resolving log
191
+ * entry's HLC equals its resolved version's HLC, which holds for BOTH entry types
192
+ * because each is deduped on overwrite — at most one entry survives per key, and
193
+ * its HLC equals the current version's:
194
+ * - COLUMN: an overwrite deletes the prior `(pk, column)` entry (see
195
+ * {@link recordColumnVersions} and `commitChangeMetadata`), so the survivor's
196
+ * HLC is the current `cv.hlc`.
197
+ * - DELETE: a newer tombstone deletes the prior `pk` delete entry (see
198
+ * {@link recordDataEvent} and `commitChangeMetadata`), so a
199
+ * delete→reinsert→delete key reuse no longer leaves a stale entry that
200
+ * re-attributes to a later tombstone HLC; the survivor's HLC is the current
201
+ * `tombstone.hlc`.
202
+ *
203
+ * The overwrite dedup above covers entries written across SEPARATE writes/applies
204
+ * (each later one sees the prior committed version). The apply path additionally
205
+ * collapses in-batch repeats: two versions of one key inside a single
206
+ * `applyChanges` call resolve against the SAME pre-batch prior version, so neither
207
+ * sees the other — `commitChangeMetadata` keeps only the max-HLC winner per key and
208
+ * writes a single entry, preserving the invariant regardless of how many versions
209
+ * of a key were batched.
210
+ *
211
+ * (Schema migrations are still fully scanned by {@link collectSchemaMigrations};
212
+ * the `sm:` range is not HLC-ordered, but migrations are few and the grouping
213
+ * step drops any that sort past the bounded fact watermark.)
214
+ */
215
+ private collectChangesSince;
216
+ /**
217
+ * Resolve a change-log entry to the live {@link Change} it references, or
218
+ * `null` when the underlying column version / tombstone is gone — a stale log
219
+ * entry (e.g. a column overwritten, or a row deleted after the entry was
220
+ * written). The authoritative HLC and value come from the current version, not
221
+ * the log key.
222
+ */
223
+ private resolveLogEntry;
224
+ /**
225
+ * Full extraction (initial sync / delta-from-zero): every column version and
226
+ * tombstone not originating from the peer. Ordering is owned by
227
+ * {@link buildTransactionChangeSets}, so no pre-sort is needed here.
228
+ *
229
+ * Unlike {@link collectChangesSince}, this path cannot early-exit at scan time:
230
+ * the `cv:`/`tb:` scans are keyed by table/pk, NOT by HLC, so transactions are
231
+ * interleaved arbitrarily and no transaction boundary is reachable without a
232
+ * full scan + sort. It is left unbounded because it is the from-zero path: a
233
+ * large initial range is expected to be served by a snapshot rather than this
234
+ * delta path (docs/sync.md).
235
+ */
65
236
  private collectAllChanges;
237
+ /**
238
+ * Collect forwardable held changes to re-offer to a peer — the outbound half of
239
+ * the `store-and-forward` unknown-table disposition. Source is
240
+ * {@link QuarantineStore.listForwardable}: straggler changes this peer held
241
+ * because it has retired the table, marked forwardable. Each is re-offered with
242
+ * its ORIGINAL `hlc` + `siteId` (the straggler's fact, not a new local one) — the
243
+ * identity that makes the relay loop-free and convergent across hops with NO
244
+ * per-table peer-membership oracle (none exists): a peer that already holds the
245
+ * change re-holds it idempotently (HLC-keyed) and the per-peer watermark stops
246
+ * re-send after one exchange.
247
+ *
248
+ * Two filters, mirroring {@link collectChangesSince} / {@link collectAllChanges}:
249
+ * - **Echo exclusion** — drop a change whose origin (`change.hlc.siteId`) is the
250
+ * peer itself, so a straggler's fact is never echoed back to its own author.
251
+ * - **Watermark filter** — when `sinceHLC` is defined (delta path), keep only
252
+ * `compareHLC(change.hlc, sinceHLC) > 0`. REQUIRED: the consumer advances its
253
+ * per-peer `lastSyncHLC` to `max(returned ChangeSet.hlc)`, so a round that
254
+ * returned a forwarded change with HLC ≤ the watermark would REGRESS it and
255
+ * trigger a re-scan/re-deliver flood. Filtering `> sinceHLC` keeps the merged
256
+ * response a safe contiguous prefix — exactly the change-log contract. When
257
+ * `sinceHLC` is undefined (from-zero / {@link collectAllChanges} path) there is
258
+ * no lower bound, so all (origin ≠ peer) are kept.
259
+ *
260
+ * Accepted limitation (documented intent, not a defect): a straggler whose change
261
+ * is causally older than the holder's sync recency with a peer (`HLC ≤ sinceHLC`)
262
+ * is NOT relayed via this delta path — the same scalar-watermark limitation the
263
+ * base delta layer already has. store-and-forward targets the transitional
264
+ * uneven-retirement window, where the straggler's writes are recent enough to
265
+ * exceed holder watermarks; quarantine already prevents write loss outside it.
266
+ *
267
+ * Snapshot carve-out: forwardable entries are DELTA-ONLY. The snapshot collectors
268
+ * scan only `cv:`/`tb:`/`sm:` (never `qt:`), since a snapshot transfers the
269
+ * offering peer's OWN basis and a forwarded change is for a table that peer does
270
+ * not have.
271
+ *
272
+ * Full horizon-bounded scan (no early-exit), paralleling {@link collectAllChanges}:
273
+ * the forwardable set is bounded by the retention horizon and is EMPTY — so this
274
+ * is zero-cost — in the no-straggler case.
275
+ */
276
+ private collectForwardableChanges;
277
+ /**
278
+ * Collect schema migrations after `sinceHLC` not originating from the peer.
279
+ * Each migration shares its transaction's base HLC, so the grouping step
280
+ * rejoins it with that transaction's data facts (or forms a DDL-only ChangeSet).
281
+ *
282
+ * The `sm:` range is keyed by `{schema}.{table}:{version}`, not by HLC, so this
283
+ * scan cannot early-exit the way {@link collectChangesSince} does — it is drained
284
+ * in full even when the fact side stops early. That is acceptable because
285
+ * migrations are few, and {@link buildTransactionChangeSets} drops any migration
286
+ * that sorts past the bounded fact watermark (its DDL-only group falls beyond the
287
+ * `batchSize` cut), so over-scanning here costs work but never correctness. A
288
+ * peer with a pathological volume of un-synced DDL is the one case this leaves
289
+ * unbounded; see the bounded-extraction ticket's handoff.
290
+ */
291
+ private collectSchemaMigrations;
66
292
  applyChanges(changes: ChangeSet[]): Promise<ApplyResult>;
293
+ drainHeldChanges(schema?: string, table?: string): Promise<number>;
67
294
  canDeltaSync(peerSiteId: SiteId, sinceHLC: HLC): Promise<boolean>;
68
295
  getSnapshot(): Promise<Snapshot>;
69
296
  applySnapshot(snapshot: Snapshot): Promise<void>;
70
297
  updatePeerSyncState(peerSiteId: SiteId, hlc: HLC): Promise<void>;
71
298
  getPeerSyncState(peerSiteId: SiteId): Promise<HLC | undefined>;
72
299
  pruneTombstones(): Promise<number>;
300
+ /**
301
+ * GC quarantined out-of-basis straggler changes past the retention horizon —
302
+ * the quarantine sibling of {@link pruneTombstones}, keyed off the same
303
+ * `retentionHorizonMs`. A held change older than the horizon was already
304
+ * outside the delivery guarantee.
305
+ */
306
+ pruneQuarantine(): Promise<number>;
73
307
  getEventEmitter(): SyncEventEmitterImpl;
74
308
  getSnapshotStream(chunkSize?: number): AsyncIterable<SnapshotChunk>;
75
309
  applySnapshotStream(chunks: AsyncIterable<SnapshotChunk>, onProgress?: (progress: SnapshotProgress) => void): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"sync-manager-impl.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-manager-impl.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync-manager-impl.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-manager-impl.ts"],"names":[],"mappings":"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"}