@powersync/service-module-mongodb-storage 0.23.1 → 0.24.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 (99) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE +201 -67
  3. package/dist/storage/MongoBucketStorage.d.ts +1 -0
  4. package/dist/storage/MongoBucketStorage.js +3 -0
  5. package/dist/storage/MongoBucketStorage.js.map +1 -1
  6. package/dist/storage/implementation/MongoBucketBatch.d.ts +60 -39
  7. package/dist/storage/implementation/MongoBucketBatch.js +123 -296
  8. package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
  9. package/dist/storage/implementation/MongoOpIdAllocator.d.ts +6 -1
  10. package/dist/storage/implementation/MongoOpIdAllocator.js +12 -5
  11. package/dist/storage/implementation/MongoOpIdAllocator.js.map +1 -1
  12. package/dist/storage/implementation/MongoParsedSyncConfigSet.d.ts +7 -0
  13. package/dist/storage/implementation/MongoParsedSyncConfigSet.js +28 -2
  14. package/dist/storage/implementation/MongoParsedSyncConfigSet.js.map +1 -1
  15. package/dist/storage/implementation/MongoReplicationOptions.d.ts +27 -0
  16. package/dist/storage/implementation/MongoReplicationOptions.js +26 -0
  17. package/dist/storage/implementation/MongoReplicationOptions.js.map +1 -0
  18. package/dist/storage/implementation/MongoSyncBucketStorage.js +2 -3
  19. package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
  20. package/dist/storage/implementation/MongoSyncRulesLock.d.ts +15 -2
  21. package/dist/storage/implementation/MongoSyncRulesLock.js +36 -14
  22. package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
  23. package/dist/storage/implementation/common/BatchOperationBuffer.d.ts +79 -0
  24. package/dist/storage/implementation/common/BatchOperationBuffer.js +286 -0
  25. package/dist/storage/implementation/common/BatchOperationBuffer.js.map +1 -0
  26. package/dist/storage/implementation/common/PersistedBatch.d.ts +10 -103
  27. package/dist/storage/implementation/common/PersistedBatch.js +1 -291
  28. package/dist/storage/implementation/common/PersistedBatch.js.map +1 -1
  29. package/dist/storage/implementation/common/PreparedPublication.d.ts +43 -0
  30. package/dist/storage/implementation/common/PreparedPublication.js +2 -0
  31. package/dist/storage/implementation/common/PreparedPublication.js.map +1 -0
  32. package/dist/storage/implementation/common/SourceRecordStore.d.ts +0 -2
  33. package/dist/storage/implementation/v1/MongoBucketBatchV1.d.ts +17 -13
  34. package/dist/storage/implementation/v1/MongoBucketBatchV1.js +259 -18
  35. package/dist/storage/implementation/v1/MongoBucketBatchV1.js.map +1 -1
  36. package/dist/storage/implementation/v1/PersistedBatchV1.d.ts +21 -15
  37. package/dist/storage/implementation/v1/PersistedBatchV1.js +58 -24
  38. package/dist/storage/implementation/v1/PersistedBatchV1.js.map +1 -1
  39. package/dist/storage/implementation/v1/SourceRecordStoreV1.d.ts +0 -2
  40. package/dist/storage/implementation/v1/SourceRecordStoreV1.js +0 -3
  41. package/dist/storage/implementation/v1/SourceRecordStoreV1.js.map +1 -1
  42. package/dist/storage/implementation/v3/MongoBucketBatchV3.d.ts +25 -14
  43. package/dist/storage/implementation/v3/MongoBucketBatchV3.js +350 -23
  44. package/dist/storage/implementation/v3/MongoBucketBatchV3.js.map +1 -1
  45. package/dist/storage/implementation/v3/MongoCompactorV3.d.ts +1 -0
  46. package/dist/storage/implementation/v3/MongoCompactorV3.js +10 -4
  47. package/dist/storage/implementation/v3/MongoCompactorV3.js.map +1 -1
  48. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js +39 -28
  49. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js.map +1 -1
  50. package/dist/storage/implementation/v3/PersistedBatchV3.d.ts +46 -24
  51. package/dist/storage/implementation/v3/PersistedBatchV3.js +159 -83
  52. package/dist/storage/implementation/v3/PersistedBatchV3.js.map +1 -1
  53. package/dist/storage/implementation/v3/SourceRecordStoreV3.d.ts +12 -0
  54. package/dist/storage/implementation/v3/SourceRecordStoreV3.js +41 -13
  55. package/dist/storage/implementation/v3/SourceRecordStoreV3.js.map +1 -1
  56. package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.d.ts +4 -0
  57. package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.js +4 -0
  58. package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.js.map +1 -1
  59. package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.d.ts +27 -2
  60. package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.js +61 -5
  61. package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.js.map +1 -1
  62. package/package.json +9 -10
  63. package/src/storage/MongoBucketStorage.ts +4 -0
  64. package/src/storage/implementation/MongoBucketBatch.ts +185 -392
  65. package/src/storage/implementation/MongoOpIdAllocator.ts +12 -5
  66. package/src/storage/implementation/MongoParsedSyncConfigSet.ts +40 -1
  67. package/src/storage/implementation/MongoReplicationOptions.ts +28 -0
  68. package/src/storage/implementation/MongoSyncBucketStorage.ts +2 -3
  69. package/src/storage/implementation/MongoSyncRulesLock.ts +39 -17
  70. package/src/storage/implementation/common/BatchOperationBuffer.ts +353 -0
  71. package/src/storage/implementation/common/PersistedBatch.ts +12 -390
  72. package/src/storage/implementation/common/PreparedPublication.ts +49 -0
  73. package/src/storage/implementation/common/SourceRecordStore.ts +0 -2
  74. package/src/storage/implementation/v1/MongoBucketBatchV1.ts +339 -27
  75. package/src/storage/implementation/v1/PersistedBatchV1.ts +74 -32
  76. package/src/storage/implementation/v1/SourceRecordStoreV1.ts +0 -5
  77. package/src/storage/implementation/v3/MongoBucketBatchV3.ts +430 -32
  78. package/src/storage/implementation/v3/MongoCompactorV3.ts +13 -4
  79. package/src/storage/implementation/v3/MongoSyncBucketStorageV3.ts +43 -29
  80. package/src/storage/implementation/v3/PersistedBatchV3.ts +209 -108
  81. package/src/storage/implementation/v3/SourceRecordStoreV3.ts +45 -15
  82. package/src/storage/implementation/v3/object-storage/BucketDataObjectStorage.ts +9 -0
  83. package/src/storage/implementation/v3/object-storage/ObjectStorageLifecycle.ts +79 -5
  84. package/test/src/checkpoint_cleanup.test.ts +75 -0
  85. package/test/src/concurrent_writers.test.ts +127 -53
  86. package/test/src/helpers/PublicationCommandMonitor.ts +119 -0
  87. package/test/src/helpers/concurrentWriter.mjs +2 -2
  88. package/test/src/invalid_sync_config.test.ts +9 -0
  89. package/test/src/object_storage_lifecycle.test.ts +72 -2
  90. package/test/src/prepared_publication.test.ts +388 -0
  91. package/test/src/replication_preparation.test.ts +829 -0
  92. package/test/src/replication_publication_baseline.test.ts +203 -0
  93. package/test/src/replication_publication_batching.test.ts +212 -0
  94. package/test/src/replication_uploads.test.ts +393 -0
  95. package/test/src/source_table_config.test.ts +4 -4
  96. package/test/src/storage_object_storage_inline_threshold.test.ts +1 -1
  97. package/test/src/storage_s3_compaction_lifecycle.test.ts +93 -1
  98. package/test/src/storage_sync.test.ts +83 -2
  99. package/tsconfig.tsbuildinfo +1 -1
@@ -1,292 +1,2 @@
1
- import { logger as defaultLogger } from '@powersync/lib-services-framework';
2
- import { utils } from '@powersync/service-core';
3
- import { JSONBig } from '@powersync/service-jsonbig';
4
- import { mongoTableId, replicaIdToSubkey } from '../../../utils/util.js';
5
- import { currentBucketKey, MAX_ROW_SIZE } from '../MongoBucketBatchShared.js';
6
- /**
7
- * Maximum size of operations we write in a single transaction.
8
- *
9
- * It's tricky to find the exact limit, but from experience, over 100MB
10
- * can cause an error:
11
- * > transaction is too large and will not fit in the storage engine cache
12
- *
13
- * Additionally, unbounded size here can balloon our memory usage in some edge
14
- * cases.
15
- *
16
- * When we reach this threshold, we commit the transaction and start a new one.
17
- */
18
- const MAX_TRANSACTION_BATCH_SIZE = 30_000_000;
19
- /**
20
- * Limit number of documents to write in a single transaction.
21
- *
22
- * This has an effect on error message size in some cases.
23
- */
24
- const MAX_TRANSACTION_DOC_COUNT = 2_000;
25
- export const DEFAULT_INLINE_THRESHOLD_BYTES = 16 * 1024;
26
- /**
27
- * Keeps track of bulkwrite operations within a transaction.
28
- *
29
- * There may be multiple of these batches per transaction, but it may not span
30
- * multiple transactions.
31
- */
32
- export class PersistedBatch {
33
- db;
34
- group_id;
35
- mapping;
36
- logger;
37
- bucketData = [];
38
- bucketParameters = [];
39
- bucketStates = new Map();
40
- objectStorage;
41
- inlineThresholdBytes = DEFAULT_INLINE_THRESHOLD_BYTES;
42
- signal;
43
- objectStorageUsageWriterId;
44
- /**
45
- * For debug logging only.
46
- */
47
- debugLastOpId = null;
48
- /**
49
- * Very rough estimate of transaction size.
50
- */
51
- currentSize = 0;
52
- constructor(db, group_id, mapping, writtenSize, options) {
53
- this.db = db;
54
- this.group_id = group_id;
55
- this.mapping = mapping;
56
- this.currentSize = writtenSize;
57
- this.logger = options?.logger ?? defaultLogger;
58
- this.objectStorage = options?.objectStorage;
59
- this.signal = options?.signal;
60
- this.objectStorageUsageWriterId = options?.objectStorageUsageWriterId;
61
- if (options?.inlineThresholdBytes != null) {
62
- this.inlineThresholdBytes = options.inlineThresholdBytes;
63
- }
64
- }
65
- saveBucketData(options) {
66
- const remaining_buckets = new Map();
67
- for (let bucket of options.before_buckets) {
68
- const mapped = {
69
- bucket: bucket.bucket,
70
- definitionId: this.checkDefinitionId(bucket.definitionId),
71
- id: bucket.id,
72
- table: bucket.table
73
- };
74
- if (options.table.bucketDataSourceIds != null && !options.table.bucketDataSourceIds.has(mapped.definitionId)) {
75
- // The bucket definition is not active anymore.
76
- // We don't cleanup these references upfront, but do need to ignore them after the definition is removed.
77
- continue;
78
- }
79
- remaining_buckets.set(currentBucketKey(mapped), mapped);
80
- }
81
- const subkey = this.persistedSubkey(options.table.id, options.sourceKey);
82
- const dchecksum = BigInt(utils.hashDelete(subkey));
83
- for (const evaluated of options.evaluated) {
84
- const definitionId = this.getBucketDefinitionId(evaluated.source);
85
- const key = currentBucketKey({
86
- definitionId: definitionId,
87
- bucket: evaluated.bucket,
88
- table: evaluated.table,
89
- id: evaluated.id
90
- });
91
- const recordData = JSONBig.stringify(evaluated.data);
92
- const checksum = utils.hashData(evaluated.table, evaluated.id, recordData);
93
- if (recordData.length > MAX_ROW_SIZE) {
94
- this.logger.error(`Row ${key} too large: ${recordData.length} bytes. Removing.`);
95
- continue;
96
- }
97
- remaining_buckets.delete(key);
98
- const byteEstimate = recordData.length + 200;
99
- this.currentSize += byteEstimate;
100
- const op_id = options.op_seq.next();
101
- this.debugLastOpId = op_id;
102
- this.addBucketDataPut({
103
- bucketKey: {
104
- bucket: evaluated.bucket,
105
- definitionId: definitionId,
106
- replicationStreamId: this.group_id
107
- },
108
- op_id,
109
- bucket: evaluated.bucket,
110
- sourceTableId: options.table.id,
111
- sourceKey: options.sourceKey,
112
- subkey,
113
- table: evaluated.table,
114
- rowId: evaluated.id,
115
- checksum: BigInt(checksum),
116
- data: recordData
117
- });
118
- this.incrementBucket(definitionId, evaluated.bucket, op_id, byteEstimate);
119
- }
120
- for (let bucket of remaining_buckets.values()) {
121
- const definitionId = bucket.definitionId;
122
- const op_id = options.op_seq.next();
123
- this.debugLastOpId = op_id;
124
- this.addBucketDataRemove({
125
- bucketKey: {
126
- replicationStreamId: this.group_id,
127
- definitionId,
128
- bucket: bucket.bucket
129
- },
130
- op_id,
131
- sourceTableId: options.table.id,
132
- sourceKey: options.sourceKey,
133
- subkey,
134
- table: bucket.table,
135
- rowId: bucket.id,
136
- checksum: dchecksum
137
- });
138
- this.currentSize += 200;
139
- this.incrementBucket(definitionId, bucket.bucket, op_id, 200);
140
- }
141
- }
142
- /**
143
- * New bucket operations persist protocol subkeys during replication. Older
144
- * V1 documents may not have one, so sync reads retain a fallback.
145
- */
146
- persistedSubkey(table, key) {
147
- return replicaIdToSubkey(table, key);
148
- }
149
- get bucketDataCount() {
150
- return this.bucketData.length;
151
- }
152
- incrementBucket(definitionId, bucket, op_id, bytes) {
153
- const key = `${definitionId ?? ''}:${bucket}`;
154
- let existingState = this.bucketStates.get(key);
155
- if (existingState) {
156
- existingState.lastOp = op_id;
157
- existingState.incrementCount += 1;
158
- existingState.incrementBytes += bytes;
159
- }
160
- else {
161
- this.bucketStates.set(key, {
162
- definitionId,
163
- bucket,
164
- lastOp: op_id,
165
- incrementCount: 1,
166
- incrementBytes: bytes,
167
- incrementChunks: 0
168
- });
169
- }
170
- }
171
- /**
172
- * V3 persists operations in chunks. Keep this separate from incrementBucket:
173
- * operation counts are known while evaluating rows, while chunk counts and
174
- * exact persisted bytes are only known after the writer has chunked a flush.
175
- */
176
- incrementBucketPersistedChunk(definitionId, bucket, bytes) {
177
- const key = `${definitionId ?? ''}:${bucket}`;
178
- const existingState = this.bucketStates.get(key);
179
- if (existingState != null) {
180
- existingState.incrementChunks += 1;
181
- existingState.incrementBytes += bytes;
182
- }
183
- }
184
- /**
185
- * V3's compactor calculates byte deltas from persisted chunk metadata.
186
- * Replace the writer's per-operation estimate with those exact sizes before
187
- * flushing the corresponding bucket state.
188
- */
189
- resetBucketPersistedBytes(definitionId, bucket) {
190
- const state = this.bucketStates.get(`${definitionId ?? ''}:${bucket}`);
191
- if (state != null) {
192
- state.incrementBytes = 0;
193
- }
194
- }
195
- addBucketDataPut(options) {
196
- this.bucketData.push({
197
- bucketKey: options.bucketKey,
198
- o: options.op_id,
199
- op: 'PUT',
200
- source_table: mongoTableId(options.sourceTableId),
201
- source_key: options.sourceKey,
202
- subkey: options.subkey,
203
- table: options.table,
204
- row_id: options.rowId,
205
- checksum: options.checksum,
206
- data: options.data
207
- });
208
- }
209
- addBucketDataRemove(options) {
210
- this.bucketData.push({
211
- bucketKey: options.bucketKey,
212
- o: options.op_id,
213
- op: 'REMOVE',
214
- source_table: mongoTableId(options.sourceTableId),
215
- source_key: options.sourceKey,
216
- subkey: options.subkey,
217
- table: options.table,
218
- row_id: options.rowId,
219
- checksum: options.checksum,
220
- data: null
221
- });
222
- }
223
- shouldFlushTransaction() {
224
- return (this.currentSize >= MAX_TRANSACTION_BATCH_SIZE ||
225
- this.bucketDataCount >= MAX_TRANSACTION_DOC_COUNT ||
226
- this.currentDataCount >= MAX_TRANSACTION_DOC_COUNT ||
227
- this.bucketParameters.length >= MAX_TRANSACTION_DOC_COUNT);
228
- }
229
- async flush(session, options) {
230
- const startAt = performance.now();
231
- let flushedSomething = false;
232
- const writes = this.db.createWriteBatch(session, { ordered: false });
233
- if (this.bucketDataCount > 0) {
234
- flushedSomething = true;
235
- await this.queueBucketData(writes);
236
- }
237
- if (this.bucketParameters.length > 0) {
238
- flushedSomething = true;
239
- this.queueBucketParameters(writes);
240
- }
241
- if (this.currentDataCount > 0) {
242
- flushedSomething = true;
243
- this.queueCurrentData(writes);
244
- }
245
- if (this.bucketStates.size > 0) {
246
- flushedSomething = true;
247
- this.queueBucketStates(writes);
248
- }
249
- await writes.execute();
250
- if (flushedSomething) {
251
- const duration = Math.round(performance.now() - startAt);
252
- if (options?.oldestUncommittedChange != null) {
253
- const replicationLag = Math.round((Date.now() - options.oldestUncommittedChange.getTime()) / 1000);
254
- this.logger.info(`Flushed: ${this.bucketDataCount} ops, ${this.bucketParameters.length} index entries, ${this.currentDataCount} records. ${Math.round(this.currentSize / 1024)}kb in ${duration}ms. Last op_id: ${this.debugLastOpId}. Replication lag: ${replicationLag}s`, {
255
- flushed: {
256
- duration: duration,
257
- size: this.currentSize,
258
- bucket_ops_count: this.bucketDataCount,
259
- parameter_indexes_count: this.bucketParameters.length,
260
- source_records_count: this.currentDataCount,
261
- replication_lag_seconds: replicationLag
262
- }
263
- });
264
- }
265
- else {
266
- this.logger.info(`Flushed: ${this.bucketDataCount} ops, ${this.bucketParameters.length} index entries, ${this.currentDataCount} records. ${Math.round(this.currentSize / 1024)}kb in ${duration}ms. Last op_id: ${this.debugLastOpId}`, {
267
- flushed: {
268
- duration: duration,
269
- size: this.currentSize,
270
- bucket_ops_count: this.bucketDataCount,
271
- parameter_indexes_count: this.bucketParameters.length,
272
- source_records_count: this.currentDataCount
273
- }
274
- });
275
- }
276
- }
277
- const stats = {
278
- bucketDataCount: this.bucketDataCount,
279
- parameterDataCount: this.bucketParameters.length,
280
- currentDataCount: this.currentDataCount,
281
- flushedAny: flushedSomething
282
- };
283
- this.bucketData = [];
284
- this.bucketParameters = [];
285
- this.resetCurrentData();
286
- this.bucketStates.clear();
287
- this.currentSize = 0;
288
- this.debugLastOpId = null;
289
- return stats;
290
- }
291
- }
1
+ export {};
292
2
  //# sourceMappingURL=PersistedBatch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PersistedBatch.js","sourceRoot":"","sources":["../../../../src/storage/implementation/common/PersistedBatch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PersistedBatch.js","sourceRoot":"","sources":["../../../../src/storage/implementation/common/PersistedBatch.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ import { mongo } from '@powersync/lib-service-mongodb';
2
+ import { storage } from '@powersync/service-core';
3
+ import { MongoWriteBatch } from '../MongoWriteBatch.js';
4
+ export interface PublicationStats {
5
+ bucketDataCount: number;
6
+ parameterDataCount: number;
7
+ currentDataCount: number;
8
+ flushedAny: boolean;
9
+ }
10
+ /**
11
+ * Sealed view of a v3/v4 batch. Preparation runs once, including on failure;
12
+ * publication creates fresh MongoDB writes on every attempt without clearing it.
13
+ *
14
+ * Scheduling metadata belongs to the caller: lease, selected config/mappings,
15
+ * input suffix, checkpoint intent and durable progress. Replay is valid only
16
+ * while that context and upload protection remain valid. A changed owner or
17
+ * config, or expired payload, must abandon this generation, never mutate it to
18
+ * fit a different context or overwrite its object paths. Publication also
19
+ * asserts that assigned IDs advance the freshly fenced persisted head.
20
+ *
21
+ * No application repair callbacks run here. The coordinator collects
22
+ * markRecordUnavailable records during evaluation and delivers them only after
23
+ * confirmed commit. Diagnostics run during evaluation.
24
+ * Before/after-flush hooks, source events and custom checkpoint consumption also
25
+ * belong to that coordinator, never to replayable writes. Only a confirmed
26
+ * commit may consume input, advance durable progress or notify readers.
27
+ */
28
+ export interface PreparedPublication {
29
+ /**
30
+ * Explicitly start preparation after consuming assigned IDs. Sealing itself
31
+ * starts no I/O, so the coordinator can establish ownership before yielding.
32
+ * A rejected preparation is terminal for this generation; all started uploads
33
+ * must have settled before this promise rejects.
34
+ */
35
+ preparePayloads(): Promise<void>;
36
+ /**
37
+ * Requires completed readiness before starting the publication transaction.
38
+ * An optional batch supplies independent head/checkpoint writes to execute
39
+ * together with this group's data. This method owns execution of that batch;
40
+ * callers must not execute it again or include another group's dependent writes.
41
+ */
42
+ publish(session: mongo.ClientSession, options?: storage.BucketBatchCommitOptions, additionalWrites?: MongoWriteBatch): Promise<PublicationStats>;
43
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=PreparedPublication.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PreparedPublication.js","sourceRoot":"","sources":["../../../../src/storage/implementation/common/PreparedPublication.ts"],"names":[],"mappings":""}
@@ -1,5 +1,4 @@
1
1
  import { mongo } from '@powersync/lib-service-mongodb';
2
- import { Logger } from '@powersync/lib-services-framework';
3
2
  import { storage } from '@powersync/service-core';
4
3
  import { BucketDefinitionId, EvaluatedParameters, EvaluatedRow, ParameterIndexId } from '@powersync/service-sync-rules';
5
4
  import * as bson from 'bson';
@@ -31,5 +30,4 @@ export interface SourceRecordStore {
31
30
  loadSizes(session: mongo.ClientSession, entries: SourceRecordLookupEntry[]): Promise<Map<string, number>>;
32
31
  loadDocuments(session: mongo.ClientSession, entries: SourceRecordLookupEntry[], idsOnly: boolean): Promise<Map<string, LoadedSourceRecord>>;
33
32
  loadTruncateBatch(session: mongo.ClientSession, sourceTableId: bson.ObjectId, limit: number): Promise<LoadedSourceRecord[]>;
34
- postCommitCleanup(lastCheckpoint: bigint, logger: Logger): Promise<void>;
35
33
  }
@@ -2,9 +2,9 @@ import { mongo } from '@powersync/lib-service-mongodb';
2
2
  import { InternalOpId, SourceTable, storage } from '@powersync/service-core';
3
3
  import { MongoBucketBatch, MongoBucketBatchOptions } from '../MongoBucketBatch.js';
4
4
  import { MongoWriteBatch } from '../MongoWriteBatch.js';
5
- import { PersistedBatch } from '../common/PersistedBatch.js';
6
5
  import { SourceRecordStore } from '../common/SourceRecordStore.js';
7
6
  import { SyncRuleDocumentBase } from '../models.js';
7
+ import { PersistedBatchV1 } from './PersistedBatchV1.js';
8
8
  import { VersionedPowerSyncMongoV1 } from './VersionedPowerSyncMongoV1.js';
9
9
  export declare class MongoBucketBatchV1 extends MongoBucketBatch {
10
10
  readonly db: VersionedPowerSyncMongoV1;
@@ -19,28 +19,32 @@ export declare class MongoBucketBatchV1 extends MongoBucketBatch {
19
19
  */
20
20
  private persisted_op;
21
21
  constructor(options: MongoBucketBatchOptions);
22
+ private withReplicationTransaction;
23
+ private clearError;
24
+ protected flushInner(options?: storage.BatchBucketFlushOptions, checkpoint?: (stream: SyncRuleDocumentBase, lastOp: InternalOpId, writes?: MongoWriteBatch) => Promise<void>, projection?: mongo.Document): Promise<storage.FlushedResult | null>;
25
+ private replicateBatch;
26
+ protected truncateSingleInternal(sourceTable: storage.SourceTable): Promise<InternalOpId>;
22
27
  protected persistedOpHead(stream: SyncRuleDocumentBase): InternalOpId;
23
28
  protected onReplicationTransactionFlush(writes: MongoWriteBatch, lastOp: InternalOpId): void;
24
- protected recordPersistedOp(lastOp: InternalOpId): void;
25
- protected createPersistedBatch(writtenSize: number): PersistedBatch;
29
+ private recordPersistedOp;
30
+ protected createPersistedBatch(writtenSize: number): PersistedBatchV1;
26
31
  protected get sourceRecordStore(): SourceRecordStore;
27
32
  protected cleanupDroppedSourceTables(_tables: SourceTable[]): Promise<void>;
28
- protected batchCreateCustomWriteCheckpoints(session: mongo.ClientSession, opId: InternalOpId): Promise<void>;
29
- resolveTables(options: storage.ResolveTablesOptions): Promise<storage.ResolveTablesResult>;
33
+ private batchCreateCustomWriteCheckpoints;
34
+ protected resolveTablesInternal(options: storage.ResolveTablesOptions): Promise<storage.ResolveTablesResult>;
30
35
  /**
31
36
  * Build a SourceTable from its persisted v1 record.
32
37
  */
33
38
  private hydrateSourceTable;
34
- getSourceTableStatus(table: storage.SourceTable): Promise<storage.SourceTable | null>;
35
- commit(lsn: string, options?: storage.BucketBatchCommitOptions): Promise<storage.CheckpointResult>;
36
- keepalive(lsn: string): Promise<storage.CheckpointResult>;
37
- setResumeLsn(lsn: string): Promise<void>;
38
- markAllSnapshotDone(no_checkpoint_before_lsn: string): Promise<void>;
39
+ protected getSourceTableStatusInternal(table: storage.SourceTable): Promise<storage.SourceTable | null>;
40
+ protected commitInternal(lsn: string, options?: storage.BucketBatchCommitOptions): Promise<storage.CheckpointResult>;
41
+ protected setResumeLsnInternal(lsn: string): Promise<void>;
42
+ protected markAllSnapshotDoneInternal(no_checkpoint_before_lsn: string): Promise<void>;
39
43
  private snapshotDoneUpdate;
40
- markSnapshotDone(no_checkpoint_before_lsn: string, options?: {
44
+ protected markSnapshotDoneInternal(no_checkpoint_before_lsn: string, options?: {
41
45
  throwOnConflict?: boolean;
42
46
  }): Promise<void>;
43
- markTableSnapshotRequired(_table: storage.SourceTable): Promise<void>;
44
- markTableSnapshotDone(tables: storage.SourceTable[], no_checkpoint_before_lsn?: string): Promise<storage.SourceTable[]>;
47
+ protected markTableSnapshotRequiredInternal(_table: storage.SourceTable): Promise<void>;
48
+ protected markTableSnapshotDoneInternal(tables: storage.SourceTable[], no_checkpoint_before_lsn?: string): Promise<storage.SourceTable[]>;
45
49
  private autoActivate;
46
50
  }