@powersync/service-module-mongodb-storage 0.0.0-dev-20260602073133 → 0.0.0-dev-20260909133214
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 +177 -5
- package/dist/migrations/db/migrations/1782950400000-checkpoint-requested-at-index.d.ts +3 -0
- package/dist/migrations/db/migrations/1782950400000-checkpoint-requested-at-index.js +41 -0
- package/dist/migrations/db/migrations/1782950400000-checkpoint-requested-at-index.js.map +1 -0
- package/dist/storage/MongoBucketStorage.d.ts +71 -18
- package/dist/storage/MongoBucketStorage.js +516 -202
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoBucketBatch.d.ts +71 -29
- package/dist/storage/implementation/MongoBucketBatch.js +140 -66
- package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
- package/dist/storage/implementation/MongoChecksums.d.ts +41 -13
- package/dist/storage/implementation/MongoChecksums.js +36 -121
- package/dist/storage/implementation/MongoChecksums.js.map +1 -1
- package/dist/storage/implementation/MongoCompactor.d.ts +28 -90
- package/dist/storage/implementation/MongoCompactor.js +87 -481
- package/dist/storage/implementation/MongoCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoHydrationState.d.ts +11 -0
- package/dist/storage/implementation/MongoHydrationState.js +49 -0
- package/dist/storage/implementation/MongoHydrationState.js.map +1 -0
- package/dist/storage/implementation/MongoParameterCompactor.d.ts +82 -8
- package/dist/storage/implementation/MongoParameterCompactor.js +312 -76
- package/dist/storage/implementation/MongoParameterCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoParsedSyncConfigSet.d.ts +21 -0
- package/dist/storage/implementation/MongoParsedSyncConfigSet.js +93 -0
- package/dist/storage/implementation/MongoParsedSyncConfigSet.js.map +1 -0
- package/dist/storage/implementation/MongoPersistedReplicationStream.d.ts +36 -0
- package/dist/storage/implementation/MongoPersistedReplicationStream.js +90 -0
- package/dist/storage/implementation/MongoPersistedReplicationStream.js.map +1 -0
- package/dist/storage/implementation/MongoPersistedSyncConfigContent.d.ts +25 -0
- package/dist/storage/implementation/MongoPersistedSyncConfigContent.js +125 -0
- package/dist/storage/implementation/MongoPersistedSyncConfigContent.js.map +1 -0
- package/dist/storage/implementation/MongoStorageProvider.js +41 -4
- package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +81 -37
- package/dist/storage/implementation/MongoSyncBucketStorage.js +159 -86
- package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoSyncRulesLock.d.ts +1 -1
- package/dist/storage/implementation/MongoSyncRulesLock.js +23 -11
- package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
- package/dist/storage/implementation/MongoWriteCheckpointAPI.d.ts +11 -8
- package/dist/storage/implementation/MongoWriteCheckpointAPI.js +159 -33
- 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 +28 -0
- package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.js +2 -0
- package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.js.map +1 -0
- package/dist/storage/implementation/common/PersistedBatch.d.ts +34 -2
- package/dist/storage/implementation/common/PersistedBatch.js +63 -10
- package/dist/storage/implementation/common/PersistedBatch.js.map +1 -1
- package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js +1 -1
- package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js.map +1 -1
- package/dist/storage/implementation/createMongoSyncBucketStorage.d.ts +2 -2
- package/dist/storage/implementation/createMongoSyncBucketStorage.js +4 -4
- package/dist/storage/implementation/createMongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/db.d.ts +4 -1
- package/dist/storage/implementation/db.js +31 -16
- package/dist/storage/implementation/db.js.map +1 -1
- package/dist/storage/implementation/models.d.ts +55 -13
- package/dist/storage/implementation/models.js.map +1 -1
- package/dist/storage/implementation/v1/MongoBucketBatchV1.d.ts +15 -1
- package/dist/storage/implementation/v1/MongoBucketBatchV1.js +135 -107
- package/dist/storage/implementation/v1/MongoBucketBatchV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoChecksumsV1.d.ts +4 -4
- package/dist/storage/implementation/v1/MongoChecksumsV1.js +119 -7
- package/dist/storage/implementation/v1/MongoChecksumsV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoCompactorV1.d.ts +47 -7
- package/dist/storage/implementation/v1/MongoCompactorV1.js +478 -8
- 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 +33 -27
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js +146 -73
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js.map +1 -1
- package/dist/storage/implementation/v1/SingleBucketStoreV1.d.ts +9 -10
- package/dist/storage/implementation/v1/SingleBucketStoreV1.js +2 -8
- package/dist/storage/implementation/v1/SingleBucketStoreV1.js.map +1 -1
- package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.d.ts +2 -1
- package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.js +3 -0
- package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.js.map +1 -1
- package/dist/storage/implementation/v1/models.d.ts +10 -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/BucketDataContextV3.d.ts +13 -0
- package/dist/storage/implementation/v3/BucketDataContextV3.js +23 -0
- package/dist/storage/implementation/v3/BucketDataContextV3.js.map +1 -0
- package/dist/storage/implementation/v3/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 +16 -5
- package/dist/storage/implementation/v3/MongoBucketBatchV3.js +393 -262
- package/dist/storage/implementation/v3/MongoBucketBatchV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoChecksumsV3.d.ts +30 -9
- package/dist/storage/implementation/v3/MongoChecksumsV3.js +161 -20
- package/dist/storage/implementation/v3/MongoChecksumsV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoCompactorV3.d.ts +108 -18
- package/dist/storage/implementation/v3/MongoCompactorV3.js +1115 -47
- package/dist/storage/implementation/v3/MongoCompactorV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoParameterCompactorV3.d.ts +12 -3
- package/dist/storage/implementation/v3/MongoParameterCompactorV3.js +13 -8
- package/dist/storage/implementation/v3/MongoParameterCompactorV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.d.ts +54 -0
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js +319 -0
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js.map +1 -0
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.d.ts +61 -36
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js +353 -161
- 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 +8 -3
- package/dist/storage/implementation/v3/PersistedBatchV3.js +131 -29
- package/dist/storage/implementation/v3/PersistedBatchV3.js.map +1 -1
- package/dist/storage/implementation/v3/SourceRecordStoreV3.d.ts +3 -3
- package/dist/storage/implementation/v3/SourceRecordStoreV3.js +13 -11
- package/dist/storage/implementation/v3/SourceRecordStoreV3.js.map +1 -1
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.d.ts +26 -14
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js +73 -29
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js.map +1 -1
- package/dist/storage/implementation/v3/bucket-format.d.ts +13 -0
- package/dist/storage/implementation/v3/bucket-format.js +79 -0
- package/dist/storage/implementation/v3/bucket-format.js.map +1 -0
- package/dist/storage/implementation/v3/chunking.d.ts +10 -0
- package/dist/storage/implementation/v3/chunking.js +30 -0
- package/dist/storage/implementation/v3/chunking.js.map +1 -0
- package/dist/storage/implementation/v3/compact-utils.d.ts +107 -0
- package/dist/storage/implementation/v3/compact-utils.js +216 -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 +187 -23
- package/dist/storage/implementation/v3/models.js +11 -28
- package/dist/storage/implementation/v3/models.js.map +1 -1
- package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.d.ts +20 -0
- package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.js +48 -0
- package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.js.map +1 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorage.d.ts +33 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorage.js +12 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorage.js.map +1 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.d.ts +68 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.js +154 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.js.map +1 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageUsage.d.ts +37 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageUsage.js +167 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageUsage.js.map +1 -0
- package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.d.ts +67 -0
- package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.js +439 -0
- package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.js.map +1 -0
- package/dist/storage/implementation/v3/source-table-utils.d.ts +63 -0
- package/dist/storage/implementation/v3/source-table-utils.js +206 -0
- package/dist/storage/implementation/v3/source-table-utils.js.map +1 -0
- package/dist/storage/storage-index.d.ts +5 -4
- package/dist/storage/storage-index.js +5 -4
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/types/types.d.ts +71 -3
- package/dist/types/types.js +58 -2
- package/dist/types/types.js.map +1 -1
- package/dist/utils/test-utils.d.ts +1 -2
- package/dist/utils/test-utils.js +7 -1
- package/dist/utils/test-utils.js.map +1 -1
- package/dist/utils/util.d.ts +9 -2
- package/dist/utils/util.js +131 -5
- package/dist/utils/util.js.map +1 -1
- package/package.json +13 -19
- package/src/migrations/db/migrations/1782950400000-checkpoint-requested-at-index.ts +55 -0
- package/src/storage/MongoBucketStorage.ts +728 -242
- package/src/storage/implementation/MongoBucketBatch.ts +196 -91
- package/src/storage/implementation/MongoChecksums.ts +93 -153
- package/src/storage/implementation/MongoCompactor.ts +106 -631
- package/src/storage/implementation/MongoHydrationState.ts +61 -0
- package/src/storage/implementation/MongoParameterCompactor.ts +392 -87
- package/src/storage/implementation/MongoParsedSyncConfigSet.ts +122 -0
- package/src/storage/implementation/MongoPersistedReplicationStream.ts +118 -0
- package/src/storage/implementation/MongoPersistedSyncConfigContent.ts +156 -0
- package/src/storage/implementation/MongoStorageProvider.ts +48 -4
- package/src/storage/implementation/MongoSyncBucketStorage.ts +226 -118
- package/src/storage/implementation/MongoSyncRulesLock.ts +28 -12
- package/src/storage/implementation/MongoWriteCheckpointAPI.ts +194 -52
- package/src/storage/implementation/SyncRuleStateUpdate.ts +13 -6
- package/src/storage/implementation/common/MongoSyncBucketStorageCheckpoint.ts +31 -0
- package/src/storage/implementation/common/PersistedBatch.ts +83 -15
- package/src/storage/implementation/common/VersionedPowerSyncMongoBase.ts +1 -1
- package/src/storage/implementation/createMongoSyncBucketStorage.ts +21 -7
- package/src/storage/implementation/db.ts +40 -22
- package/src/storage/implementation/models.ts +58 -14
- package/src/storage/implementation/v1/MongoBucketBatchV1.ts +174 -125
- package/src/storage/implementation/v1/MongoChecksumsV1.ts +154 -12
- package/src/storage/implementation/v1/MongoCompactorV1.ts +594 -25
- package/src/storage/implementation/v1/MongoParameterCompactorV1.ts +25 -9
- package/src/storage/implementation/v1/MongoSyncBucketStorageV1.ts +226 -129
- package/src/storage/implementation/v1/SingleBucketStoreV1.ts +18 -27
- package/src/storage/implementation/v1/VersionedPowerSyncMongoV1.ts +11 -1
- package/src/storage/implementation/v1/models.ts +12 -1
- package/src/storage/implementation/v3/BucketDataContextV3.ts +32 -0
- package/src/storage/implementation/v3/CompactionLease.ts +152 -0
- package/src/storage/implementation/v3/MongoBucketBatchV3.ts +502 -324
- package/src/storage/implementation/v3/MongoChecksumsV3.ts +250 -32
- package/src/storage/implementation/v3/MongoCompactorV3.ts +1439 -70
- package/src/storage/implementation/v3/MongoParameterCompactorV3.ts +19 -9
- package/src/storage/implementation/v3/MongoStoppedSyncConfigCleanup.ts +473 -0
- package/src/storage/implementation/v3/MongoSyncBucketStorageV3.ts +453 -211
- package/src/storage/implementation/v3/MongoWriteCheckpointAPIV3.ts +111 -0
- package/src/storage/implementation/v3/PersistedBatchV3.ts +169 -45
- package/src/storage/implementation/v3/SourceRecordStoreV3.ts +12 -12
- package/src/storage/implementation/v3/VersionedPowerSyncMongoV3.ts +99 -38
- package/src/storage/implementation/v3/bucket-format.ts +99 -0
- package/src/storage/implementation/v3/chunking.ts +40 -0
- package/src/storage/implementation/v3/compact-utils.ts +320 -0
- package/src/storage/implementation/v3/compaction-constants.ts +5 -0
- package/src/storage/implementation/v3/models.ts +228 -58
- package/src/storage/implementation/v3/object-storage/BucketDataObjectStorage.ts +62 -0
- package/src/storage/implementation/v3/object-storage/ObjectStorage.ts +44 -0
- package/src/storage/implementation/v3/object-storage/ObjectStorageLifecycle.ts +182 -0
- package/src/storage/implementation/v3/object-storage/ObjectStorageUsage.ts +230 -0
- package/src/storage/implementation/v3/object-storage/S3ObjectStorage.ts +573 -0
- package/src/storage/implementation/v3/source-table-utils.ts +398 -0
- package/src/storage/storage-index.ts +14 -4
- package/src/types/types.ts +76 -2
- package/src/utils/test-utils.ts +8 -3
- package/src/utils/util.ts +188 -7
- package/test/src/__snapshots__/storage.test.ts.snap +4 -54
- package/test/src/__snapshots__/storage_sync.test.ts.snap +652 -645
- package/test/src/cleanup-stopped-sync-configs.test.ts +698 -0
- package/test/src/compact-utils.test.ts +226 -0
- package/test/src/helpers/MemoryObjectStorage.ts +61 -0
- package/test/src/helpers/s3TestFactory.ts +69 -0
- package/test/src/object_storage_lifecycle.test.ts +59 -0
- package/test/src/object_storage_usage.test.ts +255 -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/setup.ts +6 -1
- package/test/src/storage.test.ts +478 -13
- package/test/src/storage_compacting.test.ts +2516 -107
- package/test/src/storage_object_storage_inline_threshold.test.ts +116 -0
- package/test/src/storage_s3_checksums.test.ts +190 -0
- package/test/src/storage_s3_compaction_lifecycle.test.ts +543 -0
- package/test/src/storage_s3_reading.test.ts +768 -0
- package/test/src/storage_s3_writing.test.ts +136 -0
- package/test/src/storage_sync.test.ts +1507 -76
- package/test/src/storeCurrentData.test.ts +227 -0
- package/test/src/util.ts +3 -2
- package/tsconfig.json +1 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/storage/implementation/BucketDefinitionMapping.d.ts +0 -15
- package/dist/storage/implementation/BucketDefinitionMapping.js +0 -58
- package/dist/storage/implementation/BucketDefinitionMapping.js.map +0 -1
- package/dist/storage/implementation/MongoPersistedSyncRules.d.ts +0 -14
- package/dist/storage/implementation/MongoPersistedSyncRules.js +0 -67
- package/dist/storage/implementation/MongoPersistedSyncRules.js.map +0 -1
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +0 -29
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +0 -76
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +0 -1
- package/dist/storage/implementation/common/MongoSyncBucketStorageContext.d.ts +0 -13
- package/dist/storage/implementation/common/MongoSyncBucketStorageContext.js +0 -2
- package/dist/storage/implementation/common/MongoSyncBucketStorageContext.js.map +0 -1
- package/dist/storage/implementation/common/SingleBucketStore.d.ts +0 -54
- package/dist/storage/implementation/common/SingleBucketStore.js +0 -3
- package/dist/storage/implementation/common/SingleBucketStore.js.map +0 -1
- package/dist/storage/implementation/v3/MongoParameterLookupV3.d.ts +0 -4
- package/dist/storage/implementation/v3/MongoParameterLookupV3.js +0 -9
- package/dist/storage/implementation/v3/MongoParameterLookupV3.js.map +0 -1
- package/dist/storage/implementation/v3/SingleBucketStoreV3.d.ts +0 -18
- package/dist/storage/implementation/v3/SingleBucketStoreV3.js +0 -48
- package/dist/storage/implementation/v3/SingleBucketStoreV3.js.map +0 -1
- package/src/storage/implementation/BucketDefinitionMapping.ts +0 -75
- package/src/storage/implementation/MongoPersistedSyncRules.ts +0 -82
- package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +0 -101
- package/src/storage/implementation/common/MongoSyncBucketStorageContext.ts +0 -15
- package/src/storage/implementation/common/SingleBucketStore.ts +0 -63
- package/src/storage/implementation/v3/MongoParameterLookupV3.ts +0 -11
- package/src/storage/implementation/v3/SingleBucketStoreV3.ts +0 -68
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { ServiceAssertionError } from '@powersync/lib-services-framework';
|
|
2
|
+
import {
|
|
3
|
+
CustomWriteCheckpointFilters,
|
|
4
|
+
GetCheckpointChangesOptions,
|
|
5
|
+
SingleSyncConfigBucketDefinitionMapping,
|
|
6
|
+
storage
|
|
7
|
+
} from '@powersync/service-core';
|
|
8
|
+
import { EventDefinitionId } from '@powersync/service-sync-rules';
|
|
9
|
+
import { MongoCheckpointAPIOptions, MongoWriteCheckpointAPI } from '../MongoWriteCheckpointAPI.js';
|
|
10
|
+
import { VersionedPowerSyncMongoV3 } from './VersionedPowerSyncMongoV3.js';
|
|
11
|
+
|
|
12
|
+
export type MongoCheckpointAPIV3Options = Omit<MongoCheckpointAPIOptions, 'db'> & {
|
|
13
|
+
db: VersionedPowerSyncMongoV3;
|
|
14
|
+
syncConfigMapping: () => SingleSyncConfigBucketDefinitionMapping;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class MongoWriteCheckpointAPIV3 extends MongoWriteCheckpointAPI {
|
|
18
|
+
declare db: VersionedPowerSyncMongoV3;
|
|
19
|
+
|
|
20
|
+
// Supplied via the constructor or the setWriteCheckpointMode setter.
|
|
21
|
+
private _customWriteCheckpointEventName: string | undefined;
|
|
22
|
+
private readonly syncConfigMapping: () => SingleSyncConfigBucketDefinitionMapping;
|
|
23
|
+
|
|
24
|
+
constructor(options: MongoCheckpointAPIV3Options) {
|
|
25
|
+
super(options);
|
|
26
|
+
this.syncConfigMapping = options.syncConfigMapping;
|
|
27
|
+
// Enforce the CUSTOM-requires-event-name invariant on construction too, not only setWriteCheckpointMode.
|
|
28
|
+
this._customWriteCheckpointEventName = this.requireCustomEventName(options.writeCheckpointMode);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
protected resolveEventId(): EventDefinitionId {
|
|
32
|
+
const eventName = this._customWriteCheckpointEventName;
|
|
33
|
+
if (!eventName) {
|
|
34
|
+
throw new ServiceAssertionError(`No eventName has been supplied via setWriteCheckpointMode.`);
|
|
35
|
+
}
|
|
36
|
+
return this.syncConfigMapping().eventDefinitionIdByName(eventName);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
protected override async lastCustomWriteCheckpoint(filters: CustomWriteCheckpointFilters): Promise<bigint | null> {
|
|
40
|
+
const { user_id } = filters;
|
|
41
|
+
const eventId = this.resolveEventId();
|
|
42
|
+
|
|
43
|
+
const lastWriteCheckpoint = await this.db
|
|
44
|
+
.customCheckpointRequests({
|
|
45
|
+
eventId,
|
|
46
|
+
replicationStreamId: this.replicationStreamId
|
|
47
|
+
})
|
|
48
|
+
.findOne({
|
|
49
|
+
user_id
|
|
50
|
+
});
|
|
51
|
+
return lastWriteCheckpoint?.checkpoint ?? null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
override setWriteCheckpointMode(config: storage.WriteCheckpointModeConfig): void {
|
|
55
|
+
this._customWriteCheckpointEventName = this.requireCustomEventName(config);
|
|
56
|
+
super.setWriteCheckpointMode(config);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Validates and returns the event name for the given mode config. Shared by the constructor and
|
|
61
|
+
* {@link setWriteCheckpointMode} so both paths enforce that CUSTOM mode always names its checkpoint event.
|
|
62
|
+
*/
|
|
63
|
+
private requireCustomEventName(config: storage.WriteCheckpointModeConfig): string | undefined {
|
|
64
|
+
if (config.mode != storage.WriteCheckpointMode.CUSTOM) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
if (!config.eventName) {
|
|
68
|
+
throw new ServiceAssertionError(`V3 incremental reprocessing requires an eventName to be supplied.`);
|
|
69
|
+
}
|
|
70
|
+
return config.eventName;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
protected override async getCustomWriteCheckpointChanges(
|
|
74
|
+
options: GetCheckpointChangesOptions
|
|
75
|
+
): Promise<{ invalidateWriteCheckpoints: boolean; updatedWriteCheckpoints: Map<string, bigint> }> {
|
|
76
|
+
const eventId = this.resolveEventId();
|
|
77
|
+
|
|
78
|
+
const limit = 1000;
|
|
79
|
+
const changes = await this.db
|
|
80
|
+
.customCheckpointRequests({
|
|
81
|
+
replicationStreamId: this.replicationStreamId,
|
|
82
|
+
eventId
|
|
83
|
+
})
|
|
84
|
+
.find(
|
|
85
|
+
{
|
|
86
|
+
op_id: { $gt: options.lastCheckpoint.checkpoint, $lte: options.nextCheckpoint.checkpoint }
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
limit: limit + 1,
|
|
90
|
+
// batchSize is 1 more than limit to auto-close the cursor.
|
|
91
|
+
// See https://github.com/mongodb/node-mongodb-native/pull/4580
|
|
92
|
+
batchSize: limit + 2,
|
|
93
|
+
singleBatch: true
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
.toArray();
|
|
97
|
+
const invalidate = changes.length > limit;
|
|
98
|
+
|
|
99
|
+
const updatedWriteCheckpoints = new Map<string, bigint>();
|
|
100
|
+
if (!invalidate) {
|
|
101
|
+
for (let c of changes) {
|
|
102
|
+
updatedWriteCheckpoints.set(c.user_id, c.checkpoint);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
invalidateWriteCheckpoints: invalidate,
|
|
108
|
+
updatedWriteCheckpoints
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -1,69 +1,99 @@
|
|
|
1
1
|
import { mongo } from '@powersync/lib-service-mongodb';
|
|
2
2
|
import { ReplicationAssertionError } from '@powersync/lib-services-framework';
|
|
3
|
-
import { InternalOpId, storage } from '@powersync/service-core';
|
|
3
|
+
import { BucketDefinitionMapping, InternalOpId, storage } from '@powersync/service-core';
|
|
4
4
|
import { BucketDataSource, BucketDefinitionId } from '@powersync/service-sync-rules';
|
|
5
5
|
import * as bson from 'bson';
|
|
6
6
|
import { mongoTableId } from '../../../utils/util.js';
|
|
7
|
+
import { BucketDataDoc } from '../common/BucketDataDoc.js';
|
|
7
8
|
import {
|
|
8
9
|
BucketStateUpdate,
|
|
9
10
|
PersistedBatch,
|
|
11
|
+
PersistedBatchOptions,
|
|
10
12
|
SaveParameterDataOptions,
|
|
11
13
|
UpsertCurrentDataOptions
|
|
12
14
|
} from '../common/PersistedBatch.js';
|
|
13
|
-
import {
|
|
15
|
+
import { SourceRecordLookupState } from '../common/SourceRecordStore.js';
|
|
16
|
+
import { serializeBucketData } from './bucket-format.js';
|
|
17
|
+
import { chunkBucketData } from './chunking.js';
|
|
18
|
+
import { DEFAULT_MIN_COMPACT_CHUNK_INTERVAL_MS } from './compaction-constants.js';
|
|
14
19
|
import {
|
|
15
|
-
|
|
20
|
+
BucketDataDocumentV3,
|
|
16
21
|
BucketStateDocumentV3,
|
|
17
22
|
CurrentDataDocumentV3,
|
|
18
|
-
|
|
23
|
+
serializeParameterLookup,
|
|
19
24
|
SourceTableDocumentV3,
|
|
20
|
-
|
|
25
|
+
taggedBucketParameterDocumentToTagged
|
|
21
26
|
} from './models.js';
|
|
22
|
-
import {
|
|
27
|
+
import { ObjectStorageLifecycle } from './object-storage/ObjectStorageLifecycle.js';
|
|
28
|
+
import { ObjectStorageUsage } from './object-storage/ObjectStorageUsage.js';
|
|
23
29
|
import { VersionedPowerSyncMongoV3 } from './VersionedPowerSyncMongoV3.js';
|
|
24
30
|
|
|
25
31
|
export class PersistedBatchV3 extends PersistedBatch {
|
|
26
|
-
declare protected readonly db: VersionedPowerSyncMongoV3;
|
|
27
|
-
|
|
28
32
|
currentData: { sourceTableId: bson.ObjectId; operation: mongo.AnyBulkWriteOperation<CurrentDataDocumentV3> }[] = [];
|
|
29
33
|
sourceTablePendingDeletes = new Map<string, InternalOpId>();
|
|
34
|
+
protected readonly objectStorageLifecycle?: ObjectStorageLifecycle;
|
|
35
|
+
protected readonly objectStorageUsage?: ObjectStorageUsage;
|
|
36
|
+
|
|
37
|
+
declare protected readonly db: VersionedPowerSyncMongoV3;
|
|
38
|
+
|
|
39
|
+
constructor(
|
|
40
|
+
db: VersionedPowerSyncMongoV3,
|
|
41
|
+
group_id: number,
|
|
42
|
+
mapping: BucketDefinitionMapping,
|
|
43
|
+
writtenSize: number,
|
|
44
|
+
options?: PersistedBatchOptions
|
|
45
|
+
) {
|
|
46
|
+
super(db, group_id, mapping, writtenSize, options);
|
|
47
|
+
if (this.objectStorage) {
|
|
48
|
+
this.objectStorageLifecycle = new ObjectStorageLifecycle(this.db, this.group_id, this.objectStorage);
|
|
49
|
+
this.objectStorageUsage = new ObjectStorageUsage(this.db, this.group_id, this.objectStorageUsageWriterId);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Abstract override from PersistedBatch (V3-specific error message)
|
|
30
54
|
|
|
31
|
-
protected checkDefinitionId(definitionId: BucketDefinitionId | null): BucketDefinitionId {
|
|
55
|
+
protected override checkDefinitionId(definitionId: BucketDefinitionId | null): BucketDefinitionId {
|
|
32
56
|
if (definitionId == null) {
|
|
33
|
-
// This is required for V3 storage.
|
|
34
57
|
throw new ReplicationAssertionError('Expected v3 bucket when incrementalReprocessing is enabled');
|
|
35
58
|
}
|
|
36
59
|
return definitionId;
|
|
37
60
|
}
|
|
38
61
|
|
|
62
|
+
// Concrete implementations from PersistedBatchShared
|
|
63
|
+
|
|
39
64
|
protected getBucketDefinitionId(bucketSource: BucketDataSource): BucketDefinitionId {
|
|
40
65
|
return this.mapping.bucketSourceId(bucketSource);
|
|
41
66
|
}
|
|
42
67
|
|
|
43
68
|
saveParameterData(data: SaveParameterDataOptions) {
|
|
44
69
|
const { sourceTable, sourceKey, evaluated } = data;
|
|
45
|
-
const remaining_lookups = new Map<string,
|
|
70
|
+
const remaining_lookups = new Map<string, SourceRecordLookupState>();
|
|
46
71
|
|
|
47
72
|
for (let lookup of data.existing_lookups) {
|
|
48
73
|
if (lookup.indexId == null) {
|
|
49
|
-
throw new ReplicationAssertionError('Expected
|
|
74
|
+
throw new ReplicationAssertionError('Expected lookup when incrementalReprocessing is enabled');
|
|
75
|
+
}
|
|
76
|
+
if (sourceTable.parameterLookupSourceIds != null && !sourceTable.parameterLookupSourceIds.has(lookup.indexId)) {
|
|
77
|
+
// The parameter index is not active anymore.
|
|
78
|
+
// We don't cleanup these references upfront, but do need to ignore them after the definition is removed.
|
|
79
|
+
continue;
|
|
50
80
|
}
|
|
51
81
|
remaining_lookups.set(`${lookup.indexId}.${lookup.lookup.toString('base64')}`, lookup);
|
|
52
82
|
}
|
|
53
83
|
|
|
54
84
|
for (let result of evaluated) {
|
|
55
85
|
const sourceDefinitionId = this.mapping.parameterLookupId(result.lookup.source);
|
|
56
|
-
const binLookup =
|
|
86
|
+
const binLookup = serializeParameterLookup(result.lookup);
|
|
57
87
|
remaining_lookups.delete(`${sourceDefinitionId}.${binLookup.toString('base64')}`);
|
|
58
88
|
|
|
59
89
|
const op_id = data.op_seq.next();
|
|
60
90
|
this.debugLastOpId = op_id;
|
|
61
|
-
const values
|
|
91
|
+
const values = {
|
|
62
92
|
_id: op_id,
|
|
63
93
|
key: {
|
|
64
94
|
t: mongoTableId(sourceTable.id),
|
|
65
95
|
k: sourceKey
|
|
66
|
-
}
|
|
96
|
+
},
|
|
67
97
|
lookup: binLookup,
|
|
68
98
|
bucket_parameters: result.bucketParameters
|
|
69
99
|
};
|
|
@@ -80,14 +110,14 @@ export class PersistedBatchV3 extends PersistedBatch {
|
|
|
80
110
|
this.debugLastOpId = op_id;
|
|
81
111
|
const indexId = lookup.indexId;
|
|
82
112
|
if (indexId == null) {
|
|
83
|
-
throw new ReplicationAssertionError('Expected
|
|
113
|
+
throw new ReplicationAssertionError('Expected lookup when incrementalReprocessing is enabled');
|
|
84
114
|
}
|
|
85
|
-
const values
|
|
115
|
+
const values = {
|
|
86
116
|
_id: op_id,
|
|
87
117
|
key: {
|
|
88
118
|
t: mongoTableId(sourceTable.id),
|
|
89
119
|
k: sourceKey
|
|
90
|
-
}
|
|
120
|
+
},
|
|
91
121
|
lookup: lookup.lookup,
|
|
92
122
|
bucket_parameters: []
|
|
93
123
|
};
|
|
@@ -125,8 +155,8 @@ export class PersistedBatchV3 extends PersistedBatch {
|
|
|
125
155
|
update: {
|
|
126
156
|
$set: {
|
|
127
157
|
data: null,
|
|
128
|
-
buckets: []
|
|
129
|
-
lookups: []
|
|
158
|
+
buckets: [],
|
|
159
|
+
lookups: [],
|
|
130
160
|
pending_delete: checkpointGreaterThan
|
|
131
161
|
}
|
|
132
162
|
},
|
|
@@ -146,7 +176,7 @@ export class PersistedBatchV3 extends PersistedBatch {
|
|
|
146
176
|
upsertCurrentData(values: UpsertCurrentDataOptions) {
|
|
147
177
|
const buckets = values.buckets.map((bucket) => {
|
|
148
178
|
if (bucket.definitionId == null) {
|
|
149
|
-
throw new ReplicationAssertionError('Expected
|
|
179
|
+
throw new ReplicationAssertionError('Expected bucket when incrementalReprocessing is enabled');
|
|
150
180
|
}
|
|
151
181
|
return {
|
|
152
182
|
def: bucket.definitionId,
|
|
@@ -157,7 +187,7 @@ export class PersistedBatchV3 extends PersistedBatch {
|
|
|
157
187
|
});
|
|
158
188
|
const lookups = values.lookups.map((lookup) => {
|
|
159
189
|
if (lookup.indexId == null) {
|
|
160
|
-
throw new ReplicationAssertionError('Expected
|
|
190
|
+
throw new ReplicationAssertionError('Expected lookup when incrementalReprocessing is enabled');
|
|
161
191
|
}
|
|
162
192
|
return {
|
|
163
193
|
i: lookup.indexId,
|
|
@@ -189,26 +219,93 @@ export class PersistedBatchV3 extends PersistedBatch {
|
|
|
189
219
|
return this.currentData.length;
|
|
190
220
|
}
|
|
191
221
|
|
|
222
|
+
// Flush methods
|
|
223
|
+
|
|
192
224
|
protected async flushBucketData(session: mongo.ClientSession) {
|
|
193
|
-
const operationsByDefinition = new Map<BucketDefinitionId,
|
|
225
|
+
const operationsByDefinition = new Map<BucketDefinitionId, BucketDataDoc[]>();
|
|
194
226
|
for (const document of this.bucketData) {
|
|
195
227
|
const existing = operationsByDefinition.get(document.bucketKey.definitionId) ?? [];
|
|
196
228
|
existing.push(document);
|
|
197
229
|
operationsByDefinition.set(document.bucketKey.definitionId, existing);
|
|
198
230
|
}
|
|
199
231
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
232
|
+
const plans = Array.from(operationsByDefinition, ([definitionId, documents]) => {
|
|
233
|
+
const operationsByBucket = Map.groupBy(documents, (document) => document.bucketKey.bucket);
|
|
234
|
+
const lifecycle = this.objectStorageLifecycle;
|
|
235
|
+
type BucketDataInsert = { insertOne: { document: BucketDataDocumentV3 } };
|
|
236
|
+
const createInserts: (() => Promise<BucketDataInsert>)[] = [];
|
|
237
|
+
|
|
238
|
+
for (const [bucket, ops] of operationsByBucket) {
|
|
239
|
+
this.resetBucketPersistedBytes(definitionId, bucket);
|
|
240
|
+
for (const chunk of chunkBucketData(ops)) {
|
|
241
|
+
const serialized = serializeBucketData(bucket, chunk);
|
|
242
|
+
this.incrementBucketPersistedChunk(definitionId, bucket, serialized.size);
|
|
243
|
+
if (lifecycle == null || serialized.size <= this.inlineThresholdBytes) {
|
|
244
|
+
createInserts.push(async () => ({
|
|
245
|
+
insertOne: {
|
|
246
|
+
document: serialized
|
|
247
|
+
}
|
|
248
|
+
}));
|
|
249
|
+
continue;
|
|
205
250
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
251
|
+
|
|
252
|
+
createInserts.push(async () => {
|
|
253
|
+
const minOp = chunk[0].o;
|
|
254
|
+
const maxOp = chunk[chunk.length - 1].o;
|
|
255
|
+
const { ops: bucketOps, ...metadata } = serialized;
|
|
256
|
+
const path = lifecycle.allocatePath(definitionId, bucket, minOp, maxOp);
|
|
257
|
+
const { fileSize } = await lifecycle.bucketData.store(path, bucketOps!, { signal: this.signal });
|
|
258
|
+
return {
|
|
259
|
+
insertOne: {
|
|
260
|
+
document: {
|
|
261
|
+
...metadata,
|
|
262
|
+
storage_ref: {
|
|
263
|
+
path,
|
|
264
|
+
file_size: fileSize
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
});
|
|
210
270
|
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return { definitionId, createInserts };
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
const createAllInserts = () =>
|
|
277
|
+
Promise.all(
|
|
278
|
+
plans.map(async ({ definitionId, createInserts }) => ({
|
|
279
|
+
definitionId,
|
|
280
|
+
inserts: await Promise.all(createInserts.map((createInsert) => createInsert()))
|
|
281
|
+
}))
|
|
211
282
|
);
|
|
283
|
+
|
|
284
|
+
// S3ObjectStorage applies one shared concurrency limit across all callers,
|
|
285
|
+
// so replication can schedule its uploads together without creating a
|
|
286
|
+
// separate limiter here.
|
|
287
|
+
const writes = await createAllInserts();
|
|
288
|
+
|
|
289
|
+
const usageDeltas = this.objectStorageUsage == null ? undefined : new Map<BucketDefinitionId, bigint>();
|
|
290
|
+
for (const { definitionId, inserts } of writes) {
|
|
291
|
+
if (usageDeltas != null) {
|
|
292
|
+
const delta = inserts.reduce(
|
|
293
|
+
(sum, operation) => sum + ObjectStorageUsage.bytes(operation.insertOne.document),
|
|
294
|
+
0n
|
|
295
|
+
);
|
|
296
|
+
if (delta !== 0n) {
|
|
297
|
+
usageDeltas.set(definitionId, delta);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (inserts.length > 0) {
|
|
301
|
+
await this.db.bucketData(this.group_id, definitionId).bulkWrite(inserts, {
|
|
302
|
+
session,
|
|
303
|
+
ordered: false
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (usageDeltas != null) {
|
|
308
|
+
await this.objectStorageUsage!.applyDeltas(usageDeltas, session);
|
|
212
309
|
}
|
|
213
310
|
}
|
|
214
311
|
|
|
@@ -221,10 +318,10 @@ export class PersistedBatchV3 extends PersistedBatch {
|
|
|
221
318
|
}
|
|
222
319
|
|
|
223
320
|
for (const [indexId, documents] of operationsByIndex.entries()) {
|
|
224
|
-
await this.db.
|
|
321
|
+
await this.db.parameterIndex(this.group_id, indexId).bulkWrite(
|
|
225
322
|
documents.map((document) => ({
|
|
226
323
|
insertOne: {
|
|
227
|
-
document:
|
|
324
|
+
document: taggedBucketParameterDocumentToTagged(document)
|
|
228
325
|
}
|
|
229
326
|
})),
|
|
230
327
|
{
|
|
@@ -260,12 +357,12 @@ export class PersistedBatchV3 extends PersistedBatch {
|
|
|
260
357
|
});
|
|
261
358
|
|
|
262
359
|
if (sourceTableUpdates.length > 0) {
|
|
263
|
-
await this.db.
|
|
360
|
+
await this.db.sourceTables(this.group_id).bulkWrite(sourceTableUpdates, { session, ordered: false });
|
|
264
361
|
}
|
|
265
362
|
|
|
266
363
|
for (const operations of operationsBySourceTable.values()) {
|
|
267
364
|
const sourceTableId = operations[0]!.sourceTableId;
|
|
268
|
-
await this.db.
|
|
365
|
+
await this.db.sourceRecords(this.group_id, sourceTableId).bulkWrite(
|
|
269
366
|
operations.map((entry) => entry.operation),
|
|
270
367
|
{
|
|
271
368
|
session,
|
|
@@ -276,7 +373,7 @@ export class PersistedBatchV3 extends PersistedBatch {
|
|
|
276
373
|
}
|
|
277
374
|
|
|
278
375
|
protected async flushBucketStates(session: mongo.ClientSession) {
|
|
279
|
-
await this.db.
|
|
376
|
+
await this.db.bucketState(this.group_id).bulkWrite(this.getBucketStateUpdates(), {
|
|
280
377
|
session,
|
|
281
378
|
ordered: false
|
|
282
379
|
});
|
|
@@ -300,15 +397,42 @@ export class PersistedBatchV3 extends PersistedBatch {
|
|
|
300
397
|
b: state.bucket
|
|
301
398
|
}
|
|
302
399
|
},
|
|
303
|
-
update
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
400
|
+
// A pipeline update makes initialisation and scheduling one atomic
|
|
401
|
+
// writer operation. In particular, a later write cannot move an
|
|
402
|
+
// already-due compact check into the future.
|
|
403
|
+
update: [
|
|
404
|
+
{
|
|
405
|
+
$set: {
|
|
406
|
+
last_op: state.lastOp,
|
|
407
|
+
bucket_stats: {
|
|
408
|
+
count: { $add: [{ $ifNull: ['$bucket_stats.count', 0] }, state.incrementCount] },
|
|
409
|
+
bytes: { $add: [{ $ifNull: ['$bucket_stats.bytes', 0n] }, BigInt(state.incrementBytes)] },
|
|
410
|
+
chunks: { $add: [{ $ifNull: ['$bucket_stats.chunks', 0] }, state.incrementChunks] }
|
|
411
|
+
},
|
|
412
|
+
first_uncompacted_write: { $ifNull: ['$first_uncompacted_write', '$$NOW'] },
|
|
413
|
+
next_compact_check: {
|
|
414
|
+
$let: {
|
|
415
|
+
vars: {
|
|
416
|
+
requested: {
|
|
417
|
+
$dateAdd: {
|
|
418
|
+
startDate: '$$NOW',
|
|
419
|
+
unit: 'millisecond',
|
|
420
|
+
amount: DEFAULT_MIN_COMPACT_CHUNK_INTERVAL_MS
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
in: {
|
|
425
|
+
$cond: [
|
|
426
|
+
{ $lt: [{ $ifNull: ['$next_compact_check', '$$requested'] }, '$$requested'] },
|
|
427
|
+
'$next_compact_check',
|
|
428
|
+
'$$requested'
|
|
429
|
+
]
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
310
434
|
}
|
|
311
|
-
|
|
435
|
+
],
|
|
312
436
|
upsert: true
|
|
313
437
|
}
|
|
314
438
|
} satisfies mongo.AnyBulkWriteOperation<BucketStateDocumentV3>;
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
import * as lib_mongo from '@powersync/lib-service-mongodb';
|
|
2
2
|
import { mongo } from '@powersync/lib-service-mongodb';
|
|
3
3
|
import { Logger } from '@powersync/lib-services-framework';
|
|
4
|
-
import { storage } from '@powersync/service-core';
|
|
4
|
+
import { BucketDefinitionMapping, storage } from '@powersync/service-core';
|
|
5
5
|
import { EvaluatedParameters, EvaluatedRow } from '@powersync/service-sync-rules';
|
|
6
6
|
import * as bson from 'bson';
|
|
7
7
|
import { retryOnMongoMaxTimeMSExpired } from '../../../utils/util.js';
|
|
8
|
-
import { BucketDefinitionMapping } from '../BucketDefinitionMapping.js';
|
|
9
8
|
import { cacheKey } from '../OperationBatch.js';
|
|
10
9
|
import { LoadedSourceRecord, SourceRecordLookupEntry, SourceRecordStore } from '../common/SourceRecordStore.js';
|
|
11
|
-
import { serializeParameterLookupV3 } from './MongoParameterLookupV3.js';
|
|
12
10
|
import { VersionedPowerSyncMongoV3 } from './VersionedPowerSyncMongoV3.js';
|
|
13
|
-
import { CurrentDataDocumentV3, SourceTableDocumentV3 } from './models.js';
|
|
11
|
+
import { CurrentDataDocumentV3, serializeParameterLookup, SourceTableDocumentV3 } from './models.js';
|
|
14
12
|
|
|
15
13
|
export class SourceRecordStoreV3 implements SourceRecordStore {
|
|
16
14
|
constructor(
|
|
17
15
|
private readonly db: VersionedPowerSyncMongoV3,
|
|
18
|
-
private readonly
|
|
16
|
+
private readonly replicationStreamId: number,
|
|
19
17
|
private readonly mapping: BucketDefinitionMapping
|
|
20
18
|
) {}
|
|
21
19
|
|
|
@@ -31,7 +29,7 @@ export class SourceRecordStoreV3 implements SourceRecordStore {
|
|
|
31
29
|
mapParameterLookups(paramEvaluated: EvaluatedParameters[]): LoadedSourceRecord['lookups'] {
|
|
32
30
|
return paramEvaluated.map((entry) => ({
|
|
33
31
|
indexId: this.mapping.parameterLookupId(entry.lookup.source),
|
|
34
|
-
lookup:
|
|
32
|
+
lookup: serializeParameterLookup(entry.lookup)
|
|
35
33
|
}));
|
|
36
34
|
}
|
|
37
35
|
|
|
@@ -67,7 +65,7 @@ export class SourceRecordStoreV3 implements SourceRecordStore {
|
|
|
67
65
|
_id: { $in: replicaIds as any[] }
|
|
68
66
|
} as unknown as mongo.Filter<CurrentDataDocumentV3>;
|
|
69
67
|
const sizeCursor: mongo.AggregationCursor<CurrentDataDocumentV3 & { size: number }> = this.db
|
|
70
|
-
.
|
|
68
|
+
.sourceRecords(this.replicationStreamId, sourceTableId)
|
|
71
69
|
.aggregate(
|
|
72
70
|
[
|
|
73
71
|
{
|
|
@@ -100,7 +98,9 @@ export class SourceRecordStoreV3 implements SourceRecordStore {
|
|
|
100
98
|
const filter = {
|
|
101
99
|
_id: { $in: replicaIds as any[] }
|
|
102
100
|
} as unknown as mongo.Filter<CurrentDataDocumentV3>;
|
|
103
|
-
const cursor = this.db
|
|
101
|
+
const cursor = this.db
|
|
102
|
+
.sourceRecords(this.replicationStreamId, sourceTableId)
|
|
103
|
+
.find(filter, { session, projection });
|
|
104
104
|
for await (const doc of cursor.stream()) {
|
|
105
105
|
const loaded = this.createLoadedDocument(
|
|
106
106
|
sourceTableId,
|
|
@@ -120,7 +120,7 @@ export class SourceRecordStoreV3 implements SourceRecordStore {
|
|
|
120
120
|
sourceTableId: bson.ObjectId,
|
|
121
121
|
limit: number
|
|
122
122
|
): Promise<LoadedSourceRecord[]> {
|
|
123
|
-
const cursor = this.db.
|
|
123
|
+
const cursor = this.db.sourceRecords(this.replicationStreamId, sourceTableId).find(
|
|
124
124
|
{
|
|
125
125
|
pending_delete: { $exists: false }
|
|
126
126
|
},
|
|
@@ -145,7 +145,7 @@ export class SourceRecordStoreV3 implements SourceRecordStore {
|
|
|
145
145
|
// ones have dirty deletes in source_tables.
|
|
146
146
|
|
|
147
147
|
const dirtySourceTables = await this.db
|
|
148
|
-
.
|
|
148
|
+
.sourceTables(this.replicationStreamId)
|
|
149
149
|
.find(
|
|
150
150
|
{
|
|
151
151
|
latest_pending_delete: { $exists: true }
|
|
@@ -159,7 +159,7 @@ export class SourceRecordStoreV3 implements SourceRecordStore {
|
|
|
159
159
|
let deletedCount = 0;
|
|
160
160
|
const sourceTableUpdates: mongo.AnyBulkWriteOperation<SourceTableDocumentV3>[] = [];
|
|
161
161
|
for (const sourceTable of dirtySourceTables) {
|
|
162
|
-
const collection = this.db.
|
|
162
|
+
const collection = this.db.sourceRecords(this.replicationStreamId, sourceTable._id);
|
|
163
163
|
const result = await this.deletePendingDeletes(collection, sourceTable._id, lastCheckpoint, logger);
|
|
164
164
|
deletedCount += result.deletedCount;
|
|
165
165
|
|
|
@@ -182,7 +182,7 @@ export class SourceRecordStoreV3 implements SourceRecordStore {
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
if (sourceTableUpdates.length > 0) {
|
|
185
|
-
await this.db.
|
|
185
|
+
await this.db.sourceTables(this.replicationStreamId).bulkWrite(sourceTableUpdates, { ordered: false });
|
|
186
186
|
}
|
|
187
187
|
if (deletedCount > 0) {
|
|
188
188
|
logger.info(`Cleaned up ${deletedCount} pending delete current_data records for checkpoint ${lastCheckpoint}`);
|