@powersync/service-module-mongodb-storage 0.18.3 → 0.20.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.
- package/CHANGELOG.md +53 -0
- package/dist/migrations/db/migrations/1782950400000-checkpoint-requested-at-index.d.ts +3 -0
- package/dist/migrations/db/migrations/1782950400000-checkpoint-requested-at-index.js +41 -0
- package/dist/migrations/db/migrations/1782950400000-checkpoint-requested-at-index.js.map +1 -0
- package/dist/storage/MongoBucketStorage.d.ts +5 -1
- package/dist/storage/MongoBucketStorage.js +5 -1
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoBucketBatch.d.ts +3 -0
- package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
- package/dist/storage/implementation/MongoCompactor.d.ts +15 -19
- package/dist/storage/implementation/MongoCompactor.js +68 -260
- package/dist/storage/implementation/MongoCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoStorageProvider.js +26 -3
- package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +10 -4
- package/dist/storage/implementation/MongoSyncBucketStorage.js +13 -12
- package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoWriteCheckpointAPI.d.ts +2 -1
- package/dist/storage/implementation/MongoWriteCheckpointAPI.js +146 -34
- package/dist/storage/implementation/MongoWriteCheckpointAPI.js.map +1 -1
- package/dist/storage/implementation/common/PersistedBatch.d.ts +6 -0
- package/dist/storage/implementation/common/PersistedBatch.js +15 -8
- package/dist/storage/implementation/common/PersistedBatch.js.map +1 -1
- package/dist/storage/implementation/models.d.ts +20 -0
- package/dist/storage/implementation/models.js.map +1 -1
- package/dist/storage/implementation/v1/MongoBucketBatchV1.d.ts +4 -0
- package/dist/storage/implementation/v1/MongoBucketBatchV1.js +58 -84
- package/dist/storage/implementation/v1/MongoBucketBatchV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoCompactorV1.d.ts +11 -2
- package/dist/storage/implementation/v1/MongoCompactorV1.js +250 -1
- package/dist/storage/implementation/v1/MongoCompactorV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js +19 -11
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js.map +1 -1
- package/dist/storage/implementation/v1/SingleBucketStoreV1.d.ts +9 -10
- package/dist/storage/implementation/v1/SingleBucketStoreV1.js +2 -8
- package/dist/storage/implementation/v1/SingleBucketStoreV1.js.map +1 -1
- package/dist/storage/implementation/v3/BucketDataContextV3.d.ts +13 -0
- package/dist/storage/implementation/v3/BucketDataContextV3.js +23 -0
- package/dist/storage/implementation/v3/BucketDataContextV3.js.map +1 -0
- package/dist/storage/implementation/v3/MongoBucketBatchV3.js +35 -23
- package/dist/storage/implementation/v3/MongoBucketBatchV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoChecksumsV3.d.ts +1 -0
- package/dist/storage/implementation/v3/MongoChecksumsV3.js +59 -103
- package/dist/storage/implementation/v3/MongoChecksumsV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoCompactorV3.d.ts +23 -2
- package/dist/storage/implementation/v3/MongoCompactorV3.js +354 -219
- package/dist/storage/implementation/v3/MongoCompactorV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.d.ts +5 -0
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js +12 -11
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js.map +1 -1
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.d.ts +5 -3
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js +108 -106
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js.map +1 -1
- package/dist/storage/implementation/v3/PersistedBatchV3.d.ts +5 -2
- package/dist/storage/implementation/v3/PersistedBatchV3.js +53 -15
- package/dist/storage/implementation/v3/PersistedBatchV3.js.map +1 -1
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.d.ts +2 -1
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js +3 -0
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js.map +1 -1
- package/dist/storage/implementation/v3/bucket-format.d.ts +10 -1
- package/dist/storage/implementation/v3/bucket-format.js +28 -9
- package/dist/storage/implementation/v3/bucket-format.js.map +1 -1
- package/dist/storage/implementation/v3/chunking.js +3 -1
- package/dist/storage/implementation/v3/chunking.js.map +1 -1
- package/dist/storage/implementation/v3/models.d.ts +43 -2
- package/dist/storage/implementation/v3/models.js.map +1 -1
- package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.d.ts +21 -0
- package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.js +44 -0
- package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.js.map +1 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorage.d.ts +30 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorage.js +12 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorage.js.map +1 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.d.ts +70 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.js +146 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.js.map +1 -0
- package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.d.ts +42 -0
- package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.js +285 -0
- package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.js.map +1 -0
- package/dist/storage/implementation/v3/source-table-utils.d.ts +9 -1
- package/dist/storage/implementation/v3/source-table-utils.js +20 -21
- package/dist/storage/implementation/v3/source-table-utils.js.map +1 -1
- package/dist/types/types.d.ts +35 -0
- package/dist/types/types.js +35 -1
- package/dist/types/types.js.map +1 -1
- package/dist/utils/test-utils.js +3 -1
- package/dist/utils/test-utils.js.map +1 -1
- package/dist/utils/util.d.ts +8 -1
- package/dist/utils/util.js +125 -2
- package/dist/utils/util.js.map +1 -1
- package/package.json +10 -7
- package/src/migrations/db/migrations/1782950400000-checkpoint-requested-at-index.ts +55 -0
- package/src/storage/MongoBucketStorage.ts +10 -2
- package/src/storage/implementation/MongoBucketBatch.ts +4 -0
- package/src/storage/implementation/MongoCompactor.ts +90 -314
- package/src/storage/implementation/MongoStorageProvider.ts +32 -3
- package/src/storage/implementation/MongoSyncBucketStorage.ts +23 -22
- package/src/storage/implementation/MongoWriteCheckpointAPI.ts +164 -37
- package/src/storage/implementation/common/PersistedBatch.ts +22 -10
- package/src/storage/implementation/models.ts +20 -0
- package/src/storage/implementation/v1/MongoBucketBatchV1.ts +76 -96
- package/src/storage/implementation/v1/MongoCompactorV1.ts +292 -8
- package/src/storage/implementation/v1/MongoSyncBucketStorageV1.ts +53 -40
- package/src/storage/implementation/v1/SingleBucketStoreV1.ts +18 -27
- package/src/storage/implementation/v3/BucketDataContextV3.ts +32 -0
- package/src/storage/implementation/v3/MongoBucketBatchV3.ts +40 -23
- package/src/storage/implementation/v3/MongoChecksumsV3.ts +75 -105
- package/src/storage/implementation/v3/MongoCompactorV3.ts +456 -258
- package/src/storage/implementation/v3/MongoStoppedSyncConfigCleanup.ts +21 -19
- package/src/storage/implementation/v3/MongoSyncBucketStorageV3.ts +122 -126
- package/src/storage/implementation/v3/PersistedBatchV3.ts +69 -16
- package/src/storage/implementation/v3/VersionedPowerSyncMongoV3.ts +5 -0
- package/src/storage/implementation/v3/bucket-format.ts +36 -9
- package/src/storage/implementation/v3/chunking.ts +3 -1
- package/src/storage/implementation/v3/models.ts +45 -1
- package/src/storage/implementation/v3/object-storage/BucketDataObjectStorage.ts +54 -0
- package/src/storage/implementation/v3/object-storage/ObjectStorage.ts +29 -0
- package/src/storage/implementation/v3/object-storage/ObjectStorageLifecycle.ts +171 -0
- package/src/storage/implementation/v3/object-storage/S3ObjectStorage.ts +343 -0
- package/src/storage/implementation/v3/source-table-utils.ts +43 -35
- package/src/types/types.ts +42 -1
- package/src/utils/test-utils.ts +3 -1
- package/src/utils/util.ts +182 -4
- package/test/src/__snapshots__/storage_sync.test.ts.snap +1 -583
- package/test/src/cleanup-stopped-sync-configs.test.ts +24 -1
- package/test/src/helpers/MemoryObjectStorage.ts +53 -0
- package/test/src/helpers/s3TestFactory.ts +69 -0
- package/test/src/object_storage_lifecycle.test.ts +59 -0
- package/test/src/setup.ts +6 -1
- package/test/src/storage.test.ts +216 -2
- package/test/src/storage_compacting.test.ts +176 -187
- package/test/src/storage_object_storage_inline_threshold.test.ts +116 -0
- package/test/src/storage_s3_checksums.test.ts +191 -0
- package/test/src/storage_s3_compaction_lifecycle.test.ts +417 -0
- package/test/src/storage_s3_reading.test.ts +526 -0
- package/test/src/storage_s3_writing.test.ts +135 -0
- package/test/src/storage_sync.test.ts +124 -5
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/storage/implementation/common/SingleBucketStore.d.ts +0 -54
- package/dist/storage/implementation/common/SingleBucketStore.js +0 -3
- package/dist/storage/implementation/common/SingleBucketStore.js.map +0 -1
- package/dist/storage/implementation/v3/SingleBucketStoreV3.d.ts +0 -18
- package/dist/storage/implementation/v3/SingleBucketStoreV3.js +0 -84
- package/dist/storage/implementation/v3/SingleBucketStoreV3.js.map +0 -1
- package/src/storage/implementation/common/SingleBucketStore.ts +0 -63
- package/src/storage/implementation/v3/SingleBucketStoreV3.ts +0 -108
|
@@ -119,6 +119,35 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
119
119
|
storageVersion,
|
|
120
120
|
tableIdStrings: storageConfig.tableIdStrings
|
|
121
121
|
});
|
|
122
|
+
|
|
123
|
+
test('updates source metadata on an existing resolved table', async () => {
|
|
124
|
+
await using factory = await storageConfig.factory();
|
|
125
|
+
const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion }));
|
|
126
|
+
const bucketStorage = factory.getInstance(syncRules);
|
|
127
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
128
|
+
const source = sourceDescriptor('test');
|
|
129
|
+
|
|
130
|
+
const initial = await writer.resolveTables({ connection_id: 1, source });
|
|
131
|
+
expect(initial.tables[0].sourceMetadata).toBeNull();
|
|
132
|
+
|
|
133
|
+
const sourceMetadata = { captureTableObjectId: 42 };
|
|
134
|
+
const updated = await writer.resolveTables({
|
|
135
|
+
connection_id: 1,
|
|
136
|
+
source,
|
|
137
|
+
reconcileSourceTables: ({ candidates }) => ({
|
|
138
|
+
compatibleTables: candidates.map((candidate) => candidate.withSourceMetadata(sourceMetadata)),
|
|
139
|
+
incompatibleTables: [],
|
|
140
|
+
newTableValues: { sourceMetadata }
|
|
141
|
+
})
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
expect(updated.tables.map((table) => table.id.toString())).toEqual(
|
|
145
|
+
initial.tables.map((table) => table.id.toString())
|
|
146
|
+
);
|
|
147
|
+
expect(updated.tables[0].sourceMetadata).toEqual(sourceMetadata);
|
|
148
|
+
expect((await writer.getSourceTableStatus(updated.tables[0]))?.sourceMetadata).toEqual(sourceMetadata);
|
|
149
|
+
});
|
|
150
|
+
|
|
122
151
|
// The split of returned results can vary depending on storage drivers
|
|
123
152
|
test('large batch (2)', async () => {
|
|
124
153
|
// Test syncing a batch of data that is small in count,
|
|
@@ -191,7 +220,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
191
220
|
const checkpoint = flushResult!.flushed_op;
|
|
192
221
|
|
|
193
222
|
const options: storage.BucketDataBatchOptions = {};
|
|
194
|
-
const batch1 = await test_utils.
|
|
223
|
+
const batch1 = await test_utils.getBatchArray(
|
|
195
224
|
bucketStorage.getBucketDataBatch(
|
|
196
225
|
test_utils.testCheckpoint(checkpoint),
|
|
197
226
|
[bucketRequest(syncRulesContent, 'global[]', 0n)],
|
|
@@ -208,7 +237,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
208
237
|
next_after: '2'
|
|
209
238
|
});
|
|
210
239
|
|
|
211
|
-
const batch2 = await test_utils.
|
|
240
|
+
const batch2 = await test_utils.getBatchArray(
|
|
212
241
|
bucketStorage.getBucketDataBatch(
|
|
213
242
|
test_utils.testCheckpoint(checkpoint),
|
|
214
243
|
[bucketRequest(syncRulesContent, 'global[]', batch1[0].chunkData.next_after)],
|
|
@@ -224,7 +253,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
224
253
|
next_after: '3'
|
|
225
254
|
});
|
|
226
255
|
|
|
227
|
-
const batch3 = await test_utils.
|
|
256
|
+
const batch3 = await test_utils.getBatchArray(
|
|
228
257
|
bucketStorage.getBucketDataBatch(
|
|
229
258
|
test_utils.testCheckpoint(checkpoint),
|
|
230
259
|
[bucketRequest(syncRulesContent, 'global[]', batch2[0].chunkData.next_after)],
|
|
@@ -1467,6 +1496,96 @@ streams:
|
|
|
1467
1496
|
expect(await mongoFactory.db.current_data.countDocuments({ '_id.g': syncRules.replicationStreamId })).toBe(0);
|
|
1468
1497
|
});
|
|
1469
1498
|
|
|
1499
|
+
test.runIf(storageVersion < 3)(
|
|
1500
|
+
'clear removes large v1 current_data sets without affecting other streams',
|
|
1501
|
+
async () => {
|
|
1502
|
+
await using factory = await storageConfig.factory();
|
|
1503
|
+
const syncRules = await factory.updateSyncRules(
|
|
1504
|
+
updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, {
|
|
1505
|
+
storageVersion
|
|
1506
|
+
})
|
|
1507
|
+
);
|
|
1508
|
+
const bucketStorage = factory.getInstance(syncRules);
|
|
1509
|
+
const mongoFactory = factory as MongoBucketStorage;
|
|
1510
|
+
const sourceTableId = new bson.ObjectId();
|
|
1511
|
+
const documents = Array.from({ length: 10_002 }, (_, index) => ({
|
|
1512
|
+
_id: {
|
|
1513
|
+
g: syncRules.replicationStreamId,
|
|
1514
|
+
t: sourceTableId,
|
|
1515
|
+
k: index
|
|
1516
|
+
},
|
|
1517
|
+
data: new bson.Binary(),
|
|
1518
|
+
buckets: [],
|
|
1519
|
+
lookups: []
|
|
1520
|
+
}));
|
|
1521
|
+
await mongoFactory.db.current_data.insertMany([
|
|
1522
|
+
...documents,
|
|
1523
|
+
{
|
|
1524
|
+
_id: {
|
|
1525
|
+
g: syncRules.replicationStreamId + 1,
|
|
1526
|
+
t: sourceTableId,
|
|
1527
|
+
k: 0
|
|
1528
|
+
},
|
|
1529
|
+
data: new bson.Binary(),
|
|
1530
|
+
buckets: [],
|
|
1531
|
+
lookups: []
|
|
1532
|
+
}
|
|
1533
|
+
]);
|
|
1534
|
+
|
|
1535
|
+
await bucketStorage.clear();
|
|
1536
|
+
|
|
1537
|
+
expect(await mongoFactory.db.current_data.countDocuments({ '_id.g': syncRules.replicationStreamId })).toBe(0);
|
|
1538
|
+
expect(await mongoFactory.db.current_data.countDocuments({ '_id.g': syncRules.replicationStreamId + 1 })).toBe(1);
|
|
1539
|
+
}
|
|
1540
|
+
);
|
|
1541
|
+
|
|
1542
|
+
test.runIf(storageVersion < 3)(
|
|
1543
|
+
'clear removes large v1 parameter index sets without affecting other streams',
|
|
1544
|
+
async () => {
|
|
1545
|
+
await using factory = await storageConfig.factory();
|
|
1546
|
+
const syncRules = await factory.updateSyncRules(
|
|
1547
|
+
updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, {
|
|
1548
|
+
storageVersion
|
|
1549
|
+
})
|
|
1550
|
+
);
|
|
1551
|
+
const bucketStorage = factory.getInstance(syncRules);
|
|
1552
|
+
const mongoFactory = factory as MongoBucketStorage;
|
|
1553
|
+
const sourceTableId = new bson.ObjectId();
|
|
1554
|
+
const documents = Array.from({ length: 10_002 }, (_, index) => ({
|
|
1555
|
+
_id: BigInt(index * 2),
|
|
1556
|
+
key: {
|
|
1557
|
+
g: syncRules.replicationStreamId,
|
|
1558
|
+
t: sourceTableId,
|
|
1559
|
+
k: index
|
|
1560
|
+
},
|
|
1561
|
+
lookup: new bson.Binary(),
|
|
1562
|
+
bucket_parameters: []
|
|
1563
|
+
}));
|
|
1564
|
+
await mongoFactory.db.bucket_parameters.insertMany([
|
|
1565
|
+
...documents,
|
|
1566
|
+
{
|
|
1567
|
+
_id: 1n,
|
|
1568
|
+
key: {
|
|
1569
|
+
g: syncRules.replicationStreamId + 1,
|
|
1570
|
+
t: sourceTableId,
|
|
1571
|
+
k: 0
|
|
1572
|
+
},
|
|
1573
|
+
lookup: new bson.Binary(),
|
|
1574
|
+
bucket_parameters: []
|
|
1575
|
+
}
|
|
1576
|
+
]);
|
|
1577
|
+
|
|
1578
|
+
await bucketStorage.clear();
|
|
1579
|
+
|
|
1580
|
+
expect(await mongoFactory.db.bucket_parameters.countDocuments({ 'key.g': syncRules.replicationStreamId })).toBe(
|
|
1581
|
+
0
|
|
1582
|
+
);
|
|
1583
|
+
expect(
|
|
1584
|
+
await mongoFactory.db.bucket_parameters.countDocuments({ 'key.g': syncRules.replicationStreamId + 1 })
|
|
1585
|
+
).toBe(1);
|
|
1586
|
+
}
|
|
1587
|
+
);
|
|
1588
|
+
|
|
1470
1589
|
test.runIf(storageVersion < 3)('storage metrics include v1 current_data', async () => {
|
|
1471
1590
|
await using factory = await storageConfig.factory();
|
|
1472
1591
|
const syncRules = await factory.updateSyncRules(
|
|
@@ -1747,7 +1866,7 @@ describe('sync - mongodb', () => {
|
|
|
1747
1866
|
async function getFilteredOps(start: number, checkpoint: number): Promise<bigint[]> {
|
|
1748
1867
|
const { syncRules, bucketStorage } = await setupFilteringTest();
|
|
1749
1868
|
const request = bucketRequest(syncRules.syncConfigContent[0], 'global[]', BigInt(start));
|
|
1750
|
-
const batch = await test_utils.
|
|
1869
|
+
const batch = await test_utils.getBatchArray(
|
|
1751
1870
|
bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(BigInt(checkpoint)), [request])
|
|
1752
1871
|
);
|
|
1753
1872
|
const ops = batch.flatMap((b) => b.chunkData.data.map((d) => BigInt(d.op_id)));
|
|
@@ -1894,7 +2013,7 @@ describe('sync - mongodb', () => {
|
|
|
1894
2013
|
const roundRequests = requests
|
|
1895
2014
|
.filter((request) => pending.has(request.bucket))
|
|
1896
2015
|
.map((request) => ({ ...request, start: positions.get(request.bucket)! }));
|
|
1897
|
-
const batch = await test_utils.
|
|
2016
|
+
const batch = await test_utils.getBatchArray(
|
|
1898
2017
|
bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(end), roundRequests)
|
|
1899
2018
|
);
|
|
1900
2019
|
let anyHasMore = false;
|