@powersync/service-module-mongodb-storage 0.0.0-dev-20260803144812 → 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.
- package/CHANGELOG.md +129 -7
- package/dist/storage/MongoBucketStorage.d.ts +42 -5
- package/dist/storage/MongoBucketStorage.js +404 -215
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoBucketBatch.d.ts +39 -14
- package/dist/storage/implementation/MongoBucketBatch.js +169 -98
- package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
- package/dist/storage/implementation/MongoCompactor.d.ts +21 -79
- package/dist/storage/implementation/MongoCompactor.js +27 -238
- package/dist/storage/implementation/MongoCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoIdSequence.d.ts +10 -1
- package/dist/storage/implementation/MongoIdSequence.js +14 -1
- package/dist/storage/implementation/MongoIdSequence.js.map +1 -1
- package/dist/storage/implementation/MongoOpIdAllocator.d.ts +27 -0
- package/dist/storage/implementation/MongoOpIdAllocator.js +97 -0
- package/dist/storage/implementation/MongoOpIdAllocator.js.map +1 -0
- package/dist/storage/implementation/MongoParameterCompactor.d.ts +83 -10
- package/dist/storage/implementation/MongoParameterCompactor.js +309 -96
- package/dist/storage/implementation/MongoParameterCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoParsedSyncConfigSet.d.ts +9 -1
- package/dist/storage/implementation/MongoParsedSyncConfigSet.js +35 -2
- package/dist/storage/implementation/MongoParsedSyncConfigSet.js.map +1 -1
- package/dist/storage/implementation/MongoPersistedReplicationStream.d.ts +2 -1
- package/dist/storage/implementation/MongoPersistedReplicationStream.js +7 -4
- package/dist/storage/implementation/MongoPersistedReplicationStream.js.map +1 -1
- package/dist/storage/implementation/MongoPersistedSyncConfigContent.d.ts +3 -3
- package/dist/storage/implementation/MongoPersistedSyncConfigContent.js +10 -8
- package/dist/storage/implementation/MongoPersistedSyncConfigContent.js.map +1 -1
- package/dist/storage/implementation/MongoStorageProvider.js +8 -4
- package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +32 -11
- package/dist/storage/implementation/MongoSyncBucketStorage.js +95 -31
- package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoSyncRulesLock.d.ts +26 -2
- package/dist/storage/implementation/MongoSyncRulesLock.js +59 -10
- package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
- package/dist/storage/implementation/MongoWriteBatch.d.ts +49 -0
- package/dist/storage/implementation/MongoWriteBatch.js +149 -0
- package/dist/storage/implementation/MongoWriteBatch.js.map +1 -0
- package/dist/storage/implementation/MongoWriteCheckpointAPI.d.ts +9 -7
- package/dist/storage/implementation/MongoWriteCheckpointAPI.js +9 -30
- package/dist/storage/implementation/MongoWriteCheckpointAPI.js.map +1 -1
- package/dist/storage/implementation/SyncRuleStateUpdate.d.ts +11 -5
- package/dist/storage/implementation/SyncRuleStateUpdate.js +14 -6
- package/dist/storage/implementation/SyncRuleStateUpdate.js.map +1 -1
- package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.d.ts +22 -2
- package/dist/storage/implementation/common/PersistedBatch.d.ts +32 -4
- package/dist/storage/implementation/common/PersistedBatch.js +57 -14
- package/dist/storage/implementation/common/PersistedBatch.js.map +1 -1
- package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.d.ts +3 -0
- package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js +3 -0
- package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js.map +1 -1
- package/dist/storage/implementation/db.d.ts +9 -1
- package/dist/storage/implementation/db.js +28 -1
- package/dist/storage/implementation/db.js.map +1 -1
- package/dist/storage/implementation/models.d.ts +35 -0
- package/dist/storage/implementation/models.js.map +1 -1
- package/dist/storage/implementation/v1/MongoBucketBatchV1.d.ts +11 -0
- package/dist/storage/implementation/v1/MongoBucketBatchV1.js +227 -221
- package/dist/storage/implementation/v1/MongoBucketBatchV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoCompactorV1.d.ts +38 -6
- package/dist/storage/implementation/v1/MongoCompactorV1.js +247 -20
- package/dist/storage/implementation/v1/MongoCompactorV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoParameterCompactorV1.d.ts +16 -2
- package/dist/storage/implementation/v1/MongoParameterCompactorV1.js +20 -9
- package/dist/storage/implementation/v1/MongoParameterCompactorV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.d.ts +18 -11
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js +66 -17
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js.map +1 -1
- package/dist/storage/implementation/v1/PersistedBatchV1.d.ts +7 -5
- package/dist/storage/implementation/v1/PersistedBatchV1.js +22 -28
- package/dist/storage/implementation/v1/PersistedBatchV1.js.map +1 -1
- package/dist/storage/implementation/v1/models.js +1 -0
- package/dist/storage/implementation/v1/models.js.map +1 -1
- package/dist/storage/implementation/v3/CompactionLease.d.ts +50 -0
- package/dist/storage/implementation/v3/CompactionLease.js +131 -0
- package/dist/storage/implementation/v3/CompactionLease.js.map +1 -0
- package/dist/storage/implementation/v3/MongoBucketBatchV3.d.ts +14 -2
- package/dist/storage/implementation/v3/MongoBucketBatchV3.js +261 -194
- package/dist/storage/implementation/v3/MongoBucketBatchV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoCompactorV3.d.ts +83 -25
- package/dist/storage/implementation/v3/MongoCompactorV3.js +702 -159
- package/dist/storage/implementation/v3/MongoCompactorV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoParameterCompactorV3.d.ts +18 -0
- package/dist/storage/implementation/v3/MongoParameterCompactorV3.js +23 -0
- package/dist/storage/implementation/v3/MongoParameterCompactorV3.js.map +1 -0
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.d.ts +2 -15
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js +60 -92
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js.map +1 -1
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.d.ts +19 -9
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js +92 -32
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoWriteCheckpointAPIV3.d.ts +26 -0
- package/dist/storage/implementation/v3/MongoWriteCheckpointAPIV3.js +82 -0
- package/dist/storage/implementation/v3/MongoWriteCheckpointAPIV3.js.map +1 -0
- package/dist/storage/implementation/v3/PersistedBatchV3.d.ts +14 -8
- package/dist/storage/implementation/v3/PersistedBatchV3.js +77 -45
- package/dist/storage/implementation/v3/PersistedBatchV3.js.map +1 -1
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.d.ts +12 -2
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js +42 -3
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js.map +1 -1
- package/dist/storage/implementation/v3/bucket-format.js +2 -0
- package/dist/storage/implementation/v3/bucket-format.js.map +1 -1
- package/dist/storage/implementation/v3/compact-utils.d.ts +108 -0
- package/dist/storage/implementation/v3/compact-utils.js +223 -0
- package/dist/storage/implementation/v3/compact-utils.js.map +1 -0
- package/dist/storage/implementation/v3/compaction-constants.d.ts +5 -0
- package/dist/storage/implementation/v3/compaction-constants.js +6 -0
- package/dist/storage/implementation/v3/compaction-constants.js.map +1 -0
- package/dist/storage/implementation/v3/models.d.ts +90 -6
- package/dist/storage/implementation/v3/models.js.map +1 -1
- package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.d.ts +7 -8
- package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.js +16 -5
- package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.js.map +1 -1
- package/dist/storage/implementation/v3/object-storage/ObjectStorage.d.ts +14 -11
- package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.d.ts +6 -8
- package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.js +17 -11
- package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.js.map +1 -1
- package/dist/storage/implementation/v3/object-storage/ObjectStorageUsage.d.ts +38 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageUsage.js +164 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageUsage.js.map +1 -0
- package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.d.ts +37 -12
- package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.js +197 -25
- package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.js.map +1 -1
- package/dist/storage/implementation/v3/source-table-utils.d.ts +15 -7
- package/dist/storage/implementation/v3/source-table-utils.js +49 -57
- package/dist/storage/implementation/v3/source-table-utils.js.map +1 -1
- package/dist/storage/storage-index.d.ts +2 -1
- package/dist/storage/storage-index.js +1 -0
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/types/types.d.ts +28 -1
- package/dist/types/types.js +28 -7
- package/dist/types/types.js.map +1 -1
- package/dist/utils/test-utils.d.ts +4 -2
- package/dist/utils/test-utils.js +7 -4
- package/dist/utils/test-utils.js.map +1 -1
- package/dist/utils/util.js +3 -1
- package/dist/utils/util.js.map +1 -1
- package/package.json +10 -9
- package/src/storage/MongoBucketStorage.ts +545 -277
- package/src/storage/implementation/MongoBucketBatch.ts +258 -124
- package/src/storage/implementation/MongoCompactor.ts +37 -346
- package/src/storage/implementation/MongoIdSequence.ts +21 -1
- package/src/storage/implementation/MongoOpIdAllocator.ts +105 -0
- package/src/storage/implementation/MongoParameterCompactor.ts +388 -102
- package/src/storage/implementation/MongoParsedSyncConfigSet.ts +46 -1
- package/src/storage/implementation/MongoPersistedReplicationStream.ts +12 -4
- package/src/storage/implementation/MongoPersistedSyncConfigContent.ts +48 -29
- package/src/storage/implementation/MongoStorageProvider.ts +16 -4
- package/src/storage/implementation/MongoSyncBucketStorage.ts +133 -40
- package/src/storage/implementation/MongoSyncRulesLock.ts +78 -12
- package/src/storage/implementation/MongoWriteBatch.ts +172 -0
- package/src/storage/implementation/MongoWriteCheckpointAPI.ts +16 -46
- package/src/storage/implementation/SyncRuleStateUpdate.ts +13 -6
- package/src/storage/implementation/common/MongoSyncBucketStorageCheckpoint.ts +24 -2
- package/src/storage/implementation/common/PersistedBatch.ts +76 -20
- package/src/storage/implementation/common/VersionedPowerSyncMongoBase.ts +4 -0
- package/src/storage/implementation/db.ts +36 -2
- package/src/storage/implementation/models.ts +39 -0
- package/src/storage/implementation/v1/MongoBucketBatchV1.ts +272 -254
- package/src/storage/implementation/v1/MongoCompactorV1.ts +327 -40
- package/src/storage/implementation/v1/MongoParameterCompactorV1.ts +25 -9
- package/src/storage/implementation/v1/MongoSyncBucketStorageV1.ts +88 -28
- package/src/storage/implementation/v1/PersistedBatchV1.ts +25 -30
- package/src/storage/implementation/v1/models.ts +1 -0
- package/src/storage/implementation/v3/CompactionLease.ts +152 -0
- package/src/storage/implementation/v3/MongoBucketBatchV3.ts +339 -247
- package/src/storage/implementation/v3/MongoCompactorV3.ts +955 -225
- package/src/storage/implementation/v3/MongoParameterCompactorV3.ts +34 -0
- package/src/storage/implementation/v3/MongoStoppedSyncConfigCleanup.ts +100 -109
- package/src/storage/implementation/v3/MongoSyncBucketStorageV3.ts +112 -42
- package/src/storage/implementation/v3/MongoWriteCheckpointAPIV3.ts +111 -0
- package/src/storage/implementation/v3/PersistedBatchV3.ts +94 -51
- package/src/storage/implementation/v3/VersionedPowerSyncMongoV3.ts +55 -4
- package/src/storage/implementation/v3/bucket-format.ts +2 -0
- package/src/storage/implementation/v3/compact-utils.ts +329 -0
- package/src/storage/implementation/v3/compaction-constants.ts +5 -0
- package/src/storage/implementation/v3/models.ts +97 -4
- package/src/storage/implementation/v3/object-storage/BucketDataObjectStorage.ts +24 -9
- package/src/storage/implementation/v3/object-storage/ObjectStorage.ts +20 -5
- package/src/storage/implementation/v3/object-storage/ObjectStorageLifecycle.ts +26 -14
- package/src/storage/implementation/v3/object-storage/ObjectStorageUsage.ts +229 -0
- package/src/storage/implementation/v3/object-storage/S3ObjectStorage.ts +279 -29
- package/src/storage/implementation/v3/source-table-utils.ts +82 -76
- package/src/storage/storage-index.ts +2 -0
- package/src/types/types.ts +42 -7
- package/src/utils/test-utils.ts +9 -5
- package/src/utils/util.ts +3 -1
- package/test/src/__snapshots__/storage.test.ts.snap +25 -0
- package/test/src/__snapshots__/storage_sync.test.ts.snap +794 -205
- package/test/src/chunk_compaction_config.test.ts +38 -0
- package/test/src/cleanup-stopped-sync-configs.test.ts +59 -26
- package/test/src/compact-utils.test.ts +251 -0
- package/test/src/concurrent_writers.test.ts +599 -0
- package/test/src/connection_config.test.ts +159 -0
- package/test/src/helpers/MemoryObjectStorage.ts +14 -6
- package/test/src/helpers/concurrentWriter.mjs +29 -0
- package/test/src/helpers/s3TestFactory.ts +12 -12
- package/test/src/object_storage_usage.test.ts +268 -0
- package/test/src/parameter_compacting_v1.test.ts +120 -0
- package/test/src/parameter_compacting_v3.test.ts +192 -0
- package/test/src/parameter_compaction_fence.test.ts +276 -0
- package/test/src/storage.test.ts +280 -24
- package/test/src/storage_compacting.test.ts +1097 -253
- package/test/src/storage_object_storage_inline_threshold.test.ts +3 -3
- package/test/src/storage_s3_checksums.test.ts +6 -7
- package/test/src/storage_s3_compaction_lifecycle.test.ts +143 -17
- package/test/src/storage_s3_reading.test.ts +294 -6
- package/test/src/storage_s3_writing.test.ts +4 -3
- package/test/src/storage_sync.test.ts +412 -80
- package/test/src/storeCurrentData.test.ts +5 -5
- package/test/src/util.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -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';
|
|
@@ -16,6 +16,7 @@ import { MongoPersistedSyncConfigContentV3 } from '../../src/storage/implementat
|
|
|
16
16
|
import { BucketDataDoc, BucketKey } from '../../src/storage/implementation/common/BucketDataDoc.js';
|
|
17
17
|
import { MongoSyncBucketStorage } from '../../src/storage/implementation/createMongoSyncBucketStorage.js';
|
|
18
18
|
import { getMongoStorageConfig } from '../../src/storage/implementation/models.js';
|
|
19
|
+
import { loadBucketDataDocumentV1, serializeBucketDataV1 } from '../../src/storage/implementation/v1/models.js';
|
|
19
20
|
import { SourceRecordStoreV3 } from '../../src/storage/implementation/v3/SourceRecordStoreV3.js';
|
|
20
21
|
import type { VersionedPowerSyncMongoV3 } from '../../src/storage/implementation/v3/VersionedPowerSyncMongoV3.js';
|
|
21
22
|
import { serializeBucketData } from '../../src/storage/implementation/v3/bucket-format.js';
|
|
@@ -98,7 +99,9 @@ async function getMongoSyncConfigContents(factory: storage.BucketStorageFactory,
|
|
|
98
99
|
})
|
|
99
100
|
.toArray();
|
|
100
101
|
|
|
101
|
-
return syncConfigDocs.map(
|
|
102
|
+
return syncConfigDocs.map(
|
|
103
|
+
(config) => new MongoPersistedSyncConfigContentV3(mongoFactory.db, doc, config, mongoFactory.syncConfigParser)
|
|
104
|
+
);
|
|
102
105
|
}
|
|
103
106
|
|
|
104
107
|
/**
|
|
@@ -114,11 +117,65 @@ function bucketDefinitionId(bucket: string) {
|
|
|
114
117
|
return parseInt(match[1], 16);
|
|
115
118
|
}
|
|
116
119
|
|
|
120
|
+
test('V1 bucket data retains an optional persisted subkey', () => {
|
|
121
|
+
const sourceTable = new bson.ObjectId();
|
|
122
|
+
const document = serializeBucketDataV1({
|
|
123
|
+
bucketKey: {
|
|
124
|
+
replicationStreamId: 1,
|
|
125
|
+
definitionId: '0',
|
|
126
|
+
bucket: 'global[]'
|
|
127
|
+
},
|
|
128
|
+
o: 1n,
|
|
129
|
+
op: 'PUT',
|
|
130
|
+
source_table: sourceTable,
|
|
131
|
+
source_key: 'source-key',
|
|
132
|
+
subkey: 'persisted-subkey',
|
|
133
|
+
table: 'items',
|
|
134
|
+
row_id: 'item-1',
|
|
135
|
+
checksum: 1n,
|
|
136
|
+
data: '{"id":"item-1"}'
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
expect(loadBucketDataDocumentV1(document).subkey).toBe('persisted-subkey');
|
|
140
|
+
|
|
141
|
+
const { subkey: _subkey, ...legacyDocument } = document;
|
|
142
|
+
expect(loadBucketDataDocumentV1(legacyDocument).subkey).toBeUndefined();
|
|
143
|
+
});
|
|
144
|
+
|
|
117
145
|
function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, storageVersion: number) {
|
|
118
146
|
register.registerSyncTests(storageConfig.factory, {
|
|
119
147
|
storageVersion,
|
|
120
148
|
tableIdStrings: storageConfig.tableIdStrings
|
|
121
149
|
});
|
|
150
|
+
|
|
151
|
+
test('updates source metadata on an existing resolved table', async () => {
|
|
152
|
+
await using factory = await storageConfig.factory();
|
|
153
|
+
const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion }));
|
|
154
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
155
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
156
|
+
const source = sourceDescriptor('test');
|
|
157
|
+
|
|
158
|
+
const initial = await writer.resolveTables({ connection_id: 1, source });
|
|
159
|
+
expect(initial.tables[0].sourceMetadata).toBeNull();
|
|
160
|
+
|
|
161
|
+
const sourceMetadata = { captureTableObjectId: 42 };
|
|
162
|
+
const updated = await writer.resolveTables({
|
|
163
|
+
connection_id: 1,
|
|
164
|
+
source,
|
|
165
|
+
reconcileSourceTables: ({ candidates }) => ({
|
|
166
|
+
compatibleTables: candidates.map((candidate) => candidate.withSourceMetadata(sourceMetadata)),
|
|
167
|
+
incompatibleTables: [],
|
|
168
|
+
newTableValues: { sourceMetadata }
|
|
169
|
+
})
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
expect(updated.tables.map((table) => table.id.toString())).toEqual(
|
|
173
|
+
initial.tables.map((table) => table.id.toString())
|
|
174
|
+
);
|
|
175
|
+
expect(updated.tables[0].sourceMetadata).toEqual(sourceMetadata);
|
|
176
|
+
expect((await writer.getSourceTableStatus(updated.tables[0]))?.sourceMetadata).toEqual(sourceMetadata);
|
|
177
|
+
});
|
|
178
|
+
|
|
122
179
|
// The split of returned results can vary depending on storage drivers
|
|
123
180
|
test('large batch (2)', async () => {
|
|
124
181
|
// Test syncing a batch of data that is small in count,
|
|
@@ -136,7 +193,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
136
193
|
{ storageVersion }
|
|
137
194
|
)
|
|
138
195
|
);
|
|
139
|
-
const bucketStorage = factory
|
|
196
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
140
197
|
const syncRulesContent = syncRules.syncConfigContent[0];
|
|
141
198
|
|
|
142
199
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
@@ -283,7 +340,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
283
340
|
{ storageVersion }
|
|
284
341
|
)
|
|
285
342
|
);
|
|
286
|
-
const bucketStorage = factory
|
|
343
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
287
344
|
|
|
288
345
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
289
346
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], INITIALIZED_MONGO_STORAGE_FACTORY);
|
|
@@ -308,7 +365,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
308
365
|
{ storageVersion }
|
|
309
366
|
)
|
|
310
367
|
);
|
|
311
|
-
const bucketStorage = factory
|
|
368
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
312
369
|
|
|
313
370
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
314
371
|
const before = await writer.resolveTables({
|
|
@@ -346,7 +403,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
346
403
|
{ storageVersion }
|
|
347
404
|
)
|
|
348
405
|
);
|
|
349
|
-
const bucketStorage = factory
|
|
406
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
350
407
|
|
|
351
408
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
352
409
|
const before = await writer.resolveTables({
|
|
@@ -382,7 +439,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
382
439
|
{ storageVersion }
|
|
383
440
|
)
|
|
384
441
|
);
|
|
385
|
-
const bucketStorage = factory
|
|
442
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
386
443
|
|
|
387
444
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
388
445
|
const before = await writer.resolveTables({
|
|
@@ -426,7 +483,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
426
483
|
{ storageVersion }
|
|
427
484
|
)
|
|
428
485
|
);
|
|
429
|
-
const bucketStorage = factory
|
|
486
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
430
487
|
|
|
431
488
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
432
489
|
const resolved = await writer.resolveTables({
|
|
@@ -495,7 +552,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
495
552
|
// Here we're persisting one sync config, then resolving tables with others.
|
|
496
553
|
// We're also using the default hydration state for them all.
|
|
497
554
|
const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(fullRulesYaml, { storageVersion }));
|
|
498
|
-
const bucketStorage = factory
|
|
555
|
+
const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
|
|
499
556
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
500
557
|
const fullRules = parsedSyncConfigSetFor(fullRulesYaml, storageVersion);
|
|
501
558
|
const dataOnlyRules = parsedSyncConfigSetFor(dataOnlyRulesYaml, storageVersion);
|
|
@@ -504,6 +561,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
504
561
|
const source = sourceDescriptor('memberships', { objectId: 'memberships-relation' });
|
|
505
562
|
const dataOnlyTableId = new bson.ObjectId('6544e3899293153fa7b38348');
|
|
506
563
|
const addedParameterTableId = new bson.ObjectId('6544e3899293153fa7b38349');
|
|
564
|
+
const addedEventTableId = new bson.ObjectId('6544e3899293153fa7b3834a');
|
|
507
565
|
|
|
508
566
|
const dataOnly = await writer.resolveTables({
|
|
509
567
|
connection_id: 1,
|
|
@@ -561,15 +619,13 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
561
619
|
const eventOnly = await writer.resolveTables({
|
|
562
620
|
connection_id: 1,
|
|
563
621
|
source,
|
|
564
|
-
idGenerator: () =>
|
|
565
|
-
throw new Error('resolve should reuse existing v3 source table');
|
|
566
|
-
},
|
|
622
|
+
idGenerator: () => addedEventTableId,
|
|
567
623
|
parsedSyncConfig: eventOnlyRules
|
|
568
624
|
});
|
|
569
625
|
|
|
570
|
-
//
|
|
626
|
+
// A newly-added event gets its own source table so that its existing rows are snapshotted.
|
|
571
627
|
expect(eventOnly.tables).toHaveLength(1);
|
|
572
|
-
expect(
|
|
628
|
+
expect(eventOnly.tables[0].id).toEqual(addedEventTableId);
|
|
573
629
|
expect(eventOnly.dropTables.map((table) => table.id)).toEqual([]);
|
|
574
630
|
expect(eventOnly.tables[0].bucketDataSources).toHaveLength(0);
|
|
575
631
|
expect(eventOnly.tables[0].parameterLookupSources).toHaveLength(0);
|
|
@@ -578,13 +634,12 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
578
634
|
expect(eventOnly.tables[0].syncEvent).toBe(true);
|
|
579
635
|
});
|
|
580
636
|
|
|
581
|
-
test.runIf(storageVersion >= 3)(
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
const dataOnlyEventYaml = `
|
|
637
|
+
test.runIf(storageVersion >= 3)('resolveTables assigns an event definition to one split source table', async () => {
|
|
638
|
+
// When memberships are split over multiple SourceTables for the same ref, a row change
|
|
639
|
+
// is saved once per table. Each event-definition id must belong to only one of those tables,
|
|
640
|
+
// otherwise that definition would be evaluated more than once for the same row change.
|
|
641
|
+
// Other tables may independently own and evaluate different event definitions.
|
|
642
|
+
const dataOnlyEventYaml = `
|
|
588
643
|
bucket_definitions:
|
|
589
644
|
by_owner:
|
|
590
645
|
parameters:
|
|
@@ -597,7 +652,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
597
652
|
payloads:
|
|
598
653
|
- SELECT id, owner_id FROM memberships
|
|
599
654
|
`;
|
|
600
|
-
|
|
655
|
+
const fullEventYaml = `
|
|
601
656
|
bucket_definitions:
|
|
602
657
|
by_owner:
|
|
603
658
|
parameters:
|
|
@@ -611,42 +666,201 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
611
666
|
- SELECT id, owner_id FROM memberships
|
|
612
667
|
`;
|
|
613
668
|
|
|
669
|
+
await using factory = await storageConfig.factory();
|
|
670
|
+
const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(dataOnlyEventYaml, { storageVersion }));
|
|
671
|
+
const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
|
|
672
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
673
|
+
const dataOnlyRules = parsedSyncConfigSetFor(dataOnlyEventYaml, storageVersion);
|
|
674
|
+
const fullRules = parsedSyncConfigSetFor(fullEventYaml, storageVersion);
|
|
675
|
+
const source = sourceDescriptor('memberships', { objectId: 'memberships-relation' });
|
|
676
|
+
|
|
677
|
+
const initial = await writer.resolveTables({
|
|
678
|
+
connection_id: 1,
|
|
679
|
+
source,
|
|
680
|
+
idGenerator: objectIdGenerator('6544e3899293153fa7b3834b'),
|
|
681
|
+
parsedSyncConfig: dataOnlyRules
|
|
682
|
+
});
|
|
683
|
+
expect(initial.tables).toHaveLength(1);
|
|
684
|
+
expect(initial.tables[0].syncEvent).toBe(true);
|
|
685
|
+
|
|
686
|
+
// Adding the table-based parameter lookup creates a second SourceTable for the same ref.
|
|
687
|
+
const split = await writer.resolveTables({
|
|
688
|
+
connection_id: 1,
|
|
689
|
+
source,
|
|
690
|
+
idGenerator: objectIdGenerator('6544e3899293153fa7b3834c'),
|
|
691
|
+
parsedSyncConfig: fullRules
|
|
692
|
+
});
|
|
693
|
+
expect(split.tables).toHaveLength(2);
|
|
694
|
+
// Both tables match the event by ref, but this event id belongs to only one of them.
|
|
695
|
+
const eventOwners = split.tables.filter((table) => table.syncEvent);
|
|
696
|
+
expect(eventOwners).toHaveLength(1);
|
|
697
|
+
|
|
698
|
+
// getSourceTableStatus rehydrates the persisted event memberships rather than recomputing
|
|
699
|
+
// them from the ref, so refreshing the other table does not assign this event to it.
|
|
700
|
+
const nonOwner = split.tables.find((table) => !table.syncEvent)!;
|
|
701
|
+
const refreshed = await writer.getSourceTableStatus(nonOwner);
|
|
702
|
+
expect(refreshed!.syncEvent).toBe(false);
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
test.runIf(storageVersion >= 3)(
|
|
706
|
+
'reuses an unchanged event definition without resnapshotting or duplicate evaluation',
|
|
707
|
+
async () => {
|
|
708
|
+
const firstYaml = `
|
|
709
|
+
config:
|
|
710
|
+
edition: 3
|
|
711
|
+
|
|
712
|
+
streams:
|
|
713
|
+
by_owner:
|
|
714
|
+
query: SELECT * FROM todos WHERE owner_id = subscription.parameter('owner_id')
|
|
715
|
+
|
|
716
|
+
event_definitions:
|
|
717
|
+
write_checkpoints:
|
|
718
|
+
payloads:
|
|
719
|
+
- SELECT user_id, checkpoint FROM checkpoints WHERE active = true AND checkpoint > 0
|
|
720
|
+
`;
|
|
721
|
+
const secondYaml = `
|
|
722
|
+
config:
|
|
723
|
+
edition: 3
|
|
724
|
+
|
|
725
|
+
streams:
|
|
726
|
+
by_owner:
|
|
727
|
+
query: SELECT * FROM todos WHERE owner_id = subscription.parameter('owner_id')
|
|
728
|
+
by_project:
|
|
729
|
+
query: SELECT * FROM todos WHERE project_id = subscription.parameter('project_id')
|
|
730
|
+
|
|
731
|
+
event_definitions:
|
|
732
|
+
write_checkpoints:
|
|
733
|
+
payloads:
|
|
734
|
+
- select "user_id", "checkpoint" from "checkpoints" where "active" = true and "checkpoint" > 0
|
|
735
|
+
`;
|
|
736
|
+
|
|
614
737
|
await using factory = await storageConfig.factory();
|
|
615
|
-
const
|
|
616
|
-
const
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
738
|
+
const emittedEvents: { name: string; eventId: string | undefined }[] = [];
|
|
739
|
+
const disposeListener = factory.registerListener({
|
|
740
|
+
replicationEvent: ({ event, event_id }) => emittedEvents.push({ name: event.name, eventId: event_id })
|
|
741
|
+
});
|
|
742
|
+
try {
|
|
743
|
+
const first = await factory.updateSyncRules(updateSyncRulesFromYaml(firstYaml, { storageVersion }));
|
|
744
|
+
const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
|
|
745
|
+
await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
746
|
+
const source = sourceDescriptor('checkpoints', { objectId: 'checkpoints-relation' });
|
|
747
|
+
const firstResolved = await firstWriter.resolveTables({
|
|
748
|
+
connection_id: 1,
|
|
749
|
+
source,
|
|
750
|
+
idGenerator: objectIdGenerator('6544e3899293153fa7b38351')
|
|
751
|
+
});
|
|
752
|
+
const eventId = [...firstResolved.tables[0].eventDefinitionIds!][0];
|
|
753
|
+
expect(eventId).toBeDefined();
|
|
754
|
+
await firstWriter.markTableSnapshotDone(firstResolved.tables, '1/1');
|
|
755
|
+
await firstWriter.markAllSnapshotDone('1/1');
|
|
756
|
+
await firstWriter.commit('1/1');
|
|
757
|
+
|
|
758
|
+
const second = await factory.updateSyncRules(updateSyncRulesFromYaml(secondYaml, { storageVersion }));
|
|
759
|
+
expect(second.replicationStreamId).toBe(first.replicationStreamId);
|
|
760
|
+
const secondStorage = (await getTestStorage(factory, second)) as MongoSyncBucketStorage;
|
|
761
|
+
await using secondWriter = await secondStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
762
|
+
const resolved = await secondWriter.resolveTables({
|
|
763
|
+
connection_id: 1,
|
|
764
|
+
source,
|
|
765
|
+
idGenerator: () => {
|
|
766
|
+
throw new Error('unchanged event definition should reuse the snapshotted source table');
|
|
767
|
+
}
|
|
768
|
+
});
|
|
621
769
|
|
|
622
|
-
|
|
770
|
+
expect(resolved.tables).toHaveLength(1);
|
|
771
|
+
expect(resolved.tables[0].id).toEqual(firstResolved.tables[0].id);
|
|
772
|
+
expect(resolved.tables[0].snapshotComplete).toBe(true);
|
|
773
|
+
expect([...resolved.tables[0].eventDefinitionIds!]).toEqual([eventId]);
|
|
774
|
+
|
|
775
|
+
emittedEvents.length = 0;
|
|
776
|
+
await secondWriter.save({
|
|
777
|
+
sourceTable: resolved.tables[0],
|
|
778
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
779
|
+
after: { id: 'checkpoint-1', user_id: 'user-1', checkpoint: 1n, active: 1 },
|
|
780
|
+
afterReplicaId: test_utils.rid('checkpoint-1')
|
|
781
|
+
});
|
|
782
|
+
expect(emittedEvents).toEqual([{ name: 'write_checkpoints', eventId }]);
|
|
783
|
+
} finally {
|
|
784
|
+
disposeListener();
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
);
|
|
788
|
+
|
|
789
|
+
test.runIf(storageVersion >= 3)('creates snapshot work for a changed event definition', async () => {
|
|
790
|
+
const yaml = (active: boolean) => `
|
|
791
|
+
config:
|
|
792
|
+
edition: 3
|
|
793
|
+
|
|
794
|
+
streams:
|
|
795
|
+
by_owner:
|
|
796
|
+
query: SELECT * FROM todos WHERE owner_id = subscription.parameter('owner_id')
|
|
797
|
+
|
|
798
|
+
event_definitions:
|
|
799
|
+
write_checkpoints:
|
|
800
|
+
payloads:
|
|
801
|
+
- SELECT user_id, checkpoint FROM checkpoints WHERE active = ${active}
|
|
802
|
+
`;
|
|
803
|
+
|
|
804
|
+
await using factory = await storageConfig.factory();
|
|
805
|
+
const emittedEvents: { name: string; eventId: string | undefined }[] = [];
|
|
806
|
+
const disposeListener = factory.registerListener({
|
|
807
|
+
replicationEvent: ({ event, event_id }) => emittedEvents.push({ name: event.name, eventId: event_id })
|
|
808
|
+
});
|
|
809
|
+
try {
|
|
810
|
+
const first = await factory.updateSyncRules(updateSyncRulesFromYaml(yaml(true), { storageVersion }));
|
|
811
|
+
const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
|
|
812
|
+
await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
813
|
+
const source = sourceDescriptor('checkpoints', { objectId: 'checkpoints-relation' });
|
|
814
|
+
const firstResolved = await firstWriter.resolveTables({
|
|
623
815
|
connection_id: 1,
|
|
624
816
|
source,
|
|
625
|
-
idGenerator: objectIdGenerator('
|
|
626
|
-
parsedSyncConfig: dataOnlyRules
|
|
817
|
+
idGenerator: objectIdGenerator('6544e3899293153fa7b38352')
|
|
627
818
|
});
|
|
628
|
-
|
|
629
|
-
|
|
819
|
+
const oldEventId = [...firstResolved.tables[0].eventDefinitionIds!][0];
|
|
820
|
+
await firstWriter.markTableSnapshotDone(firstResolved.tables, '1/1');
|
|
821
|
+
await firstWriter.markAllSnapshotDone('1/1');
|
|
822
|
+
await firstWriter.commit('1/1');
|
|
630
823
|
|
|
631
|
-
|
|
632
|
-
|
|
824
|
+
const second = await factory.updateSyncRules(updateSyncRulesFromYaml(yaml(false), { storageVersion }));
|
|
825
|
+
expect(second.replicationStreamId).toBe(first.replicationStreamId);
|
|
826
|
+
const secondStorage = (await getTestStorage(factory, second)) as MongoSyncBucketStorage;
|
|
827
|
+
await using secondWriter = await secondStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
828
|
+
const resolved = await secondWriter.resolveTables({
|
|
633
829
|
connection_id: 1,
|
|
634
830
|
source,
|
|
635
|
-
idGenerator: objectIdGenerator('
|
|
636
|
-
parsedSyncConfig: fullRules
|
|
831
|
+
idGenerator: objectIdGenerator('6544e3899293153fa7b38353')
|
|
637
832
|
});
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
const
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
expect(
|
|
833
|
+
|
|
834
|
+
expect(resolved.tables).toHaveLength(2);
|
|
835
|
+
const oldTable = resolved.tables.find((table) => table.eventDefinitionIds?.has(oldEventId))!;
|
|
836
|
+
const newTable = resolved.tables.find((table) => !table.eventDefinitionIds?.has(oldEventId))!;
|
|
837
|
+
const newEventId = [...newTable.eventDefinitionIds!][0];
|
|
838
|
+
expect(newEventId).toBeDefined();
|
|
839
|
+
expect(newEventId).not.toBe(oldEventId);
|
|
840
|
+
expect(oldTable.snapshotComplete).toBe(true);
|
|
841
|
+
expect(newTable.snapshotComplete).toBe(false);
|
|
842
|
+
expect(newTable.bucketDataSources).toEqual([]);
|
|
843
|
+
expect(newTable.parameterLookupSources).toEqual([]);
|
|
844
|
+
|
|
845
|
+
await expect(secondWriter.markSnapshotDone('2/1')).rejects.toThrow(
|
|
846
|
+
'Cannot mark snapshot done while source tables still require snapshotting'
|
|
847
|
+
);
|
|
848
|
+
|
|
849
|
+
emittedEvents.length = 0;
|
|
850
|
+
await secondWriter.save({
|
|
851
|
+
sourceTable: newTable,
|
|
852
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
853
|
+
after: { id: 'checkpoint-2', user_id: 'user-2', checkpoint: 2n, active: 0 },
|
|
854
|
+
afterReplicaId: test_utils.rid('checkpoint-2')
|
|
855
|
+
});
|
|
856
|
+
expect(emittedEvents).toEqual([{ name: 'write_checkpoints', eventId: newEventId }]);
|
|
857
|
+
|
|
858
|
+
await secondWriter.markTableSnapshotDone([newTable], '2/1');
|
|
859
|
+
await secondWriter.markSnapshotDone('2/1');
|
|
860
|
+
} finally {
|
|
861
|
+
disposeListener();
|
|
648
862
|
}
|
|
649
|
-
);
|
|
863
|
+
});
|
|
650
864
|
|
|
651
865
|
test.runIf(storageVersion >= 3)('uses v3 mongodb model shapes', async () => {
|
|
652
866
|
await using factory = await storageConfig.factory();
|
|
@@ -663,7 +877,7 @@ function registerSyncStorageTests(storageConfig: storage.TestStorageConfig, stor
|
|
|
663
877
|
{ storageVersion }
|
|
664
878
|
)
|
|
665
879
|
);
|
|
666
|
-
const bucketStorage = factory
|
|
880
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
667
881
|
const syncRulesContent = syncRules.syncConfigContent[0];
|
|
668
882
|
const sync_rules = syncRulesContent.parsed(test_utils.PARSE_OPTIONS).hydratedSyncConfig;
|
|
669
883
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
@@ -776,7 +990,7 @@ streams:
|
|
|
776
990
|
expect(parsed.syncConfigs).toHaveLength(1);
|
|
777
991
|
expect(parsed.hydratedSyncConfig.bucketDataSources).toHaveLength(1);
|
|
778
992
|
|
|
779
|
-
const bucketStorage = factory
|
|
993
|
+
const bucketStorage = await getTestStorage(factory, replicatingStreams[0]);
|
|
780
994
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
781
995
|
const resolved = await writer.resolveTables({
|
|
782
996
|
connection_id: 1,
|
|
@@ -803,7 +1017,7 @@ streams:
|
|
|
803
1017
|
{ storageVersion }
|
|
804
1018
|
)
|
|
805
1019
|
);
|
|
806
|
-
const firstStorage = factory
|
|
1020
|
+
const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
|
|
807
1021
|
await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
808
1022
|
await firstWriter.markAllSnapshotDone('1/1');
|
|
809
1023
|
await firstWriter.commit('1/1');
|
|
@@ -823,7 +1037,7 @@ streams:
|
|
|
823
1037
|
);
|
|
824
1038
|
expect(second.replicationStreamId).toEqual(first.replicationStreamId);
|
|
825
1039
|
|
|
826
|
-
const bucketStorage = factory
|
|
1040
|
+
const bucketStorage = await getTestStorage(factory, second);
|
|
827
1041
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
828
1042
|
const source = sourceDescriptor('todos', { objectId: 'todos-relation' });
|
|
829
1043
|
|
|
@@ -838,7 +1052,10 @@ streams:
|
|
|
838
1052
|
await writer.markAllSnapshotDone('2/1');
|
|
839
1053
|
await writer.commit('2/1');
|
|
840
1054
|
|
|
841
|
-
const activeStorage = (await
|
|
1055
|
+
const activeStorage = (await getTestStorage(
|
|
1056
|
+
factory,
|
|
1057
|
+
(await factory.getActiveSyncConfig())!.replicationStream
|
|
1058
|
+
)) as MongoSyncBucketStorage;
|
|
842
1059
|
await using activeWriter = await activeStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
843
1060
|
const activeStatus = await activeWriter.getSourceTableStatus(resolved.tables[0]);
|
|
844
1061
|
expect(activeStatus?.bucketDataSources).toHaveLength(1);
|
|
@@ -862,7 +1079,7 @@ streams:
|
|
|
862
1079
|
{ storageVersion }
|
|
863
1080
|
)
|
|
864
1081
|
);
|
|
865
|
-
const firstStorage = factory
|
|
1082
|
+
const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
|
|
866
1083
|
await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
867
1084
|
const source = sourceDescriptor('todos', { objectId: 'todos-relation' });
|
|
868
1085
|
const firstResolved = await firstWriter.resolveTables({
|
|
@@ -891,7 +1108,7 @@ streams:
|
|
|
891
1108
|
|
|
892
1109
|
const deploying = await factory.getDeployingSyncConfig();
|
|
893
1110
|
expect(deploying?.replicationStream.replicationStreamId).toBe(first.replicationStreamId);
|
|
894
|
-
const bucketStorage = deploying!.
|
|
1111
|
+
const bucketStorage = await getTestStorage(factory, deploying!.replicationStream);
|
|
895
1112
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
896
1113
|
const resolved = await writer.resolveTables({
|
|
897
1114
|
connection_id: 1,
|
|
@@ -937,7 +1154,7 @@ streams:
|
|
|
937
1154
|
`;
|
|
938
1155
|
|
|
939
1156
|
const first = await factory.updateSyncRules(updateSyncRulesFromYaml(ownerRules, { storageVersion }));
|
|
940
|
-
const firstStorage = factory
|
|
1157
|
+
const firstStorage = await getTestStorage(factory, first);
|
|
941
1158
|
await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
942
1159
|
await firstWriter.markAllSnapshotDone('1/1');
|
|
943
1160
|
await firstWriter.commit('1/1');
|
|
@@ -989,7 +1206,7 @@ streams:
|
|
|
989
1206
|
{ storageVersion }
|
|
990
1207
|
)
|
|
991
1208
|
);
|
|
992
|
-
const firstStorage = factory
|
|
1209
|
+
const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
|
|
993
1210
|
await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
994
1211
|
await firstWriter.markAllSnapshotDone('1/1');
|
|
995
1212
|
await firstWriter.commit('1/1');
|
|
@@ -1011,7 +1228,7 @@ streams:
|
|
|
1011
1228
|
);
|
|
1012
1229
|
expect(second.replicationStreamId).toBe(first.replicationStreamId);
|
|
1013
1230
|
|
|
1014
|
-
const bucketStorage = factory
|
|
1231
|
+
const bucketStorage = await getTestStorage(factory, second);
|
|
1015
1232
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1016
1233
|
const resolved = await writer.resolveTables({
|
|
1017
1234
|
connection_id: 1,
|
|
@@ -1062,7 +1279,7 @@ streams:
|
|
|
1062
1279
|
{ storageVersion }
|
|
1063
1280
|
)
|
|
1064
1281
|
);
|
|
1065
|
-
const firstStorage = factory
|
|
1282
|
+
const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
|
|
1066
1283
|
await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1067
1284
|
await firstWriter.markAllSnapshotDone('1/1');
|
|
1068
1285
|
await firstWriter.commit('1/1');
|
|
@@ -1105,7 +1322,7 @@ streams:
|
|
|
1105
1322
|
expect(replicatingStreams[0].replicationJobId).toContain(config.syncConfigId);
|
|
1106
1323
|
}
|
|
1107
1324
|
|
|
1108
|
-
const secondStorage = factory
|
|
1325
|
+
const secondStorage = (await getTestStorage(factory, replicatingStreams[0])) as MongoSyncBucketStorage;
|
|
1109
1326
|
await using secondWriter = await secondStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1110
1327
|
await secondWriter.markAllSnapshotDone('2/1');
|
|
1111
1328
|
await secondWriter.commit('2/1');
|
|
@@ -1130,6 +1347,100 @@ streams:
|
|
|
1130
1347
|
}
|
|
1131
1348
|
);
|
|
1132
1349
|
|
|
1350
|
+
test.runIf(storageVersion >= 3)(
|
|
1351
|
+
'restart creates a replacement stream instead of appending to the active stream',
|
|
1352
|
+
async () => {
|
|
1353
|
+
await using factory = await storageConfig.factory();
|
|
1354
|
+
|
|
1355
|
+
const active = await factory.updateSyncRules(
|
|
1356
|
+
updateSyncRulesFromYaml(
|
|
1357
|
+
`
|
|
1358
|
+
config:
|
|
1359
|
+
edition: 3
|
|
1360
|
+
|
|
1361
|
+
streams:
|
|
1362
|
+
by_owner:
|
|
1363
|
+
query: SELECT * FROM todos WHERE owner_id = subscription.parameter('owner_id')
|
|
1364
|
+
`,
|
|
1365
|
+
{ storageVersion }
|
|
1366
|
+
)
|
|
1367
|
+
);
|
|
1368
|
+
const activeStorage = (await getTestStorage(factory, active)) as MongoSyncBucketStorage;
|
|
1369
|
+
await using activeWriter = await activeStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1370
|
+
await activeWriter.markAllSnapshotDone('1/1');
|
|
1371
|
+
await activeWriter.commit('1/1');
|
|
1372
|
+
|
|
1373
|
+
await factory.restartReplication(active.replicationStreamId);
|
|
1374
|
+
|
|
1375
|
+
const replicatingStreams = await factory.getReplicatingReplicationStreams();
|
|
1376
|
+
expect(replicatingStreams).toHaveLength(1);
|
|
1377
|
+
expect(replicatingStreams[0].replicationStreamId).not.toEqual(active.replicationStreamId);
|
|
1378
|
+
expect(replicatingStreams[0].state).toBe(storage.SyncRuleState.PROCESSING);
|
|
1379
|
+
|
|
1380
|
+
const oldStream = (await (factory as MongoBucketStorage).db.sync_rules.findOne({
|
|
1381
|
+
_id: active.replicationStreamId
|
|
1382
|
+
})) as ReplicationStreamDocumentV3;
|
|
1383
|
+
expect(oldStream.state).toBe(storage.SyncRuleState.ERRORED);
|
|
1384
|
+
expect(oldStream.sync_configs.map((config) => config.state)).toEqual([storage.SyncRuleState.ERRORED]);
|
|
1385
|
+
}
|
|
1386
|
+
);
|
|
1387
|
+
|
|
1388
|
+
test.runIf(storageVersion >= 3)('restart errors an active stream with an embedded deploying config', async () => {
|
|
1389
|
+
await using factory = await storageConfig.factory();
|
|
1390
|
+
|
|
1391
|
+
const active = await factory.updateSyncRules(
|
|
1392
|
+
updateSyncRulesFromYaml(
|
|
1393
|
+
`
|
|
1394
|
+
config:
|
|
1395
|
+
edition: 3
|
|
1396
|
+
|
|
1397
|
+
streams:
|
|
1398
|
+
by_owner:
|
|
1399
|
+
query: SELECT * FROM todos WHERE owner_id = subscription.parameter('owner_id')
|
|
1400
|
+
`,
|
|
1401
|
+
{ storageVersion }
|
|
1402
|
+
)
|
|
1403
|
+
);
|
|
1404
|
+
const activeStorage = (await getTestStorage(factory, active)) as MongoSyncBucketStorage;
|
|
1405
|
+
await using activeWriter = await activeStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1406
|
+
await activeWriter.markAllSnapshotDone('1/1');
|
|
1407
|
+
await activeWriter.commit('1/1');
|
|
1408
|
+
|
|
1409
|
+
const deploying = await factory.updateSyncRules(
|
|
1410
|
+
updateSyncRulesFromYaml(
|
|
1411
|
+
`
|
|
1412
|
+
config:
|
|
1413
|
+
edition: 3
|
|
1414
|
+
|
|
1415
|
+
streams:
|
|
1416
|
+
by_project:
|
|
1417
|
+
query: SELECT * FROM todos WHERE project_id = subscription.parameter('project_id')
|
|
1418
|
+
`,
|
|
1419
|
+
{ storageVersion }
|
|
1420
|
+
)
|
|
1421
|
+
);
|
|
1422
|
+
expect(deploying.replicationStreamId).toEqual(active.replicationStreamId);
|
|
1423
|
+
|
|
1424
|
+
await factory.restartReplication(active.replicationStreamId);
|
|
1425
|
+
|
|
1426
|
+
const replicatingStreams = await factory.getReplicatingReplicationStreams();
|
|
1427
|
+
expect(replicatingStreams).toHaveLength(1);
|
|
1428
|
+
expect(replicatingStreams[0].replicationStreamId).not.toEqual(active.replicationStreamId);
|
|
1429
|
+
|
|
1430
|
+
const oldStream = (await (factory as MongoBucketStorage).db.sync_rules.findOne({
|
|
1431
|
+
_id: active.replicationStreamId
|
|
1432
|
+
})) as ReplicationStreamDocumentV3;
|
|
1433
|
+
expect(oldStream.state).toBe(storage.SyncRuleState.ERRORED);
|
|
1434
|
+
expect(oldStream.sync_configs.map((config) => config.state)).toEqual([
|
|
1435
|
+
storage.SyncRuleState.ERRORED,
|
|
1436
|
+
storage.SyncRuleState.STOP
|
|
1437
|
+
]);
|
|
1438
|
+
const oldActive = await factory.getActiveSyncConfig();
|
|
1439
|
+
expect(oldActive).not.toBeNull();
|
|
1440
|
+
expect(oldActive!.replicationStream.syncConfigContent).toHaveLength(1);
|
|
1441
|
+
await expect(oldActive!.storage.getCheckpoint()).resolves.toBeDefined();
|
|
1442
|
+
});
|
|
1443
|
+
|
|
1133
1444
|
test.runIf(storageVersion >= 3)(
|
|
1134
1445
|
'appended compatible config adopts the stream checkpoint instead of regressing to 0',
|
|
1135
1446
|
async () => {
|
|
@@ -1149,7 +1460,7 @@ streams:
|
|
|
1149
1460
|
{ storageVersion }
|
|
1150
1461
|
)
|
|
1151
1462
|
);
|
|
1152
|
-
const firstStorage = factory
|
|
1463
|
+
const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
|
|
1153
1464
|
await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1154
1465
|
const sourceTable = await test_utils.resolveTestTable(
|
|
1155
1466
|
firstWriter,
|
|
@@ -1199,7 +1510,7 @@ streams:
|
|
|
1199
1510
|
|
|
1200
1511
|
const replicatingStreams = await factory.getReplicatingReplicationStreams();
|
|
1201
1512
|
expect(replicatingStreams).toHaveLength(1);
|
|
1202
|
-
const secondStorage = factory
|
|
1513
|
+
const secondStorage = (await getTestStorage(factory, replicatingStreams[0])) as MongoSyncBucketStorage;
|
|
1203
1514
|
await using secondWriter = await secondStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1204
1515
|
// No new data replicated - just complete the snapshot and commit.
|
|
1205
1516
|
await secondWriter.markAllSnapshotDone('2/1');
|
|
@@ -1218,7 +1529,10 @@ streams:
|
|
|
1218
1529
|
expect(head).toBeGreaterThanOrEqual(firstCheckpoint);
|
|
1219
1530
|
|
|
1220
1531
|
// After activation, the active config's checkpoint does not regress.
|
|
1221
|
-
const activeStorage = (await
|
|
1532
|
+
const activeStorage = (await getTestStorage(
|
|
1533
|
+
factory,
|
|
1534
|
+
(await factory.getActiveSyncConfig())!.replicationStream
|
|
1535
|
+
)) as MongoSyncBucketStorage;
|
|
1222
1536
|
const activeCheckpoint = (await activeStorage.getCheckpoint()).checkpoint;
|
|
1223
1537
|
expect(activeCheckpoint).toBeGreaterThanOrEqual(firstCheckpoint);
|
|
1224
1538
|
}
|
|
@@ -1240,7 +1554,7 @@ streams:
|
|
|
1240
1554
|
{ storageVersion }
|
|
1241
1555
|
)
|
|
1242
1556
|
);
|
|
1243
|
-
const firstStorage = factory
|
|
1557
|
+
const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
|
|
1244
1558
|
await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1245
1559
|
await firstWriter.markAllSnapshotDone('1/1');
|
|
1246
1560
|
await firstWriter.commit('1/1');
|
|
@@ -1287,7 +1601,7 @@ streams:
|
|
|
1287
1601
|
{ storageVersion }
|
|
1288
1602
|
)
|
|
1289
1603
|
);
|
|
1290
|
-
const firstStorage = factory
|
|
1604
|
+
const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
|
|
1291
1605
|
await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1292
1606
|
await firstWriter.markAllSnapshotDone('1/1');
|
|
1293
1607
|
await firstWriter.commit('1/1');
|
|
@@ -1302,7 +1616,7 @@ streams:
|
|
|
1302
1616
|
await using factory = await storageConfig.factory();
|
|
1303
1617
|
|
|
1304
1618
|
const first = await factory.updateSyncRules(updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion }));
|
|
1305
|
-
const firstStorage = factory
|
|
1619
|
+
const firstStorage = (await getTestStorage(factory, first)) as MongoSyncBucketStorage;
|
|
1306
1620
|
await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1307
1621
|
await firstWriter.markAllSnapshotDone('1/1');
|
|
1308
1622
|
await firstWriter.commit('1/1');
|
|
@@ -1375,7 +1689,7 @@ streams:
|
|
|
1375
1689
|
const first = await factory.updateSyncRules(updateSyncRulesFromYaml(firstRules, { storageVersion, lock: true }));
|
|
1376
1690
|
expect(first.current_lock?.sync_rules_id).toBe(first.replicationStreamId);
|
|
1377
1691
|
try {
|
|
1378
|
-
const firstStorage = factory.getInstance(first);
|
|
1692
|
+
const firstStorage = factory.getInstance(first, { replicationLock: first.current_lock! });
|
|
1379
1693
|
await using firstWriter = await firstStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1380
1694
|
await firstWriter.markAllSnapshotDone('1/1');
|
|
1381
1695
|
await firstWriter.commit('1/1');
|
|
@@ -1403,7 +1717,7 @@ streams:
|
|
|
1403
1717
|
{ storageVersion }
|
|
1404
1718
|
)
|
|
1405
1719
|
);
|
|
1406
|
-
const bucketStorage = factory
|
|
1720
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
1407
1721
|
|
|
1408
1722
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1409
1723
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], INITIALIZED_MONGO_STORAGE_FACTORY);
|
|
@@ -1442,7 +1756,7 @@ streams:
|
|
|
1442
1756
|
{ storageVersion }
|
|
1443
1757
|
)
|
|
1444
1758
|
);
|
|
1445
|
-
const bucketStorage = factory
|
|
1759
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
1446
1760
|
|
|
1447
1761
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1448
1762
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], INITIALIZED_MONGO_STORAGE_FACTORY);
|
|
@@ -1476,7 +1790,7 @@ streams:
|
|
|
1476
1790
|
storageVersion
|
|
1477
1791
|
})
|
|
1478
1792
|
);
|
|
1479
|
-
const bucketStorage = factory
|
|
1793
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
1480
1794
|
const mongoFactory = factory as MongoBucketStorage;
|
|
1481
1795
|
const sourceTableId = new bson.ObjectId();
|
|
1482
1796
|
const documents = Array.from({ length: 10_002 }, (_, index) => ({
|
|
@@ -1519,7 +1833,7 @@ streams:
|
|
|
1519
1833
|
storageVersion
|
|
1520
1834
|
})
|
|
1521
1835
|
);
|
|
1522
|
-
const bucketStorage = factory
|
|
1836
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
1523
1837
|
const mongoFactory = factory as MongoBucketStorage;
|
|
1524
1838
|
const sourceTableId = new bson.ObjectId();
|
|
1525
1839
|
const documents = Array.from({ length: 10_002 }, (_, index) => ({
|
|
@@ -1570,7 +1884,7 @@ streams:
|
|
|
1570
1884
|
{ storageVersion }
|
|
1571
1885
|
)
|
|
1572
1886
|
);
|
|
1573
|
-
const bucketStorage = factory
|
|
1887
|
+
const bucketStorage = await getTestStorage(factory, syncRules);
|
|
1574
1888
|
const metricsBefore = await factory.getStorageMetrics();
|
|
1575
1889
|
|
|
1576
1890
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
@@ -1595,6 +1909,22 @@ streams:
|
|
|
1595
1909
|
expect(metricsAfter.replication_size_bytes).toBeGreaterThan(metricsBefore.replication_size_bytes);
|
|
1596
1910
|
});
|
|
1597
1911
|
|
|
1912
|
+
test.runIf(storageVersion >= 3)('storage metrics include the sync config version label', async () => {
|
|
1913
|
+
await using factory = await storageConfig.factory();
|
|
1914
|
+
const syncRules = await factory.updateSyncRules(
|
|
1915
|
+
updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion, version_label: 'metrics-test' })
|
|
1916
|
+
);
|
|
1917
|
+
|
|
1918
|
+
const metrics = await factory.getStorageMetrics();
|
|
1919
|
+
|
|
1920
|
+
expect(metrics.sync_config_metrics).toContainEqual(
|
|
1921
|
+
expect.objectContaining({
|
|
1922
|
+
sync_config_id: syncRules.syncConfigContent[0].syncConfigId,
|
|
1923
|
+
version_label: 'metrics-test'
|
|
1924
|
+
})
|
|
1925
|
+
);
|
|
1926
|
+
});
|
|
1927
|
+
|
|
1598
1928
|
test.runIf(storageVersion >= 3)(
|
|
1599
1929
|
'loads parameter checkpoint changes across all v3 parameter index collections',
|
|
1600
1930
|
async () => {
|
|
@@ -1617,7 +1947,7 @@ streams:
|
|
|
1617
1947
|
{ storageVersion }
|
|
1618
1948
|
)
|
|
1619
1949
|
);
|
|
1620
|
-
const bucketStorage = factory
|
|
1950
|
+
const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
|
|
1621
1951
|
const previousCheckpoint = await bucketStorage.getCheckpoint();
|
|
1622
1952
|
|
|
1623
1953
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
@@ -1647,7 +1977,7 @@ streams:
|
|
|
1647
1977
|
}
|
|
1648
1978
|
);
|
|
1649
1979
|
|
|
1650
|
-
test.runIf(storageVersion
|
|
1980
|
+
test.runIf(storageVersion >= 3)('cleans pending deletes only for tracked v3 source tables', async () => {
|
|
1651
1981
|
await using factory = await storageConfig.factory();
|
|
1652
1982
|
const syncRules = await factory.updateSyncRules(
|
|
1653
1983
|
updateSyncRulesFromYaml(
|
|
@@ -1662,7 +1992,7 @@ streams:
|
|
|
1662
1992
|
);
|
|
1663
1993
|
|
|
1664
1994
|
const mongoFactory = factory as MongoBucketStorage;
|
|
1665
|
-
const bucketStorage = mongoFactory
|
|
1995
|
+
const bucketStorage = await getTestStorage(mongoFactory, syncRules);
|
|
1666
1996
|
const db = bucketStorage.db as VersionedPowerSyncMongoV3;
|
|
1667
1997
|
await db.initializeStreamStorage(syncRules.replicationStreamId);
|
|
1668
1998
|
|
|
@@ -1680,6 +2010,7 @@ streams:
|
|
|
1680
2010
|
snapshot_status: undefined,
|
|
1681
2011
|
bucket_data_source_ids: [],
|
|
1682
2012
|
parameter_lookup_source_ids: [],
|
|
2013
|
+
event_definition_ids: [],
|
|
1683
2014
|
latest_pending_delete: 9n
|
|
1684
2015
|
},
|
|
1685
2016
|
{
|
|
@@ -1693,6 +2024,7 @@ streams:
|
|
|
1693
2024
|
snapshot_status: undefined,
|
|
1694
2025
|
bucket_data_source_ids: [],
|
|
1695
2026
|
parameter_lookup_source_ids: [],
|
|
2027
|
+
event_definition_ids: [],
|
|
1696
2028
|
latest_pending_delete: 12n
|
|
1697
2029
|
}
|
|
1698
2030
|
]);
|
|
@@ -1755,7 +2087,7 @@ describe('sync - mongodb', () => {
|
|
|
1755
2087
|
const legacySyncRules = await factory.updateSyncRules(
|
|
1756
2088
|
updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion: storage.LEGACY_STORAGE_VERSION })
|
|
1757
2089
|
);
|
|
1758
|
-
const legacyStorage = factory
|
|
2090
|
+
const legacyStorage = await getTestStorage(factory, legacySyncRules);
|
|
1759
2091
|
await using legacyWriter = await legacyStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1760
2092
|
await legacyWriter.markAllSnapshotDone('1/1');
|
|
1761
2093
|
await legacyWriter.commit('1/1');
|
|
@@ -1767,7 +2099,7 @@ describe('sync - mongodb', () => {
|
|
|
1767
2099
|
const v3SyncRules = await factory.updateSyncRules(
|
|
1768
2100
|
updateSyncRulesFromYaml(MINIMAL_SYNC_RULES, { storageVersion: storage.STORAGE_VERSION_3 })
|
|
1769
2101
|
);
|
|
1770
|
-
const v3Storage = factory
|
|
2102
|
+
const v3Storage = await getTestStorage(factory, v3SyncRules);
|
|
1771
2103
|
await using v3Writer = await v3Storage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1772
2104
|
await v3Writer.markAllSnapshotDone('2/1');
|
|
1773
2105
|
await v3Writer.commit('2/1');
|
|
@@ -1781,7 +2113,7 @@ describe('sync - mongodb', () => {
|
|
|
1781
2113
|
describe(`storage v${storageVersion}`, () => {
|
|
1782
2114
|
registerSyncStorageTests(INITIALIZED_MONGO_STORAGE_FACTORY, storageVersion);
|
|
1783
2115
|
|
|
1784
|
-
describe.runIf(storageVersion
|
|
2116
|
+
describe.runIf(storageVersion >= 3)('V3 read filtering boundaries', () => {
|
|
1785
2117
|
async function setupFilteringTest() {
|
|
1786
2118
|
await using factory = await INITIALIZED_MONGO_STORAGE_FACTORY.factory();
|
|
1787
2119
|
const syncRules = await factory.updateSyncRules(
|
|
@@ -1795,7 +2127,7 @@ describe('sync - mongodb', () => {
|
|
|
1795
2127
|
{ storageVersion }
|
|
1796
2128
|
)
|
|
1797
2129
|
);
|
|
1798
|
-
const bucketStorage = factory
|
|
2130
|
+
const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorage;
|
|
1799
2131
|
const db = bucketStorage.db as VersionedPowerSyncMongoV3;
|
|
1800
2132
|
const mapping = syncRules.syncConfigContent[0].mapping;
|
|
1801
2133
|
|
|
@@ -1927,7 +2259,7 @@ describe('sync - mongodb', () => {
|
|
|
1927
2259
|
{ storageVersion }
|
|
1928
2260
|
)
|
|
1929
2261
|
);
|
|
1930
|
-
const bucketStorage = factory
|
|
2262
|
+
const bucketStorage = (await getTestStorage(factory, syncRules)) as MongoSyncBucketStorageV3;
|
|
1931
2263
|
const db = bucketStorage.db as VersionedPowerSyncMongoV3;
|
|
1932
2264
|
|
|
1933
2265
|
const start = 5n;
|