@powersync/service-module-mongodb-storage 0.0.0-dev-20260909133214 → 0.0.0-dev-20260929095716

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 (140) hide show
  1. package/CHANGELOG.md +52 -6
  2. package/dist/storage/MongoBucketStorage.d.ts +11 -2
  3. package/dist/storage/MongoBucketStorage.js +43 -13
  4. package/dist/storage/MongoBucketStorage.js.map +1 -1
  5. package/dist/storage/implementation/MongoBucketBatch.d.ts +24 -10
  6. package/dist/storage/implementation/MongoBucketBatch.js +134 -89
  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/MongoParsedSyncConfigSet.js +6 -2
  17. package/dist/storage/implementation/MongoParsedSyncConfigSet.js.map +1 -1
  18. package/dist/storage/implementation/MongoPersistedReplicationStream.d.ts +2 -1
  19. package/dist/storage/implementation/MongoPersistedReplicationStream.js +7 -4
  20. package/dist/storage/implementation/MongoPersistedReplicationStream.js.map +1 -1
  21. package/dist/storage/implementation/MongoPersistedSyncConfigContent.d.ts +3 -3
  22. package/dist/storage/implementation/MongoPersistedSyncConfigContent.js +6 -6
  23. package/dist/storage/implementation/MongoPersistedSyncConfigContent.js.map +1 -1
  24. package/dist/storage/implementation/MongoStorageProvider.js +5 -3
  25. package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
  26. package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +5 -0
  27. package/dist/storage/implementation/MongoSyncBucketStorage.js +17 -0
  28. package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
  29. package/dist/storage/implementation/MongoSyncRulesLock.d.ts +26 -2
  30. package/dist/storage/implementation/MongoSyncRulesLock.js +38 -1
  31. package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
  32. package/dist/storage/implementation/MongoWriteBatch.d.ts +49 -0
  33. package/dist/storage/implementation/MongoWriteBatch.js +149 -0
  34. package/dist/storage/implementation/MongoWriteBatch.js.map +1 -0
  35. package/dist/storage/implementation/MongoWriteCheckpointAPI.js +2 -2
  36. package/dist/storage/implementation/MongoWriteCheckpointAPI.js.map +1 -1
  37. package/dist/storage/implementation/common/PersistedBatch.d.ts +5 -4
  38. package/dist/storage/implementation/common/PersistedBatch.js +6 -4
  39. package/dist/storage/implementation/common/PersistedBatch.js.map +1 -1
  40. package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.d.ts +3 -0
  41. package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js +3 -0
  42. package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js.map +1 -1
  43. package/dist/storage/implementation/db.d.ts +5 -0
  44. package/dist/storage/implementation/db.js +14 -0
  45. package/dist/storage/implementation/db.js.map +1 -1
  46. package/dist/storage/implementation/v1/MongoBucketBatchV1.d.ts +5 -0
  47. package/dist/storage/implementation/v1/MongoBucketBatchV1.js +149 -139
  48. package/dist/storage/implementation/v1/MongoBucketBatchV1.js.map +1 -1
  49. package/dist/storage/implementation/v1/MongoCompactorV1.d.ts +2 -1
  50. package/dist/storage/implementation/v1/MongoCompactorV1.js +23 -17
  51. package/dist/storage/implementation/v1/MongoCompactorV1.js.map +1 -1
  52. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js +1 -1
  53. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js.map +1 -1
  54. package/dist/storage/implementation/v1/PersistedBatchV1.d.ts +7 -5
  55. package/dist/storage/implementation/v1/PersistedBatchV1.js +22 -28
  56. package/dist/storage/implementation/v1/PersistedBatchV1.js.map +1 -1
  57. package/dist/storage/implementation/v3/MongoBucketBatchV3.d.ts +6 -1
  58. package/dist/storage/implementation/v3/MongoBucketBatchV3.js +148 -162
  59. package/dist/storage/implementation/v3/MongoBucketBatchV3.js.map +1 -1
  60. package/dist/storage/implementation/v3/MongoCompactorV3.d.ts +10 -4
  61. package/dist/storage/implementation/v3/MongoCompactorV3.js +175 -76
  62. package/dist/storage/implementation/v3/MongoCompactorV3.js.map +1 -1
  63. package/dist/storage/implementation/v3/PersistedBatchV3.d.ts +12 -8
  64. package/dist/storage/implementation/v3/PersistedBatchV3.js +25 -32
  65. package/dist/storage/implementation/v3/PersistedBatchV3.js.map +1 -1
  66. package/dist/storage/implementation/v3/compact-utils.d.ts +3 -2
  67. package/dist/storage/implementation/v3/compact-utils.js +12 -5
  68. package/dist/storage/implementation/v3/compact-utils.js.map +1 -1
  69. package/dist/storage/implementation/v3/models.d.ts +1 -1
  70. package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.js +8 -1
  71. package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.js.map +1 -1
  72. package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.d.ts +3 -3
  73. package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.js +7 -9
  74. package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.js.map +1 -1
  75. package/dist/storage/implementation/v3/object-storage/ObjectStorageUsage.d.ts +3 -2
  76. package/dist/storage/implementation/v3/object-storage/ObjectStorageUsage.js +4 -7
  77. package/dist/storage/implementation/v3/object-storage/ObjectStorageUsage.js.map +1 -1
  78. package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.js +21 -3
  79. package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.js.map +1 -1
  80. package/dist/types/types.d.ts +5 -0
  81. package/dist/types/types.js +12 -0
  82. package/dist/types/types.js.map +1 -1
  83. package/dist/utils/test-utils.d.ts +4 -2
  84. package/dist/utils/test-utils.js +7 -4
  85. package/dist/utils/test-utils.js.map +1 -1
  86. package/package.json +6 -6
  87. package/src/storage/MongoBucketStorage.ts +54 -13
  88. package/src/storage/implementation/MongoBucketBatch.ts +205 -111
  89. package/src/storage/implementation/MongoCompactor.ts +2 -0
  90. package/src/storage/implementation/MongoIdSequence.ts +21 -1
  91. package/src/storage/implementation/MongoOpIdAllocator.ts +105 -0
  92. package/src/storage/implementation/MongoParsedSyncConfigSet.ts +12 -1
  93. package/src/storage/implementation/MongoPersistedReplicationStream.ts +12 -4
  94. package/src/storage/implementation/MongoPersistedSyncConfigContent.ts +48 -31
  95. package/src/storage/implementation/MongoStorageProvider.ts +13 -3
  96. package/src/storage/implementation/MongoSyncBucketStorage.ts +19 -0
  97. package/src/storage/implementation/MongoSyncRulesLock.ts +56 -3
  98. package/src/storage/implementation/MongoWriteBatch.ts +172 -0
  99. package/src/storage/implementation/MongoWriteCheckpointAPI.ts +4 -2
  100. package/src/storage/implementation/common/PersistedBatch.ts +12 -8
  101. package/src/storage/implementation/common/VersionedPowerSyncMongoBase.ts +4 -0
  102. package/src/storage/implementation/db.ts +15 -0
  103. package/src/storage/implementation/models.ts +1 -0
  104. package/src/storage/implementation/v1/MongoBucketBatchV1.ts +167 -160
  105. package/src/storage/implementation/v1/MongoCompactorV1.ts +29 -26
  106. package/src/storage/implementation/v1/MongoSyncBucketStorageV1.ts +1 -1
  107. package/src/storage/implementation/v1/PersistedBatchV1.ts +25 -30
  108. package/src/storage/implementation/v3/MongoBucketBatchV3.ts +217 -242
  109. package/src/storage/implementation/v3/MongoCompactorV3.ts +284 -108
  110. package/src/storage/implementation/v3/PersistedBatchV3.ts +36 -36
  111. package/src/storage/implementation/v3/compact-utils.ts +16 -7
  112. package/src/storage/implementation/v3/models.ts +1 -1
  113. package/src/storage/implementation/v3/object-storage/BucketDataObjectStorage.ts +8 -1
  114. package/src/storage/implementation/v3/object-storage/ObjectStorageLifecycle.ts +11 -10
  115. package/src/storage/implementation/v3/object-storage/ObjectStorageUsage.ts +8 -9
  116. package/src/storage/implementation/v3/object-storage/S3ObjectStorage.ts +23 -3
  117. package/src/types/types.ts +18 -0
  118. package/src/utils/test-utils.ts +9 -5
  119. package/test/src/__snapshots__/storage_sync.test.ts.snap +12 -12
  120. package/test/src/chunk_compaction_config.test.ts +38 -0
  121. package/test/src/cleanup-stopped-sync-configs.test.ts +19 -13
  122. package/test/src/compact-utils.test.ts +33 -8
  123. package/test/src/concurrent_writers.test.ts +599 -0
  124. package/test/src/connection_config.test.ts +159 -0
  125. package/test/src/helpers/concurrentWriter.mjs +29 -0
  126. package/test/src/helpers/s3TestFactory.ts +12 -12
  127. package/test/src/object_storage_usage.test.ts +18 -5
  128. package/test/src/parameter_compacting_v1.test.ts +2 -2
  129. package/test/src/parameter_compacting_v3.test.ts +2 -2
  130. package/test/src/parameter_compaction_fence.test.ts +3 -3
  131. package/test/src/storage.test.ts +15 -10
  132. package/test/src/storage_compacting.test.ts +397 -23
  133. package/test/src/storage_object_storage_inline_threshold.test.ts +3 -3
  134. package/test/src/storage_s3_checksums.test.ts +4 -4
  135. package/test/src/storage_s3_compaction_lifecycle.test.ts +8 -8
  136. package/test/src/storage_s3_reading.test.ts +51 -5
  137. package/test/src/storage_s3_writing.test.ts +3 -3
  138. package/test/src/storage_sync.test.ts +55 -47
  139. package/test/src/storeCurrentData.test.ts +5 -5
  140. 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,8 +1,8 @@
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
- import { describe, expect, test } from 'vitest';
5
+ import { describe, expect, test, vi } from 'vitest';
6
6
  import { MongoSyncBucketStorage } from '../../src/storage/implementation/createMongoSyncBucketStorage.js';
7
7
  import { VersionedPowerSyncMongoV3 } from '../../src/storage/implementation/v3/VersionedPowerSyncMongoV3.js';
8
8
  import { hydrateBucketDataDocuments } from '../../src/storage/implementation/v3/object-storage/BucketDataObjectStorage.js';
@@ -576,6 +576,52 @@ describe('S3 object storage reads', () => {
576
576
  expect(maxActiveOperations).toBe(4);
577
577
  });
578
578
 
579
+ test('drains sibling downloads before reporting a hydration failure', async () => {
580
+ const objectStorage = new MemoryObjectStorage();
581
+ const gate = Promise.withResolvers<void>();
582
+ const failure = new Error('download failed');
583
+ const documents = ['failed', 'pending'].map((path, index) => ({
584
+ _id: { b: 'bucket', o: BigInt(index + 1) },
585
+ min_op: BigInt(index + 1),
586
+ checksum: 0n,
587
+ count: 0,
588
+ size: 1,
589
+ storage_ref: { path, file_size: 1 }
590
+ }));
591
+ const get = vi.spyOn(objectStorage, 'get').mockImplementation(async (path) => {
592
+ if (path === 'failed') {
593
+ throw failure;
594
+ }
595
+ await gate.promise;
596
+ return {
597
+ data: bson.serialize({ ops: [] }),
598
+ metadata: { contentType: 'application/bson', contentEncoding: null }
599
+ };
600
+ });
601
+ let settled = false;
602
+ const result = hydrateBucketDataDocuments(documents, objectStorage, {}).then(
603
+ () => {
604
+ settled = true;
605
+ return undefined;
606
+ },
607
+ (error) => {
608
+ settled = true;
609
+ return error;
610
+ }
611
+ );
612
+ try {
613
+ await vi.waitFor(() => expect(get).toHaveBeenCalledTimes(2));
614
+ await new Promise<void>((resolve) => setImmediate(resolve));
615
+ expect(settled).toBe(false);
616
+ } finally {
617
+ gate.resolve();
618
+ await result;
619
+ get.mockRestore();
620
+ }
621
+ expect(await result).toBe(failure);
622
+ expect(documents[1]).toHaveProperty('ops', []);
623
+ });
624
+
579
625
  test('aborts active object downloads', async () => {
580
626
  const objectStorage = new MemoryObjectStorage();
581
627
  const controller = new AbortController();
@@ -616,7 +662,7 @@ describe('S3 object storage reads', () => {
616
662
  const { memoryStorage, factory: factoryGen } = memoryS3Factory();
617
663
  await using factory = await factoryGen.factory();
618
664
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
619
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
665
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
620
666
 
621
667
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
622
668
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 1);
@@ -664,7 +710,7 @@ describe('S3 object storage reads', () => {
664
710
  const { factory: factoryGen } = s3Factory();
665
711
  await using factory = await factoryGen.factory();
666
712
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
667
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
713
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
668
714
 
669
715
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
670
716
  const sourceTable = await test_utils.resolveTestTable(writer, 'items', ['id'], factoryGen, 1);
@@ -717,7 +763,7 @@ describe('S3 object storage reads', () => {
717
763
  const { memoryStorage, factory: factoryGen } = memoryS3Factory({ inlineThresholdBytes: 1_000 });
718
764
  await using factory = await factoryGen.factory();
719
765
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(SYNC_RULES_YAML, { storageVersion: 3 }));
720
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
766
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
721
767
 
722
768
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
723
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';
@@ -99,7 +99,9 @@ async function getMongoSyncConfigContents(factory: storage.BucketStorageFactory,
99
99
  })
100
100
  .toArray();
101
101
 
102
- return syncConfigDocs.map((config) => new MongoPersistedSyncConfigContentV3(mongoFactory.db, doc, config));
102
+ return syncConfigDocs.map(
103
+ (config) => new MongoPersistedSyncConfigContentV3(mongoFactory.db, doc, config, mongoFactory.syncConfigParser)
104
+ );
103
105
  }
104
106
 
105
107
  /**
@@ -149,7 +151,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
149
151
  test('updates source metadata on an existing resolved table', async () => {
150
152
  await using factory = await storageConfig.factory();
151
153
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion }));
152
- const bucketStorage = factory.getInstance(syncRules);
154
+ const bucketStorage = await getTestStorage(factory, syncRules);
153
155
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
154
156
  const source = sourceDescriptor('test');
155
157
 
@@ -191,7 +193,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
191
193
  { storageVersion }
192
194
  )
193
195
  );
194
- const bucketStorage = factory.getInstance(syncRules);
196
+ const bucketStorage = await getTestStorage(factory, syncRules);
195
197
  const syncRulesContent = syncRules.syncConfigContent[0];
196
198
 
197
199
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
@@ -338,7 +340,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
338
340
  { storageVersion }
339
341
  )
340
342
  );
341
- const bucketStorage = factory.getInstance(syncRules);
343
+ const bucketStorage = await getTestStorage(factory, syncRules);
342
344
 
343
345
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
344
346
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], INITIALIZED_MONGO_STORAGE_FACTORY);
@@ -363,7 +365,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
363
365
  { storageVersion }
364
366
  )
365
367
  );
366
- const bucketStorage = factory.getInstance(syncRules);
368
+ const bucketStorage = await getTestStorage(factory, syncRules);
367
369
 
368
370
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
369
371
  const before = await writer.resolveTables({
@@ -401,7 +403,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
401
403
  { storageVersion }
402
404
  )
403
405
  );
404
- const bucketStorage = factory.getInstance(syncRules);
406
+ const bucketStorage = await getTestStorage(factory, syncRules);
405
407
 
406
408
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
407
409
  const before = await writer.resolveTables({
@@ -437,7 +439,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
437
439
  { storageVersion }
438
440
  )
439
441
  );
440
- const bucketStorage = factory.getInstance(syncRules);
442
+ const bucketStorage = await getTestStorage(factory, syncRules);
441
443
 
442
444
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
443
445
  const before = await writer.resolveTables({
@@ -481,7 +483,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
481
483
  { storageVersion }
482
484
  )
483
485
  );
484
- const bucketStorage = factory.getInstance(syncRules);
486
+ const bucketStorage = await getTestStorage(factory, syncRules);
485
487
 
486
488
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
487
489
  const resolved = await writer.resolveTables({
@@ -550,7 +552,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
550
552
  // Here we're persisting one sync config, then resolving tables with others.
551
553
  // We're also using the default hydration state for them all.
552
554
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(fullRulesYaml, { storageVersion }));
553
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
555
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
554
556
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
555
557
  const fullRules = parsedSyncConfigSetFor(fullRulesYaml, storageVersion);
556
558
  const dataOnlyRules = parsedSyncConfigSetFor(dataOnlyRulesYaml, storageVersion);
@@ -666,7 +668,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
666
668
 
667
669
  await using factory = await storageConfig.factory();
668
670
  const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(dataOnlyEventYaml, { storageVersion }));
669
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
671
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
670
672
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
671
673
  const dataOnlyRules = parsedSyncConfigSetFor(dataOnlyEventYaml, storageVersion);
672
674
  const fullRules = parsedSyncConfigSetFor(fullEventYaml, storageVersion);
@@ -739,7 +741,7 @@ event_definitions:
739
741
  });
740
742
  try {
741
743
  const first = await factory.updateSyncRules(updateSyncRulesFromYaml(firstYaml, { storageVersion }));
742
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
744
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
743
745
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
744
746
  const source = sourceDescriptor('checkpoints', { objectId: 'checkpoints-relation' });
745
747
  const firstResolved = await firstWriter.resolveTables({
@@ -755,7 +757,7 @@ event_definitions:
755
757
 
756
758
  const second = await factory.updateSyncRules(updateSyncRulesFromYaml(secondYaml, { storageVersion }));
757
759
  expect(second.replicationStreamId).toBe(first.replicationStreamId);
758
- const secondStorage = factory.getInstance(second) as MongoSyncBucketStorage;
760
+ const secondStorage = (await getTestStorage(factory, second)) as MongoSyncBucketStorage;
759
761
  await using secondWriter = await secondStorage.createWriter(test_utils.BATCH_OPTIONS);
760
762
  const resolved = await secondWriter.resolveTables({
761
763
  connection_id: 1,
@@ -806,7 +808,7 @@ event_definitions:
806
808
  });
807
809
  try {
808
810
  const first = await factory.updateSyncRules(updateSyncRulesFromYaml(yaml(true), { storageVersion }));
809
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
811
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
810
812
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
811
813
  const source = sourceDescriptor('checkpoints', { objectId: 'checkpoints-relation' });
812
814
  const firstResolved = await firstWriter.resolveTables({
@@ -821,7 +823,7 @@ event_definitions:
821
823
 
822
824
  const second = await factory.updateSyncRules(updateSyncRulesFromYaml(yaml(false), { storageVersion }));
823
825
  expect(second.replicationStreamId).toBe(first.replicationStreamId);
824
- const secondStorage = factory.getInstance(second) as MongoSyncBucketStorage;
826
+ const secondStorage = (await getTestStorage(factory, second)) as MongoSyncBucketStorage;
825
827
  await using secondWriter = await secondStorage.createWriter(test_utils.BATCH_OPTIONS);
826
828
  const resolved = await secondWriter.resolveTables({
827
829
  connection_id: 1,
@@ -875,7 +877,7 @@ event_definitions:
875
877
  { storageVersion }
876
878
  )
877
879
  );
878
- const bucketStorage = factory.getInstance(syncRules);
880
+ const bucketStorage = await getTestStorage(factory, syncRules);
879
881
  const syncRulesContent = syncRules.syncConfigContent[0];
880
882
  const sync_rules = syncRulesContent.parsed(test_utils.PARSE_OPTIONS).hydratedSyncConfig;
881
883
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
@@ -988,7 +990,7 @@ streams:
988
990
  expect(parsed.syncConfigs).toHaveLength(1);
989
991
  expect(parsed.hydratedSyncConfig.bucketDataSources).toHaveLength(1);
990
992
 
991
- const bucketStorage = factory.getInstance(replicatingStreams[0]);
993
+ const bucketStorage = await getTestStorage(factory, replicatingStreams[0]);
992
994
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
993
995
  const resolved = await writer.resolveTables({
994
996
  connection_id: 1,
@@ -1015,7 +1017,7 @@ streams:
1015
1017
  { storageVersion }
1016
1018
  )
1017
1019
  );
1018
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1020
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1019
1021
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1020
1022
  await firstWriter.markAllSnapshotDone('1/1');
1021
1023
  await firstWriter.commit('1/1');
@@ -1035,7 +1037,7 @@ streams:
1035
1037
  );
1036
1038
  expect(second.replicationStreamId).toEqual(first.replicationStreamId);
1037
1039
 
1038
- const bucketStorage = factory.getInstance(second);
1040
+ const bucketStorage = await getTestStorage(factory, second);
1039
1041
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1040
1042
  const source = sourceDescriptor('todos', { objectId: 'todos-relation' });
1041
1043
 
@@ -1050,7 +1052,10 @@ streams:
1050
1052
  await writer.markAllSnapshotDone('2/1');
1051
1053
  await writer.commit('2/1');
1052
1054
 
1053
- const activeStorage = (await factory.getActiveSyncConfig())?.storage as MongoSyncBucketStorage;
1055
+ const activeStorage = (await getTestStorage(
1056
+ factory,
1057
+ (await factory.getActiveSyncConfig())!.replicationStream
1058
+ )) as MongoSyncBucketStorage;
1054
1059
  await using activeWriter = await activeStorage.createWriter(test_utils.BATCH_OPTIONS);
1055
1060
  const activeStatus = await activeWriter.getSourceTableStatus(resolved.tables[0]);
1056
1061
  expect(activeStatus?.bucketDataSources).toHaveLength(1);
@@ -1074,7 +1079,7 @@ streams:
1074
1079
  { storageVersion }
1075
1080
  )
1076
1081
  );
1077
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1082
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1078
1083
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1079
1084
  const source = sourceDescriptor('todos', { objectId: 'todos-relation' });
1080
1085
  const firstResolved = await firstWriter.resolveTables({
@@ -1103,7 +1108,7 @@ streams:
1103
1108
 
1104
1109
  const deploying = await factory.getDeployingSyncConfig();
1105
1110
  expect(deploying?.replicationStream.replicationStreamId).toBe(first.replicationStreamId);
1106
- const bucketStorage = deploying!.storage;
1111
+ const bucketStorage = await getTestStorage(factory, deploying!.replicationStream);
1107
1112
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1108
1113
  const resolved = await writer.resolveTables({
1109
1114
  connection_id: 1,
@@ -1149,7 +1154,7 @@ streams:
1149
1154
  `;
1150
1155
 
1151
1156
  const first = await factory.updateSyncRules(updateSyncRulesFromYaml(ownerRules, { storageVersion }));
1152
- const firstStorage = factory.getInstance(first);
1157
+ const firstStorage = await getTestStorage(factory, first);
1153
1158
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1154
1159
  await firstWriter.markAllSnapshotDone('1/1');
1155
1160
  await firstWriter.commit('1/1');
@@ -1201,7 +1206,7 @@ streams:
1201
1206
  { storageVersion }
1202
1207
  )
1203
1208
  );
1204
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1209
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1205
1210
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1206
1211
  await firstWriter.markAllSnapshotDone('1/1');
1207
1212
  await firstWriter.commit('1/1');
@@ -1223,7 +1228,7 @@ streams:
1223
1228
  );
1224
1229
  expect(second.replicationStreamId).toBe(first.replicationStreamId);
1225
1230
 
1226
- const bucketStorage = factory.getInstance(second);
1231
+ const bucketStorage = await getTestStorage(factory, second);
1227
1232
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1228
1233
  const resolved = await writer.resolveTables({
1229
1234
  connection_id: 1,
@@ -1274,7 +1279,7 @@ streams:
1274
1279
  { storageVersion }
1275
1280
  )
1276
1281
  );
1277
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1282
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1278
1283
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1279
1284
  await firstWriter.markAllSnapshotDone('1/1');
1280
1285
  await firstWriter.commit('1/1');
@@ -1317,7 +1322,7 @@ streams:
1317
1322
  expect(replicatingStreams[0].replicationJobId).toContain(config.syncConfigId);
1318
1323
  }
1319
1324
 
1320
- const secondStorage = factory.getInstance(replicatingStreams[0]) as MongoSyncBucketStorage;
1325
+ const secondStorage = (await getTestStorage(factory, replicatingStreams[0])) as MongoSyncBucketStorage;
1321
1326
  await using secondWriter = await secondStorage.createWriter(test_utils.BATCH_OPTIONS);
1322
1327
  await secondWriter.markAllSnapshotDone('2/1');
1323
1328
  await secondWriter.commit('2/1');
@@ -1360,7 +1365,7 @@ streams:
1360
1365
  { storageVersion }
1361
1366
  )
1362
1367
  );
1363
- const activeStorage = factory.getInstance(active) as MongoSyncBucketStorage;
1368
+ const activeStorage = (await getTestStorage(factory, active)) as MongoSyncBucketStorage;
1364
1369
  await using activeWriter = await activeStorage.createWriter(test_utils.BATCH_OPTIONS);
1365
1370
  await activeWriter.markAllSnapshotDone('1/1');
1366
1371
  await activeWriter.commit('1/1');
@@ -1396,7 +1401,7 @@ streams:
1396
1401
  { storageVersion }
1397
1402
  )
1398
1403
  );
1399
- const activeStorage = factory.getInstance(active) as MongoSyncBucketStorage;
1404
+ const activeStorage = (await getTestStorage(factory, active)) as MongoSyncBucketStorage;
1400
1405
  await using activeWriter = await activeStorage.createWriter(test_utils.BATCH_OPTIONS);
1401
1406
  await activeWriter.markAllSnapshotDone('1/1');
1402
1407
  await activeWriter.commit('1/1');
@@ -1455,7 +1460,7 @@ streams:
1455
1460
  { storageVersion }
1456
1461
  )
1457
1462
  );
1458
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1463
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1459
1464
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1460
1465
  const sourceTable = await test_utils.resolveTestTable(
1461
1466
  firstWriter,
@@ -1505,7 +1510,7 @@ streams:
1505
1510
 
1506
1511
  const replicatingStreams = await factory.getReplicatingReplicationStreams();
1507
1512
  expect(replicatingStreams).toHaveLength(1);
1508
- const secondStorage = factory.getInstance(replicatingStreams[0]) as MongoSyncBucketStorage;
1513
+ const secondStorage = (await getTestStorage(factory, replicatingStreams[0])) as MongoSyncBucketStorage;
1509
1514
  await using secondWriter = await secondStorage.createWriter(test_utils.BATCH_OPTIONS);
1510
1515
  // No new data replicated - just complete the snapshot and commit.
1511
1516
  await secondWriter.markAllSnapshotDone('2/1');
@@ -1524,7 +1529,10 @@ streams:
1524
1529
  expect(head).toBeGreaterThanOrEqual(firstCheckpoint);
1525
1530
 
1526
1531
  // After activation, the active config's checkpoint does not regress.
1527
- const activeStorage = (await factory.getActiveSyncConfig())?.storage as MongoSyncBucketStorage;
1532
+ const activeStorage = (await getTestStorage(
1533
+ factory,
1534
+ (await factory.getActiveSyncConfig())!.replicationStream
1535
+ )) as MongoSyncBucketStorage;
1528
1536
  const activeCheckpoint = (await activeStorage.getCheckpoint()).checkpoint;
1529
1537
  expect(activeCheckpoint).toBeGreaterThanOrEqual(firstCheckpoint);
1530
1538
  }
@@ -1546,7 +1554,7 @@ streams:
1546
1554
  { storageVersion }
1547
1555
  )
1548
1556
  );
1549
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1557
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1550
1558
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1551
1559
  await firstWriter.markAllSnapshotDone('1/1');
1552
1560
  await firstWriter.commit('1/1');
@@ -1593,7 +1601,7 @@ streams:
1593
1601
  { storageVersion }
1594
1602
  )
1595
1603
  );
1596
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1604
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1597
1605
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1598
1606
  await firstWriter.markAllSnapshotDone('1/1');
1599
1607
  await firstWriter.commit('1/1');
@@ -1608,7 +1616,7 @@ streams:
1608
1616
  await using factory = await storageConfig.factory();
1609
1617
 
1610
1618
  const first = await factory.updateSyncRules(updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion }));
1611
- const firstStorage = factory.getInstance(first) as MongoSyncBucketStorage;
1619
+ const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
1612
1620
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1613
1621
  await firstWriter.markAllSnapshotDone('1/1');
1614
1622
  await firstWriter.commit('1/1');
@@ -1681,7 +1689,7 @@ streams:
1681
1689
  const first = await factory.updateSyncRules(updateSyncRulesFromYaml(firstRules, { storageVersion, lock: true }));
1682
1690
  expect(first.current_lock?.sync_rules_id).toBe(first.replicationStreamId);
1683
1691
  try {
1684
- const firstStorage = factory.getInstance(first);
1692
+ const firstStorage = factory.getInstance(first, { replicationLock: first.current_lock! });
1685
1693
  await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
1686
1694
  await firstWriter.markAllSnapshotDone('1/1');
1687
1695
  await firstWriter.commit('1/1');
@@ -1709,7 +1717,7 @@ streams:
1709
1717
  { storageVersion }
1710
1718
  )
1711
1719
  );
1712
- const bucketStorage = factory.getInstance(syncRules);
1720
+ const bucketStorage = await getTestStorage(factory, syncRules);
1713
1721
 
1714
1722
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1715
1723
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], INITIALIZED_MONGO_STORAGE_FACTORY);
@@ -1748,7 +1756,7 @@ streams:
1748
1756
  { storageVersion }
1749
1757
  )
1750
1758
  );
1751
- const bucketStorage = factory.getInstance(syncRules);
1759
+ const bucketStorage = await getTestStorage(factory, syncRules);
1752
1760
 
1753
1761
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1754
1762
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], INITIALIZED_MONGO_STORAGE_FACTORY);
@@ -1782,7 +1790,7 @@ streams:
1782
1790
  storageVersion
1783
1791
  })
1784
1792
  );
1785
- const bucketStorage = factory.getInstance(syncRules);
1793
+ const bucketStorage = await getTestStorage(factory, syncRules);
1786
1794
  const mongoFactory = factory as MongoBucketStorage;
1787
1795
  const sourceTableId = new bson.ObjectId();
1788
1796
  const documents = Array.from({ length: 10_002 }, (_, index) => ({
@@ -1825,7 +1833,7 @@ streams:
1825
1833
  storageVersion
1826
1834
  })
1827
1835
  );
1828
- const bucketStorage = factory.getInstance(syncRules);
1836
+ const bucketStorage = await getTestStorage(factory, syncRules);
1829
1837
  const mongoFactory = factory as MongoBucketStorage;
1830
1838
  const sourceTableId = new bson.ObjectId();
1831
1839
  const documents = Array.from({ length: 10_002 }, (_, index) => ({
@@ -1876,7 +1884,7 @@ streams:
1876
1884
  { storageVersion }
1877
1885
  )
1878
1886
  );
1879
- const bucketStorage = factory.getInstance(syncRules);
1887
+ const bucketStorage = await getTestStorage(factory, syncRules);
1880
1888
  const metricsBefore = await factory.getStorageMetrics();
1881
1889
 
1882
1890
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
@@ -1939,7 +1947,7 @@ streams:
1939
1947
  { storageVersion }
1940
1948
  )
1941
1949
  );
1942
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
1950
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
1943
1951
  const previousCheckpoint = await bucketStorage.getCheckpoint();
1944
1952
 
1945
1953
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
@@ -1984,7 +1992,7 @@ streams:
1984
1992
  );
1985
1993
 
1986
1994
  const mongoFactory = factory as MongoBucketStorage;
1987
- const bucketStorage = mongoFactory.getInstance(syncRules);
1995
+ const bucketStorage = await getTestStorage(mongoFactory, syncRules);
1988
1996
  const db = bucketStorage.db as VersionedPowerSyncMongoV3;
1989
1997
  await db.initializeStreamStorage(syncRules.replicationStreamId);
1990
1998
 
@@ -2079,7 +2087,7 @@ describe('sync - mongodb', () => {
2079
2087
  const legacySyncRules = await factory.updateSyncRules(
2080
2088
  updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion: storage.LEGACY_STORAGE_VERSION })
2081
2089
  );
2082
- const legacyStorage = factory.getInstance(legacySyncRules);
2090
+ const legacyStorage = await getTestStorage(factory, legacySyncRules);
2083
2091
  await using legacyWriter = await legacyStorage.createWriter(test_utils.BATCH_OPTIONS);
2084
2092
  await legacyWriter.markAllSnapshotDone('1/1');
2085
2093
  await legacyWriter.commit('1/1');
@@ -2091,7 +2099,7 @@ describe('sync - mongodb', () => {
2091
2099
  const v3SyncRules = await factory.updateSyncRules(
2092
2100
  updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion: storage.STORAGE_VERSION_3 })
2093
2101
  );
2094
- const v3Storage = factory.getInstance(v3SyncRules);
2102
+ const v3Storage = await getTestStorage(factory, v3SyncRules);
2095
2103
  await using v3Writer = await v3Storage.createWriter(test_utils.BATCH_OPTIONS);
2096
2104
  await v3Writer.markAllSnapshotDone('2/1');
2097
2105
  await v3Writer.commit('2/1');
@@ -2119,7 +2127,7 @@ describe('sync - mongodb', () => {
2119
2127
  { storageVersion }
2120
2128
  )
2121
2129
  );
2122
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorage;
2130
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
2123
2131
  const db = bucketStorage.db as VersionedPowerSyncMongoV3;
2124
2132
  const mapping = syncRules.syncConfigContent[0].mapping;
2125
2133
 
@@ -2251,7 +2259,7 @@ describe('sync - mongodb', () => {
2251
2259
  { storageVersion }
2252
2260
  )
2253
2261
  );
2254
- const bucketStorage = factory.getInstance(syncRules) as MongoSyncBucketStorageV3;
2262
+ const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorageV3;
2255
2263
  const db = bucketStorage.db as VersionedPowerSyncMongoV3;
2256
2264
 
2257
2265
  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);