@powersync/service-module-mongodb-storage 0.22.0 → 0.23.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 (80) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/storage/MongoBucketStorage.d.ts +5 -1
  3. package/dist/storage/MongoBucketStorage.js +30 -6
  4. package/dist/storage/MongoBucketStorage.js.map +1 -1
  5. package/dist/storage/implementation/MongoBucketBatch.d.ts +23 -10
  6. package/dist/storage/implementation/MongoBucketBatch.js +132 -88
  7. package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
  8. package/dist/storage/implementation/MongoCompactor.d.ts +2 -0
  9. package/dist/storage/implementation/MongoCompactor.js.map +1 -1
  10. package/dist/storage/implementation/MongoIdSequence.d.ts +10 -1
  11. package/dist/storage/implementation/MongoIdSequence.js +14 -1
  12. package/dist/storage/implementation/MongoIdSequence.js.map +1 -1
  13. package/dist/storage/implementation/MongoOpIdAllocator.d.ts +27 -0
  14. package/dist/storage/implementation/MongoOpIdAllocator.js +97 -0
  15. package/dist/storage/implementation/MongoOpIdAllocator.js.map +1 -0
  16. package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +5 -0
  17. package/dist/storage/implementation/MongoSyncBucketStorage.js +17 -0
  18. package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
  19. package/dist/storage/implementation/MongoSyncRulesLock.d.ts +26 -2
  20. package/dist/storage/implementation/MongoSyncRulesLock.js +38 -1
  21. package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
  22. package/dist/storage/implementation/db.js +1 -0
  23. package/dist/storage/implementation/db.js.map +1 -1
  24. package/dist/storage/implementation/v1/MongoBucketBatchV1.d.ts +5 -0
  25. package/dist/storage/implementation/v1/MongoBucketBatchV1.js +136 -133
  26. package/dist/storage/implementation/v1/MongoBucketBatchV1.js.map +1 -1
  27. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js +1 -1
  28. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js.map +1 -1
  29. package/dist/storage/implementation/v3/MongoBucketBatchV3.d.ts +5 -1
  30. package/dist/storage/implementation/v3/MongoBucketBatchV3.js +131 -148
  31. package/dist/storage/implementation/v3/MongoBucketBatchV3.js.map +1 -1
  32. package/dist/storage/implementation/v3/MongoCompactorV3.d.ts +4 -3
  33. package/dist/storage/implementation/v3/MongoCompactorV3.js +14 -10
  34. package/dist/storage/implementation/v3/MongoCompactorV3.js.map +1 -1
  35. package/dist/storage/implementation/v3/compact-utils.d.ts +3 -2
  36. package/dist/storage/implementation/v3/compact-utils.js +12 -5
  37. package/dist/storage/implementation/v3/compact-utils.js.map +1 -1
  38. package/dist/storage/implementation/v3/models.d.ts +1 -1
  39. package/dist/utils/test-utils.d.ts +2 -1
  40. package/dist/utils/test-utils.js +4 -3
  41. package/dist/utils/test-utils.js.map +1 -1
  42. package/package.json +7 -7
  43. package/src/storage/MongoBucketStorage.ts +35 -7
  44. package/src/storage/implementation/MongoBucketBatch.ts +201 -110
  45. package/src/storage/implementation/MongoCompactor.ts +2 -0
  46. package/src/storage/implementation/MongoIdSequence.ts +21 -1
  47. package/src/storage/implementation/MongoOpIdAllocator.ts +105 -0
  48. package/src/storage/implementation/MongoSyncBucketStorage.ts +19 -0
  49. package/src/storage/implementation/MongoSyncRulesLock.ts +56 -3
  50. package/src/storage/implementation/db.ts +1 -0
  51. package/src/storage/implementation/models.ts +1 -0
  52. package/src/storage/implementation/v1/MongoBucketBatchV1.ts +150 -152
  53. package/src/storage/implementation/v1/MongoSyncBucketStorageV1.ts +1 -1
  54. package/src/storage/implementation/v3/MongoBucketBatchV3.ts +167 -194
  55. package/src/storage/implementation/v3/MongoCompactorV3.ts +19 -22
  56. package/src/storage/implementation/v3/compact-utils.ts +16 -7
  57. package/src/storage/implementation/v3/models.ts +1 -1
  58. package/src/utils/test-utils.ts +5 -3
  59. package/test/src/__snapshots__/storage.test.ts.snap +102 -2
  60. package/test/src/__snapshots__/storage_compacting.test.ts.snap +2 -2
  61. package/test/src/__snapshots__/storage_sync.test.ts.snap +12 -12
  62. package/test/src/cleanup-stopped-sync-configs.test.ts +19 -13
  63. package/test/src/compact-utils.test.ts +33 -8
  64. package/test/src/concurrent_writers.test.ts +599 -0
  65. package/test/src/helpers/concurrentWriter.mjs +29 -0
  66. package/test/src/helpers/s3TestFactory.ts +12 -12
  67. package/test/src/object_storage_usage.test.ts +2 -1
  68. package/test/src/parameter_compacting_v1.test.ts +2 -2
  69. package/test/src/parameter_compacting_v3.test.ts +2 -2
  70. package/test/src/parameter_compaction_fence.test.ts +3 -3
  71. package/test/src/storage.test.ts +32 -33
  72. package/test/src/storage_compacting.test.ts +147 -21
  73. package/test/src/storage_object_storage_inline_threshold.test.ts +3 -3
  74. package/test/src/storage_s3_checksums.test.ts +4 -4
  75. package/test/src/storage_s3_compaction_lifecycle.test.ts +8 -8
  76. package/test/src/storage_s3_reading.test.ts +4 -4
  77. package/test/src/storage_s3_writing.test.ts +3 -3
  78. package/test/src/storage_sync.test.ts +52 -46
  79. package/test/src/storeCurrentData.test.ts +5 -5
  80. package/tsconfig.tsbuildinfo +1 -1
@@ -1,6 +1,6 @@
1
1
  import * as lib_mongo from '@powersync/lib-service-mongodb';
2
2
  import { storage, updateSyncRulesFromYaml } from '@powersync/service-core';
3
- import { bucketRequest, compactActive, test_utils } from '@powersync/service-core-tests';
3
+ import { bucketRequest, compactActive, getTestStorage, test_utils } from '@powersync/service-core-tests';
4
4
  import { describe, expect, test } from 'vitest';
5
5
  import { MongoSyncBucketStorage } from '../../src/storage/implementation/createMongoSyncBucketStorage.js';
6
6
  import { MongoSyncBucketStorageV3 } from '../../src/storage/implementation/v3/MongoSyncBucketStorageV3.js';
@@ -57,7 +57,7 @@ describe('S3 compaction storage lifecycle', () => {
57
57
  const { memoryStorage, factory: factoryGen } = memoryS3Factory();
58
58
  await using factory = await factoryGen.factory();
59
59
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
60
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
60
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
61
61
 
62
62
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
63
63
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 1);
@@ -106,7 +106,7 @@ describe('S3 compaction storage lifecycle', () => {
106
106
  const { memoryStorage, factory: factoryGen } = memoryS3Factory({ inlineThresholdBytes: 10_000 });
107
107
  await using factory = await factoryGen.factory();
108
108
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
109
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
109
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
110
110
 
111
111
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
112
112
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 10);
@@ -152,7 +152,7 @@ describe('S3 compaction storage lifecycle', () => {
152
152
  const { factory: factoryGen } = memoryS3Factory();
153
153
  await using factory = await factoryGen.factory();
154
154
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
155
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
155
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
156
156
 
157
157
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
158
158
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 11);
@@ -187,7 +187,7 @@ describe('S3 compaction storage lifecycle', () => {
187
187
  const { factory: factoryGen } = memoryS3Factory();
188
188
  await using factory = await factoryGen.factory();
189
189
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
190
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
190
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
191
191
 
192
192
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
193
193
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 12);
@@ -248,7 +248,7 @@ describe('S3 compaction storage lifecycle', () => {
248
248
  const { memoryStorage, factory: factoryGen } = memoryS3Factory();
249
249
  await using factory = await factoryGen.factory();
250
250
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
251
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
251
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
252
252
 
253
253
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
254
254
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 1);
@@ -323,7 +323,7 @@ describe('S3 compaction storage lifecycle', () => {
323
323
  const { memoryStorage, factory: factoryGen } = memoryS3Factory();
324
324
  await using factory = await factoryGen.factory();
325
325
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
326
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
326
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
327
327
 
328
328
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
329
329
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 1);
@@ -396,7 +396,7 @@ describe('S3 compaction storage lifecycle', () => {
396
396
  const { memoryStorage, factory: factoryGen } = memoryS3Factory();
397
397
  await using factory = await factoryGen.factory();
398
398
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
399
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
399
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
400
400
 
401
401
  // Write several operations, including a repeated object id, to exercise
402
402
  // the compaction round-trip.
@@ -1,6 +1,6 @@
1
1
  import { DeleteObjectsCommand, ListObjectsV2Command } from '@aws-sdk/client-s3';
2
2
  import { storage, updateSyncRulesFromYaml } from '@powersync/service-core';
3
- import { bucketRequest, test_utils } from '@powersync/service-core-tests';
3
+ import { bucketRequest, getTestStorage, test_utils } from '@powersync/service-core-tests';
4
4
  import * as bson from 'bson';
5
5
  import { describe, expect, test, vi } from 'vitest';
6
6
  import { MongoSyncBucketStorage } from '../../src/storage/implementation/createMongoSyncBucketStorage.js';
@@ -662,7 +662,7 @@ describe('S3 object storage reads', () => {
662
662
  const { memoryStorage, factory: factoryGen } = memoryS3Factory();
663
663
  await using factory = await factoryGen.factory();
664
664
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
665
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
665
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
666
666
 
667
667
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
668
668
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 1);
@@ -710,7 +710,7 @@ describe('S3 object storage reads', () => {
710
710
  const { factory: factoryGen } = s3Factory();
711
711
  await using factory = await factoryGen.factory();
712
712
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
713
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
713
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
714
714
 
715
715
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
716
716
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 1);
@@ -763,7 +763,7 @@ describe('S3 object storage reads', () => {
763
763
  const { memoryStorage, factory: factoryGen } = memoryS3Factory({ inlineThresholdBytes: 1_000 });
764
764
  await using factory = await factoryGen.factory();
765
765
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
766
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
766
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
767
767
 
768
768
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
769
769
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 1);
@@ -1,5 +1,5 @@
1
1
  import { storage, updateSyncRulesFromYaml } from '@powersync/service-core';
2
- import { test_utils } from '@powersync/service-core-tests';
2
+ import { getTestStorage, test_utils } from '@powersync/service-core-tests';
3
3
  import * as bson from 'bson';
4
4
  import { describe, expect, test } from 'vitest';
5
5
  import { MongoSyncBucketStorage } from '../../src/storage/implementation/createMongoSyncBucketStorage.js';
@@ -28,7 +28,7 @@ describe('S3 object storage writes', () => {
28
28
  const { memoryStorage, factory: factoryGen } = memoryS3Factory();
29
29
  await using factory = await factoryGen.factory();
30
30
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
31
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
31
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
32
32
 
33
33
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
34
34
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 1);
@@ -95,7 +95,7 @@ describe('S3 object storage writes', () => {
95
95
  const { memoryStorage, factory: factoryGen } = memoryS3Factory();
96
96
  await using factory = await factoryGen.factory();
97
97
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
98
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
98
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
99
99
 
100
100
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
101
101
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 4);
@@ -6,7 +6,7 @@ import {
6
6
  storage,
7
7
  updateSyncRulesFromYaml
8
8
  } from '@powersync/service-core';
9
- import { bucketRequest, register, test_utils } from '@powersync/service-core-tests';
9
+ import { bucketRequest, getTestStorage, register, test_utils } from '@powersync/service-core-tests';
10
10
  import { RequestParameters, ScopedParameterLookup, SqlSyncRules } from '@powersync/service-sync-rules';
11
11
  import * as bson from 'bson';
12
12
  import { describe, expect, test } from 'vitest';
@@ -149,7 +149,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
149
149
  test('updates source metadata on an existing resolved table', async () => {
150
150
  await using factory = await storageConfig.factory();
151
151
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion }));
152
- const bucketStorage = factory.getInstance(syncRules);
152
+ const bucketStorage = await getTestStorage(factory, syncRules);
153
153
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
154
154
  const source = sourceDescriptor('test');
155
155
 
@@ -191,7 +191,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
191
191
  { storageVersion }
192
192
  )
193
193
  );
194
- const bucketStorage = factory.getInstance(syncRules);
194
+ const bucketStorage = await getTestStorage(factory, syncRules);
195
195
  const syncRulesContent = syncRules.syncConfigContent[0];
196
196
 
197
197
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
@@ -338,7 +338,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
338
338
  { storageVersion }
339
339
  )
340
340
  );
341
- const bucketStorage = factory.getInstance(syncRules);
341
+ const bucketStorage = await getTestStorage(factory, syncRules);
342
342
 
343
343
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
344
344
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], INITIALIZED_MONGO_STORAGE_FACTORY);
@@ -363,7 +363,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
363
363
  { storageVersion }
364
364
  )
365
365
  );
366
- const bucketStorage = factory.getInstance(syncRules);
366
+ const bucketStorage = await getTestStorage(factory, syncRules);
367
367
 
368
368
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
369
369
  const before = await writer.resolveTables({
@@ -401,7 +401,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
401
401
  { storageVersion }
402
402
  )
403
403
  );
404
- const bucketStorage = factory.getInstance(syncRules);
404
+ const bucketStorage = await getTestStorage(factory, syncRules);
405
405
 
406
406
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
407
407
  const before = await writer.resolveTables({
@@ -437,7 +437,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
437
437
  { storageVersion }
438
438
  )
439
439
  );
440
- const bucketStorage = factory.getInstance(syncRules);
440
+ const bucketStorage = await getTestStorage(factory, syncRules);
441
441
 
442
442
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
443
443
  const before = await writer.resolveTables({
@@ -481,7 +481,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
481
481
  { storageVersion }
482
482
  )
483
483
  );
484
- const bucketStorage = factory.getInstance(syncRules);
484
+ const bucketStorage = await getTestStorage(factory, syncRules);
485
485
 
486
486
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
487
487
  const resolved = await writer.resolveTables({
@@ -550,7 +550,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
550
550
  // Here we're persisting one sync config, then resolving tables with others.
551
551
  // We're also using the default hydration state for them all.
552
552
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(fullRulesYaml, { storageVersion }));
553
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
553
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
554
554
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
555
555
  const fullRules = parsedSyncConfigSetFor(fullRulesYaml, storageVersion);
556
556
  const dataOnlyRules = parsedSyncConfigSetFor(dataOnlyRulesYaml, storageVersion);
@@ -666,7 +666,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
666
666
 
667
667
  await using factory = await storageConfig.factory();
668
668
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(dataOnlyEventYaml, { storageVersion }));
669
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
669
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
670
670
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
671
671
  const dataOnlyRules = parsedSyncConfigSetFor(dataOnlyEventYaml, storageVersion);
672
672
  const fullRules = parsedSyncConfigSetFor(fullEventYaml, storageVersion);
@@ -739,7 +739,7 @@ event_definitions:
739
739
  });
740
740
  try {
741
741
  const first = await factory.updateSyncRules(updateSyncRulesFromYaml(firstYaml, { storageVersion }));
742
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
742
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
743
743
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
744
744
  const source = sourceDescriptor('checkpoints', { objectId: 'checkpoints-relation' });
745
745
  const firstResolved = await firstWriter.resolveTables({
@@ -755,7 +755,7 @@ event_definitions:
755
755
 
756
756
  const second = await factory.updateSyncRules(updateSyncRulesFromYaml(secondYaml, { storageVersion }));
757
757
  expect(second.replicationStreamId).toBe(first.replicationStreamId);
758
- const secondStorage = factory.getInstance(second) as MongoSyncBucketStorage;
758
+ const secondStorage = (await getTestStorage(factory, second)) as MongoSyncBucketStorage;
759
759
  await using secondWriter = await secondStorage.createWriter(test_utils.BATCH_OPTIONS);
760
760
  const resolved = await secondWriter.resolveTables({
761
761
  connection_id: 1,
@@ -806,7 +806,7 @@ event_definitions:
806
806
  });
807
807
  try {
808
808
  const first = await factory.updateSyncRules(updateSyncRulesFromYaml(yaml(true), { storageVersion }));
809
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
809
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
810
810
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
811
811
  const source = sourceDescriptor('checkpoints', { objectId: 'checkpoints-relation' });
812
812
  const firstResolved = await firstWriter.resolveTables({
@@ -821,7 +821,7 @@ event_definitions:
821
821
 
822
822
  const second = await factory.updateSyncRules(updateSyncRulesFromYaml(yaml(false), { storageVersion }));
823
823
  expect(second.replicationStreamId).toBe(first.replicationStreamId);
824
- const secondStorage = factory.getInstance(second) as MongoSyncBucketStorage;
824
+ const secondStorage = (await getTestStorage(factory, second)) as MongoSyncBucketStorage;
825
825
  await using secondWriter = await secondStorage.createWriter(test_utils.BATCH_OPTIONS);
826
826
  const resolved = await secondWriter.resolveTables({
827
827
  connection_id: 1,
@@ -875,7 +875,7 @@ event_definitions:
875
875
  { storageVersion }
876
876
  )
877
877
  );
878
- const bucketStorage = factory.getInstance(syncRules);
878
+ const bucketStorage = await getTestStorage(factory, syncRules);
879
879
  const syncRulesContent = syncRules.syncConfigContent[0];
880
880
  const sync_rules = syncRulesContent.parsed(test_utils.PARSE_OPTIONS).hydratedSyncConfig;
881
881
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
@@ -988,7 +988,7 @@ streams:
988
988
  expect(parsed.syncConfigs).toHaveLength(1);
989
989
  expect(parsed.hydratedSyncConfig.bucketDataSources).toHaveLength(1);
990
990
 
991
- const bucketStorage = factory.getInstance(replicatingStreams[0]);
991
+ const bucketStorage = await getTestStorage(factory, replicatingStreams[0]);
992
992
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
993
993
  const resolved = await writer.resolveTables({
994
994
  connection_id: 1,
@@ -1015,7 +1015,7 @@ streams:
1015
1015
  { storageVersion }
1016
1016
  )
1017
1017
  );
1018
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1018
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1019
1019
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1020
1020
  await firstWriter.markAllSnapshotDone('1/1');
1021
1021
  await firstWriter.commit('1/1');
@@ -1035,7 +1035,7 @@ streams:
1035
1035
  );
1036
1036
  expect(second.replicationStreamId).toEqual(first.replicationStreamId);
1037
1037
 
1038
- const bucketStorage = factory.getInstance(second);
1038
+ const bucketStorage = await getTestStorage(factory, second);
1039
1039
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1040
1040
  const source = sourceDescriptor('todos', { objectId: 'todos-relation' });
1041
1041
 
@@ -1050,7 +1050,10 @@ streams:
1050
1050
  await writer.markAllSnapshotDone('2/1');
1051
1051
  await writer.commit('2/1');
1052
1052
 
1053
- const activeStorage = (await factory.getActiveSyncConfig())?.storage as MongoSyncBucketStorage;
1053
+ const activeStorage = (await getTestStorage(
1054
+ factory,
1055
+ (await factory.getActiveSyncConfig())!.replicationStream
1056
+ )) as MongoSyncBucketStorage;
1054
1057
  await using activeWriter = await activeStorage.createWriter(test_utils.BATCH_OPTIONS);
1055
1058
  const activeStatus = await activeWriter.getSourceTableStatus(resolved.tables[0]);
1056
1059
  expect(activeStatus?.bucketDataSources).toHaveLength(1);
@@ -1074,7 +1077,7 @@ streams:
1074
1077
  { storageVersion }
1075
1078
  )
1076
1079
  );
1077
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1080
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1078
1081
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1079
1082
  const source = sourceDescriptor('todos', { objectId: 'todos-relation' });
1080
1083
  const firstResolved = await firstWriter.resolveTables({
@@ -1103,7 +1106,7 @@ streams:
1103
1106
 
1104
1107
  const deploying = await factory.getDeployingSyncConfig();
1105
1108
  expect(deploying?.replicationStream.replicationStreamId).toBe(first.replicationStreamId);
1106
- const bucketStorage = deploying!.storage;
1109
+ const bucketStorage = await getTestStorage(factory, deploying!.replicationStream);
1107
1110
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1108
1111
  const resolved = await writer.resolveTables({
1109
1112
  connection_id: 1,
@@ -1149,7 +1152,7 @@ streams:
1149
1152
  `;
1150
1153
 
1151
1154
  const first = await factory.updateSyncRules(updateSyncRulesFromYaml(ownerRules, { storageVersion }));
1152
- const firstStorage = factory.getInstance(first);
1155
+ const firstStorage = await getTestStorage(factory, first);
1153
1156
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1154
1157
  await firstWriter.markAllSnapshotDone('1/1');
1155
1158
  await firstWriter.commit('1/1');
@@ -1201,7 +1204,7 @@ streams:
1201
1204
  { storageVersion }
1202
1205
  )
1203
1206
  );
1204
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1207
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1205
1208
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1206
1209
  await firstWriter.markAllSnapshotDone('1/1');
1207
1210
  await firstWriter.commit('1/1');
@@ -1223,7 +1226,7 @@ streams:
1223
1226
  );
1224
1227
  expect(second.replicationStreamId).toBe(first.replicationStreamId);
1225
1228
 
1226
- const bucketStorage = factory.getInstance(second);
1229
+ const bucketStorage = await getTestStorage(factory, second);
1227
1230
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1228
1231
  const resolved = await writer.resolveTables({
1229
1232
  connection_id: 1,
@@ -1274,7 +1277,7 @@ streams:
1274
1277
  { storageVersion }
1275
1278
  )
1276
1279
  );
1277
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1280
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1278
1281
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1279
1282
  await firstWriter.markAllSnapshotDone('1/1');
1280
1283
  await firstWriter.commit('1/1');
@@ -1317,7 +1320,7 @@ streams:
1317
1320
  expect(replicatingStreams[0].replicationJobId).toContain(config.syncConfigId);
1318
1321
  }
1319
1322
 
1320
- const secondStorage = factory.getInstance(replicatingStreams[0]) as MongoSyncBucketStorage;
1323
+ const secondStorage = (await getTestStorage(factory, replicatingStreams[0])) as MongoSyncBucketStorage;
1321
1324
  await using secondWriter = await secondStorage.createWriter(test_utils.BATCH_OPTIONS);
1322
1325
  await secondWriter.markAllSnapshotDone('2/1');
1323
1326
  await secondWriter.commit('2/1');
@@ -1360,7 +1363,7 @@ streams:
1360
1363
  { storageVersion }
1361
1364
  )
1362
1365
  );
1363
- const activeStorage = factory.getInstance(active) as MongoSyncBucketStorage;
1366
+ const activeStorage = (await getTestStorage(factory, active)) as MongoSyncBucketStorage;
1364
1367
  await using activeWriter = await activeStorage.createWriter(test_utils.BATCH_OPTIONS);
1365
1368
  await activeWriter.markAllSnapshotDone('1/1');
1366
1369
  await activeWriter.commit('1/1');
@@ -1396,7 +1399,7 @@ streams:
1396
1399
  { storageVersion }
1397
1400
  )
1398
1401
  );
1399
- const activeStorage = factory.getInstance(active) as MongoSyncBucketStorage;
1402
+ const activeStorage = (await getTestStorage(factory, active)) as MongoSyncBucketStorage;
1400
1403
  await using activeWriter = await activeStorage.createWriter(test_utils.BATCH_OPTIONS);
1401
1404
  await activeWriter.markAllSnapshotDone('1/1');
1402
1405
  await activeWriter.commit('1/1');
@@ -1455,7 +1458,7 @@ streams:
1455
1458
  { storageVersion }
1456
1459
  )
1457
1460
  );
1458
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1461
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1459
1462
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1460
1463
  const sourceTable = await test_utils.resolveTestTable(
1461
1464
  firstWriter,
@@ -1505,7 +1508,7 @@ streams:
1505
1508
 
1506
1509
  const replicatingStreams = await factory.getReplicatingReplicationStreams();
1507
1510
  expect(replicatingStreams).toHaveLength(1);
1508
- const secondStorage = factory.getInstance(replicatingStreams[0]) as MongoSyncBucketStorage;
1511
+ const secondStorage = (await getTestStorage(factory, replicatingStreams[0])) as MongoSyncBucketStorage;
1509
1512
  await using secondWriter = await secondStorage.createWriter(test_utils.BATCH_OPTIONS);
1510
1513
  // No new data replicated - just complete the snapshot and commit.
1511
1514
  await secondWriter.markAllSnapshotDone('2/1');
@@ -1524,7 +1527,10 @@ streams:
1524
1527
  expect(head).toBeGreaterThanOrEqual(firstCheckpoint);
1525
1528
 
1526
1529
  // After activation, the active config's checkpoint does not regress.
1527
- const activeStorage = (await factory.getActiveSyncConfig())?.storage as MongoSyncBucketStorage;
1530
+ const activeStorage = (await getTestStorage(
1531
+ factory,
1532
+ (await factory.getActiveSyncConfig())!.replicationStream
1533
+ )) as MongoSyncBucketStorage;
1528
1534
  const activeCheckpoint = (await activeStorage.getCheckpoint()).checkpoint;
1529
1535
  expect(activeCheckpoint).toBeGreaterThanOrEqual(firstCheckpoint);
1530
1536
  }
@@ -1546,7 +1552,7 @@ streams:
1546
1552
  { storageVersion }
1547
1553
  )
1548
1554
  );
1549
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1555
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1550
1556
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1551
1557
  await firstWriter.markAllSnapshotDone('1/1');
1552
1558
  await firstWriter.commit('1/1');
@@ -1593,7 +1599,7 @@ streams:
1593
1599
  { storageVersion }
1594
1600
  )
1595
1601
  );
1596
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1602
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1597
1603
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1598
1604
  await firstWriter.markAllSnapshotDone('1/1');
1599
1605
  await firstWriter.commit('1/1');
@@ -1608,7 +1614,7 @@ streams:
1608
1614
  await using factory = await storageConfig.factory();
1609
1615
 
1610
1616
  const first = await factory.updateSyncRules(updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion }));
1611
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1617
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1612
1618
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1613
1619
  await firstWriter.markAllSnapshotDone('1/1');
1614
1620
  await firstWriter.commit('1/1');
@@ -1681,7 +1687,7 @@ streams:
1681
1687
  const first = await factory.updateSyncRules(updateSyncRulesFromYaml(firstRules, { storageVersion, lock: true }));
1682
1688
  expect(first.current_lock?.sync_rules_id).toBe(first.replicationStreamId);
1683
1689
  try {
1684
- const firstStorage = factory.getInstance(first);
1690
+ const firstStorage = factory.getInstance(first, { replicationLock: first.current_lock! });
1685
1691
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1686
1692
  await firstWriter.markAllSnapshotDone('1/1');
1687
1693
  await firstWriter.commit('1/1');
@@ -1709,7 +1715,7 @@ streams:
1709
1715
  { storageVersion }
1710
1716
  )
1711
1717
  );
1712
- const bucketStorage = factory.getInstance(syncRules);
1718
+ const bucketStorage = await getTestStorage(factory, syncRules);
1713
1719
 
1714
1720
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1715
1721
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], INITIALIZED_MONGO_STORAGE_FACTORY);
@@ -1748,7 +1754,7 @@ streams:
1748
1754
  { storageVersion }
1749
1755
  )
1750
1756
  );
1751
- const bucketStorage = factory.getInstance(syncRules);
1757
+ const bucketStorage = await getTestStorage(factory, syncRules);
1752
1758
 
1753
1759
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1754
1760
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], INITIALIZED_MONGO_STORAGE_FACTORY);
@@ -1782,7 +1788,7 @@ streams:
1782
1788
  storageVersion
1783
1789
  })
1784
1790
  );
1785
- const bucketStorage = factory.getInstance(syncRules);
1791
+ const bucketStorage = await getTestStorage(factory, syncRules);
1786
1792
  const mongoFactory = factory as MongoBucketStorage;
1787
1793
  const sourceTableId = new bson.ObjectId();
1788
1794
  const documents = Array.from({ length: 10_002 }, (_, index) => ({
@@ -1825,7 +1831,7 @@ streams:
1825
1831
  storageVersion
1826
1832
  })
1827
1833
  );
1828
- const bucketStorage = factory.getInstance(syncRules);
1834
+ const bucketStorage = await getTestStorage(factory, syncRules);
1829
1835
  const mongoFactory = factory as MongoBucketStorage;
1830
1836
  const sourceTableId = new bson.ObjectId();
1831
1837
  const documents = Array.from({ length: 10_002 }, (_, index) => ({
@@ -1876,7 +1882,7 @@ streams:
1876
1882
  { storageVersion }
1877
1883
  )
1878
1884
  );
1879
- const bucketStorage = factory.getInstance(syncRules);
1885
+ const bucketStorage = await getTestStorage(factory, syncRules);
1880
1886
  const metricsBefore = await factory.getStorageMetrics();
1881
1887
 
1882
1888
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
@@ -1939,7 +1945,7 @@ streams:
1939
1945
  { storageVersion }
1940
1946
  )
1941
1947
  );
1942
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
1948
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
1943
1949
  const previousCheckpoint = await bucketStorage.getCheckpoint();
1944
1950
 
1945
1951
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
@@ -1984,7 +1990,7 @@ streams:
1984
1990
  );
1985
1991
 
1986
1992
  const mongoFactory = factory as MongoBucketStorage;
1987
- const bucketStorage = mongoFactory.getInstance(syncRules);
1993
+ const bucketStorage = await getTestStorage(mongoFactory, syncRules);
1988
1994
  const db = bucketStorage.db as VersionedPowerSyncMongoV3;
1989
1995
  await db.initializeStreamStorage(syncRules.replicationStreamId);
1990
1996
 
@@ -2079,7 +2085,7 @@ describe('sync - mongodb', () => {
2079
2085
  const legacySyncRules = await factory.updateSyncRules(
2080
2086
  updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion: storage.LEGACY_STORAGE_VERSION })
2081
2087
  );
2082
- const legacyStorage = factory.getInstance(legacySyncRules);
2088
+ const legacyStorage = await getTestStorage(factory, legacySyncRules);
2083
2089
  await using legacyWriter = await legacyStorage.createWriter(test_utils.BATCH_OPTIONS);
2084
2090
  await legacyWriter.markAllSnapshotDone('1/1');
2085
2091
  await legacyWriter.commit('1/1');
@@ -2091,7 +2097,7 @@ describe('sync - mongodb', () => {
2091
2097
  const v3SyncRules = await factory.updateSyncRules(
2092
2098
  updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion: storage.STORAGE_VERSION_3 })
2093
2099
  );
2094
- const v3Storage = factory.getInstance(v3SyncRules);
2100
+ const v3Storage = await getTestStorage(factory, v3SyncRules);
2095
2101
  await using v3Writer = await v3Storage.createWriter(test_utils.BATCH_OPTIONS);
2096
2102
  await v3Writer.markAllSnapshotDone('2/1');
2097
2103
  await v3Writer.commit('2/1');
@@ -2119,7 +2125,7 @@ describe('sync - mongodb', () => {
2119
2125
  { storageVersion }
2120
2126
  )
2121
2127
  );
2122
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
2128
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
2123
2129
  const db = bucketStorage.db as VersionedPowerSyncMongoV3;
2124
2130
  const mapping = syncRules.syncConfigContent[0].mapping;
2125
2131
 
@@ -2251,7 +2257,7 @@ describe('sync - mongodb', () => {
2251
2257
  { storageVersion }
2252
2258
  )
2253
2259
  );
2254
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorageV3;
2260
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorageV3;
2255
2261
  const db = bucketStorage.db as VersionedPowerSyncMongoV3;
2256
2262
 
2257
2263
  const start = 5n;
@@ -1,5 +1,5 @@
1
1
  import { storage, updateSyncRulesFromYaml } from '@powersync/service-core';
2
- import { bucketRequest, test_utils } from '@powersync/service-core-tests';
2
+ import { bucketRequest, getTestStorage, test_utils } from '@powersync/service-core-tests';
3
3
  import * as bson from 'bson';
4
4
  import { describe, expect, test } from 'vitest';
5
5
  import { MongoBucketStorage } from '../../src/storage/MongoBucketStorage.js';
@@ -80,7 +80,7 @@ function registerStoreCurrentDataTests(storageVersion: number) {
80
80
  test('resolveTables derives storeCurrentData fresh each call, with no persisted memory', async () => {
81
81
  await using factory = await INITIALIZED_MONGO_STORAGE_FACTORY.factory();
82
82
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES, { storageVersion }));
83
- const bucketStorage = factory.getInstance(syncRules);
83
+ const bucketStorage = await getTestStorage(factory, syncRules);
84
84
  const syncRulesContent = syncRules.syncConfigContent[0];
85
85
 
86
86
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
@@ -114,7 +114,7 @@ function registerStoreCurrentDataTests(storageVersion: number) {
114
114
  test('storeCurrentData=false omits the row payload from current_data, data still syncs', async () => {
115
115
  await using factory = await INITIALIZED_MONGO_STORAGE_FACTORY.factory();
116
116
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES, { storageVersion }));
117
- const bucketStorage = factory.getInstance(syncRules);
117
+ const bucketStorage = await getTestStorage(factory, syncRules);
118
118
  const syncRulesContent = syncRules.syncConfigContent[0];
119
119
 
120
120
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
@@ -146,7 +146,7 @@ function registerStoreCurrentDataTests(storageVersion: number) {
146
146
  test('storeCurrentData=true retains the row payload in current_data', async () => {
147
147
  await using factory = await INITIALIZED_MONGO_STORAGE_FACTORY.factory();
148
148
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES, { storageVersion }));
149
- const bucketStorage = factory.getInstance(syncRules);
149
+ const bucketStorage = await getTestStorage(factory, syncRules);
150
150
  const syncRulesContent = syncRules.syncConfigContent[0];
151
151
 
152
152
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
@@ -179,7 +179,7 @@ function registerStoreCurrentDataTests(storageVersion: number) {
179
179
  test('storeCurrentData=false processes UPDATE without a stored copy', async () => {
180
180
  await using factory = await INITIALIZED_MONGO_STORAGE_FACTORY.factory();
181
181
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES, { storageVersion }));
182
- const bucketStorage = factory.getInstance(syncRules);
182
+ const bucketStorage = await getTestStorage(factory, syncRules);
183
183
  const syncRulesContent = syncRules.syncConfigContent[0];
184
184
 
185
185
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);