@powersync/service-module-mongodb 0.0.0-dev-20241128134723 → 0.0.0-dev-20241219110735
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 +69 -4
- package/dist/db/db-index.d.ts +1 -0
- package/dist/db/db-index.js +2 -0
- package/dist/db/db-index.js.map +1 -0
- package/dist/db/mongo.d.ts +35 -0
- package/dist/db/mongo.js +73 -0
- package/dist/db/mongo.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/locks/MonogLocks.d.ts +36 -0
- package/dist/locks/MonogLocks.js +83 -0
- package/dist/locks/MonogLocks.js.map +1 -0
- package/dist/migrations/MonogMigrationAgent.d.ts +12 -0
- package/dist/migrations/MonogMigrationAgent.js +25 -0
- package/dist/migrations/MonogMigrationAgent.js.map +1 -0
- package/dist/migrations/db/migrations/1684951997326-init.d.ts +3 -0
- package/dist/migrations/db/migrations/1684951997326-init.js +30 -0
- package/dist/migrations/db/migrations/1684951997326-init.js.map +1 -0
- package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.d.ts +2 -0
- package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.js +5 -0
- package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.js.map +1 -0
- package/dist/migrations/db/migrations/1702295701188-sync-rule-state.d.ts +3 -0
- package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js +54 -0
- package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js.map +1 -0
- package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.d.ts +3 -0
- package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js +26 -0
- package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js.map +1 -0
- package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.d.ts +3 -0
- package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.js +28 -0
- package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.js.map +1 -0
- package/dist/migrations/mongo-migration-store.d.ts +7 -0
- package/dist/migrations/mongo-migration-store.js +49 -0
- package/dist/migrations/mongo-migration-store.js.map +1 -0
- package/dist/module/MongoModule.js +15 -4
- package/dist/module/MongoModule.js.map +1 -1
- package/dist/replication/MongoManager.d.ts +1 -1
- package/dist/replication/MongoManager.js +3 -2
- package/dist/replication/MongoManager.js.map +1 -1
- package/dist/storage/MongoBucketStorage.d.ts +48 -0
- package/dist/storage/MongoBucketStorage.js +425 -0
- package/dist/storage/MongoBucketStorage.js.map +1 -0
- package/dist/storage/implementation/MongoBucketBatch.d.ts +72 -0
- package/dist/storage/implementation/MongoBucketBatch.js +681 -0
- package/dist/storage/implementation/MongoBucketBatch.js.map +1 -0
- package/dist/storage/implementation/MongoCompactor.d.ts +40 -0
- package/dist/storage/implementation/MongoCompactor.js +310 -0
- package/dist/storage/implementation/MongoCompactor.js.map +1 -0
- package/dist/storage/implementation/MongoIdSequence.d.ts +12 -0
- package/dist/storage/implementation/MongoIdSequence.js +21 -0
- package/dist/storage/implementation/MongoIdSequence.js.map +1 -0
- package/dist/storage/implementation/MongoPersistedSyncRules.d.ts +9 -0
- package/dist/storage/implementation/MongoPersistedSyncRules.js +9 -0
- package/dist/storage/implementation/MongoPersistedSyncRules.js.map +1 -0
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +20 -0
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +26 -0
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +1 -0
- package/dist/storage/implementation/MongoStorageProvider.d.ts +6 -0
- package/dist/storage/implementation/MongoStorageProvider.js +34 -0
- package/dist/storage/implementation/MongoStorageProvider.js.map +1 -0
- package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +36 -0
- package/dist/storage/implementation/MongoSyncBucketStorage.js +529 -0
- package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -0
- package/dist/storage/implementation/MongoSyncRulesLock.d.ts +16 -0
- package/dist/storage/implementation/MongoSyncRulesLock.js +65 -0
- package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -0
- package/dist/storage/implementation/MongoWriteCheckpointAPI.d.ts +20 -0
- package/dist/storage/implementation/MongoWriteCheckpointAPI.js +104 -0
- package/dist/storage/implementation/MongoWriteCheckpointAPI.js.map +1 -0
- package/dist/storage/implementation/OperationBatch.d.ts +34 -0
- package/dist/storage/implementation/OperationBatch.js +119 -0
- package/dist/storage/implementation/OperationBatch.js.map +1 -0
- package/dist/storage/implementation/PersistedBatch.d.ts +46 -0
- package/dist/storage/implementation/PersistedBatch.js +223 -0
- package/dist/storage/implementation/PersistedBatch.js.map +1 -0
- package/dist/storage/implementation/config.d.ts +19 -0
- package/dist/storage/implementation/config.js +26 -0
- package/dist/storage/implementation/config.js.map +1 -0
- package/dist/storage/implementation/db.d.ts +36 -0
- package/dist/storage/implementation/db.js +47 -0
- package/dist/storage/implementation/db.js.map +1 -0
- package/dist/storage/implementation/models.d.ts +139 -0
- package/dist/storage/implementation/models.js +2 -0
- package/dist/storage/implementation/models.js.map +1 -0
- package/dist/storage/implementation/util.d.ts +58 -0
- package/dist/storage/implementation/util.js +196 -0
- package/dist/storage/implementation/util.js.map +1 -0
- package/dist/storage/storage-index.d.ts +14 -0
- package/dist/storage/storage-index.js +15 -0
- package/dist/storage/storage-index.js.map +1 -0
- package/dist/types/types.d.ts +3 -0
- package/dist/types/types.js +4 -1
- package/dist/types/types.js.map +1 -1
- package/package.json +11 -8
- package/src/db/db-index.ts +1 -0
- package/src/db/mongo.ts +81 -0
- package/src/index.ts +4 -0
- package/src/locks/MonogLocks.ts +147 -0
- package/src/migrations/MonogMigrationAgent.ts +39 -0
- package/src/migrations/db/migrations/1684951997326-init.ts +39 -0
- package/src/migrations/db/migrations/1688556755264-initial-sync-rules.ts +5 -0
- package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +105 -0
- package/src/migrations/db/migrations/1711543888062-write-checkpoint-index.ts +38 -0
- package/src/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.ts +40 -0
- package/src/migrations/mongo-migration-store.ts +62 -0
- package/src/module/MongoModule.ts +18 -4
- package/src/replication/MongoManager.ts +6 -2
- package/src/storage/MongoBucketStorage.ts +530 -0
- package/src/storage/implementation/MongoBucketBatch.ts +893 -0
- package/src/storage/implementation/MongoCompactor.ts +392 -0
- package/src/storage/implementation/MongoIdSequence.ts +24 -0
- package/src/storage/implementation/MongoPersistedSyncRules.ts +16 -0
- package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +49 -0
- package/src/storage/implementation/MongoStorageProvider.ts +42 -0
- package/src/storage/implementation/MongoSyncBucketStorage.ts +612 -0
- package/src/storage/implementation/MongoSyncRulesLock.ts +88 -0
- package/src/storage/implementation/MongoWriteCheckpointAPI.ts +146 -0
- package/src/storage/implementation/OperationBatch.ts +130 -0
- package/src/storage/implementation/PersistedBatch.ts +283 -0
- package/src/storage/implementation/config.ts +40 -0
- package/src/storage/implementation/db.ts +88 -0
- package/src/storage/implementation/models.ts +160 -0
- package/src/storage/implementation/util.ts +209 -0
- package/src/storage/storage-index.ts +14 -0
- package/src/types/types.ts +8 -1
- package/test/src/__snapshots__/storage_sync.test.ts.snap +332 -0
- package/test/src/change_stream.test.ts +34 -33
- package/test/src/change_stream_utils.ts +6 -6
- package/test/src/env.ts +1 -0
- package/test/src/slow_tests.test.ts +4 -4
- package/test/src/storage.test.ts +7 -0
- package/test/src/storage_compacting.test.ts +6 -0
- package/test/src/storage_sync.test.ts +113 -0
- package/test/src/util.ts +20 -7
- package/test/tsconfig.json +4 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongo-migration-store.js","sourceRoot":"","sources":["../../src/migrations/mongo-migration-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,EAAM,EAA6B,EAAE;IAC7E,MAAM,UAAU,GAAG,EAAE,CAAC,UAAU,CAA4B,YAAY,CAAC,CAAC;IAE1E,OAAO;QACL,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;YAC/C,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO;YACT,CAAC;YAED,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,WAAW,CAAC;YAEtC;;;eAGG;YACH,IAAI,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;YAC9B,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;gBACvB,QAAQ,GAAI,KAAa,CAAC,OAAO,CAAC;YACpC,CAAC;YAED;;;eAGG;YACH,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACzC,IAAI,SAAS,EAAE,CAAC;gBACd,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YAC7C,CAAC;YAED,OAAO;gBACL,QAAQ;gBACR,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,EAAE;aACrB,CAAC;QACJ,CAAC;QAED,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,MAAM,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,EAAE,KAAK,EAAE,KAAgC,EAAE,EAAE;YAC/C,MAAM,UAAU,CAAC,UAAU,CACzB,EAAE,EACF;gBACE,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,GAAG,EAAE,KAAK,CAAC,GAAG;aACf,EACD;gBACE,MAAM,EAAE,IAAI;aACb,CACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { ConfigurationFileSyncRulesProvider, replication } from '@powersync/service-core';
|
|
2
2
|
import { MongoRouteAPIAdapter } from '../api/MongoRouteAPIAdapter.js';
|
|
3
|
+
import { MongoMigrationAgent } from '../migrations/MonogMigrationAgent.js';
|
|
4
|
+
import { ChangeStreamReplicator } from '../replication/ChangeStreamReplicator.js';
|
|
3
5
|
import { ConnectionManagerFactory } from '../replication/ConnectionManagerFactory.js';
|
|
4
6
|
import { MongoErrorRateLimiter } from '../replication/MongoErrorRateLimiter.js';
|
|
5
|
-
import { ChangeStreamReplicator } from '../replication/ChangeStreamReplicator.js';
|
|
6
|
-
import * as types from '../types/types.js';
|
|
7
7
|
import { MongoManager } from '../replication/MongoManager.js';
|
|
8
8
|
import { checkSourceConfiguration } from '../replication/replication-utils.js';
|
|
9
|
+
import { MongoStorageProvider } from '../storage/storage-index.js';
|
|
10
|
+
import * as types from '../types/types.js';
|
|
9
11
|
export class MongoModule extends replication.ReplicationModule {
|
|
10
12
|
constructor() {
|
|
11
13
|
super({
|
|
@@ -16,6 +18,10 @@ export class MongoModule extends replication.ReplicationModule {
|
|
|
16
18
|
}
|
|
17
19
|
async initialize(context) {
|
|
18
20
|
await super.initialize(context);
|
|
21
|
+
context.storageEngine.registerProvider(new MongoStorageProvider());
|
|
22
|
+
if (types.isMongoStorageConfig(context.configuration.storage)) {
|
|
23
|
+
context.migrations.registerMigrationAgent(new MongoMigrationAgent(this.resolveConfig(context.configuration.storage)));
|
|
24
|
+
}
|
|
19
25
|
}
|
|
20
26
|
createRouteAPIAdapter() {
|
|
21
27
|
return new MongoRouteAPIAdapter(this.resolveConfig(this.decodedConfig));
|
|
@@ -47,9 +53,14 @@ export class MongoModule extends replication.ReplicationModule {
|
|
|
47
53
|
async testConnection(config) {
|
|
48
54
|
this.decodeConfig(config);
|
|
49
55
|
const normalisedConfig = this.resolveConfig(this.decodedConfig);
|
|
50
|
-
const connectionManager = new MongoManager(normalisedConfig
|
|
56
|
+
const connectionManager = new MongoManager(normalisedConfig, {
|
|
57
|
+
// Use short timeouts for testing connections.
|
|
58
|
+
// Must be < 30s, to ensure we get a proper timeout error.
|
|
59
|
+
socketTimeoutMS: 5000,
|
|
60
|
+
serverSelectionTimeoutMS: 5000
|
|
61
|
+
});
|
|
51
62
|
try {
|
|
52
|
-
return checkSourceConfiguration(connectionManager);
|
|
63
|
+
return await checkSourceConfiguration(connectionManager);
|
|
53
64
|
}
|
|
54
65
|
finally {
|
|
55
66
|
await connectionManager.end();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MongoModule.js","sourceRoot":"","sources":["../../src/module/MongoModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,kCAAkC,EAAE,WAAW,EAA2B,MAAM,yBAAyB,CAAC;AACxH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"MongoModule.js","sourceRoot":"","sources":["../../src/module/MongoModule.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ export declare class MongoManager {
|
|
|
7
7
|
*/
|
|
8
8
|
readonly client: mongo.MongoClient;
|
|
9
9
|
readonly db: mongo.Db;
|
|
10
|
-
constructor(options: NormalizedMongoConnectionConfig);
|
|
10
|
+
constructor(options: NormalizedMongoConnectionConfig, overrides?: mongo.MongoClientOptions);
|
|
11
11
|
get connectionTag(): string;
|
|
12
12
|
end(): Promise<void>;
|
|
13
13
|
destroy(): Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as mongo from 'mongodb';
|
|
2
2
|
export class MongoManager {
|
|
3
|
-
constructor(options) {
|
|
3
|
+
constructor(options, overrides) {
|
|
4
4
|
this.options = options;
|
|
5
5
|
// The pool is lazy - no connections are opened until a query is performed.
|
|
6
6
|
this.client = new mongo.MongoClient(options.uri, {
|
|
@@ -19,7 +19,8 @@ export class MongoManager {
|
|
|
19
19
|
// 2. Processing too many queries in parallel can cause the process to run out of memory.
|
|
20
20
|
maxPoolSize: 8,
|
|
21
21
|
maxConnecting: 3,
|
|
22
|
-
maxIdleTimeMS: 60000
|
|
22
|
+
maxIdleTimeMS: 60000,
|
|
23
|
+
...overrides
|
|
23
24
|
});
|
|
24
25
|
this.db = this.client.db(options.database, {});
|
|
25
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MongoManager.js","sourceRoot":"","sources":["../../src/replication/MongoManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAGjC,MAAM,OAAO,YAAY;IAOvB,
|
|
1
|
+
{"version":3,"file":"MongoManager.js","sourceRoot":"","sources":["../../src/replication/MongoManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAGjC,MAAM,OAAO,YAAY;IAOvB,YACS,OAAwC,EAC/C,SAAoC;QAD7B,YAAO,GAAP,OAAO,CAAiC;QAG/C,2EAA2E;QAC3E,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE;YAC/C,IAAI,EAAE;gBACJ,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;aAC3B;YACD,iCAAiC;YACjC,gBAAgB,EAAE,IAAK;YACvB,0CAA0C;YAC1C,eAAe,EAAE,KAAM;YACvB,6CAA6C;YAC7C,wBAAwB,EAAE,KAAM;YAEhC,8BAA8B;YAC9B,2CAA2C;YAC3C,yFAAyF;YACzF,WAAW,EAAE,CAAC;YAEd,aAAa,EAAE,CAAC;YAChB,aAAa,EAAE,KAAM;YACrB,GAAG,SAAS;SACb,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,mBAAmB;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { storage } from '@powersync/service-core';
|
|
2
|
+
import { DisposableObserver } from '@powersync/lib-services-framework';
|
|
3
|
+
import { PowerSyncMongo } from './implementation/db.js';
|
|
4
|
+
import { MongoPersistedSyncRulesContent } from './implementation/MongoPersistedSyncRulesContent.js';
|
|
5
|
+
import { MongoSyncBucketStorage } from './implementation/MongoSyncBucketStorage.js';
|
|
6
|
+
export declare class MongoBucketStorage extends DisposableObserver<storage.BucketStorageFactoryListener> implements storage.BucketStorageFactory {
|
|
7
|
+
private readonly client;
|
|
8
|
+
private readonly session;
|
|
9
|
+
readonly slot_name_prefix: string;
|
|
10
|
+
private readonly storageCache;
|
|
11
|
+
readonly db: PowerSyncMongo;
|
|
12
|
+
constructor(db: PowerSyncMongo, options: {
|
|
13
|
+
slot_name_prefix: string;
|
|
14
|
+
});
|
|
15
|
+
getInstance(options: storage.PersistedSyncRulesContent): MongoSyncBucketStorage;
|
|
16
|
+
configureSyncRules(sync_rules: string, options?: {
|
|
17
|
+
lock?: boolean;
|
|
18
|
+
}): Promise<{
|
|
19
|
+
updated: boolean;
|
|
20
|
+
persisted_sync_rules?: undefined;
|
|
21
|
+
lock?: undefined;
|
|
22
|
+
} | {
|
|
23
|
+
updated: boolean;
|
|
24
|
+
persisted_sync_rules: MongoPersistedSyncRulesContent;
|
|
25
|
+
lock: import("./storage-index.js").MongoSyncRulesLock | undefined;
|
|
26
|
+
}>;
|
|
27
|
+
slotRemoved(slot_name: string): Promise<void>;
|
|
28
|
+
updateSyncRules(options: storage.UpdateSyncRulesOptions): Promise<MongoPersistedSyncRulesContent>;
|
|
29
|
+
getActiveSyncRulesContent(): Promise<MongoPersistedSyncRulesContent | null>;
|
|
30
|
+
getActiveSyncRules(options: storage.ParseSyncRulesOptions): Promise<storage.PersistedSyncRules | null>;
|
|
31
|
+
getNextSyncRulesContent(): Promise<MongoPersistedSyncRulesContent | null>;
|
|
32
|
+
getNextSyncRules(options: storage.ParseSyncRulesOptions): Promise<storage.PersistedSyncRules | null>;
|
|
33
|
+
getReplicatingSyncRules(): Promise<storage.PersistedSyncRulesContent[]>;
|
|
34
|
+
getStoppedSyncRules(): Promise<storage.PersistedSyncRulesContent[]>;
|
|
35
|
+
getActiveCheckpoint(): Promise<storage.ActiveCheckpoint>;
|
|
36
|
+
getStorageMetrics(): Promise<storage.StorageMetrics>;
|
|
37
|
+
getPowerSyncInstanceId(): Promise<string>;
|
|
38
|
+
private makeActiveCheckpoint;
|
|
39
|
+
/**
|
|
40
|
+
* Instance-wide watch on the latest available checkpoint (op_id + lsn).
|
|
41
|
+
*/
|
|
42
|
+
private watchActiveCheckpoint;
|
|
43
|
+
private readonly sharedIter;
|
|
44
|
+
/**
|
|
45
|
+
* User-specific watch on the latest checkpoint and/or write checkpoint.
|
|
46
|
+
*/
|
|
47
|
+
watchWriteCheckpoint(user_id: string, signal: AbortSignal): AsyncIterable<storage.WriteCheckpoint>;
|
|
48
|
+
}
|
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
import { SqlSyncRules } from '@powersync/service-sync-rules';
|
|
2
|
+
import { wrapWithAbort } from 'ix/asynciterable/operators/withabort.js';
|
|
3
|
+
import { LRUCache } from 'lru-cache/min';
|
|
4
|
+
import * as mongo from 'mongodb';
|
|
5
|
+
import * as timers from 'timers/promises';
|
|
6
|
+
import { storage, sync, utils } from '@powersync/service-core';
|
|
7
|
+
import { DisposableObserver, logger } from '@powersync/lib-services-framework';
|
|
8
|
+
import { v4 as uuid } from 'uuid';
|
|
9
|
+
import { createMongoLockManager } from '../locks/MonogLocks.js';
|
|
10
|
+
import { MongoPersistedSyncRulesContent } from './implementation/MongoPersistedSyncRulesContent.js';
|
|
11
|
+
import { MongoSyncBucketStorage } from './implementation/MongoSyncBucketStorage.js';
|
|
12
|
+
import { generateSlotName } from './implementation/util.js';
|
|
13
|
+
export class MongoBucketStorage extends DisposableObserver {
|
|
14
|
+
constructor(db, options) {
|
|
15
|
+
super();
|
|
16
|
+
this.storageCache = new LRUCache({
|
|
17
|
+
max: 3,
|
|
18
|
+
fetchMethod: async (id) => {
|
|
19
|
+
const doc2 = await this.db.sync_rules.findOne({
|
|
20
|
+
_id: id
|
|
21
|
+
}, { limit: 1 });
|
|
22
|
+
if (doc2 == null) {
|
|
23
|
+
// Deleted in the meantime?
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const rules = new MongoPersistedSyncRulesContent(this.db, doc2);
|
|
27
|
+
return this.getInstance(rules);
|
|
28
|
+
},
|
|
29
|
+
dispose: (storage) => {
|
|
30
|
+
storage[Symbol.dispose]();
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
// Nothing is done here until a subscriber starts to iterate
|
|
34
|
+
this.sharedIter = new sync.BroadcastIterable((signal) => {
|
|
35
|
+
return this.watchActiveCheckpoint(signal);
|
|
36
|
+
});
|
|
37
|
+
this.client = db.client;
|
|
38
|
+
this.db = db;
|
|
39
|
+
this.session = this.client.startSession();
|
|
40
|
+
this.slot_name_prefix = options.slot_name_prefix;
|
|
41
|
+
}
|
|
42
|
+
getInstance(options) {
|
|
43
|
+
let { id, slot_name } = options;
|
|
44
|
+
if (typeof id == 'bigint') {
|
|
45
|
+
id = Number(id);
|
|
46
|
+
}
|
|
47
|
+
const storage = new MongoSyncBucketStorage(this, id, options, slot_name);
|
|
48
|
+
this.iterateListeners((cb) => cb.syncStorageCreated?.(storage));
|
|
49
|
+
storage.registerListener({
|
|
50
|
+
batchStarted: (batch) => {
|
|
51
|
+
// This nested listener will be automatically disposed when the storage is disposed
|
|
52
|
+
batch.registerManagedListener(storage, {
|
|
53
|
+
replicationEvent: (payload) => this.iterateListeners((cb) => cb.replicationEvent?.(payload))
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return storage;
|
|
58
|
+
}
|
|
59
|
+
async configureSyncRules(sync_rules, options) {
|
|
60
|
+
const next = await this.getNextSyncRulesContent();
|
|
61
|
+
const active = await this.getActiveSyncRulesContent();
|
|
62
|
+
if (next?.sync_rules_content == sync_rules) {
|
|
63
|
+
logger.info('Sync rules from configuration unchanged');
|
|
64
|
+
return { updated: false };
|
|
65
|
+
}
|
|
66
|
+
else if (next == null && active?.sync_rules_content == sync_rules) {
|
|
67
|
+
logger.info('Sync rules from configuration unchanged');
|
|
68
|
+
return { updated: false };
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
logger.info('Sync rules updated from configuration');
|
|
72
|
+
const persisted_sync_rules = await this.updateSyncRules({
|
|
73
|
+
content: sync_rules,
|
|
74
|
+
lock: options?.lock
|
|
75
|
+
});
|
|
76
|
+
return { updated: true, persisted_sync_rules, lock: persisted_sync_rules.current_lock ?? undefined };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async slotRemoved(slot_name) {
|
|
80
|
+
const next = await this.getNextSyncRulesContent();
|
|
81
|
+
const active = await this.getActiveSyncRulesContent();
|
|
82
|
+
// In both the below cases, we create a new sync rules instance.
|
|
83
|
+
// The current one will continue erroring until the next one has finished processing.
|
|
84
|
+
// TODO: Update
|
|
85
|
+
if (next != null && next.slot_name == slot_name) {
|
|
86
|
+
// We need to redo the "next" sync rules
|
|
87
|
+
await this.updateSyncRules({
|
|
88
|
+
content: next.sync_rules_content
|
|
89
|
+
});
|
|
90
|
+
// Pro-actively stop replicating
|
|
91
|
+
await this.db.sync_rules.updateOne({
|
|
92
|
+
_id: next.id,
|
|
93
|
+
state: storage.SyncRuleState.PROCESSING
|
|
94
|
+
}, {
|
|
95
|
+
$set: {
|
|
96
|
+
state: storage.SyncRuleState.STOP
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
else if (next == null && active?.slot_name == slot_name) {
|
|
101
|
+
// Slot removed for "active" sync rules, while there is no "next" one.
|
|
102
|
+
await this.updateSyncRules({
|
|
103
|
+
content: active.sync_rules_content
|
|
104
|
+
});
|
|
105
|
+
// Pro-actively stop replicating
|
|
106
|
+
await this.db.sync_rules.updateOne({
|
|
107
|
+
_id: active.id,
|
|
108
|
+
state: storage.SyncRuleState.ACTIVE
|
|
109
|
+
}, {
|
|
110
|
+
$set: {
|
|
111
|
+
state: storage.SyncRuleState.STOP
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async updateSyncRules(options) {
|
|
117
|
+
// Parse and validate before applying any changes
|
|
118
|
+
const parsed = SqlSyncRules.fromYaml(options.content, {
|
|
119
|
+
// No schema-based validation at this point
|
|
120
|
+
schema: undefined,
|
|
121
|
+
defaultSchema: 'not_applicable', // Not needed for validation
|
|
122
|
+
throwOnError: true
|
|
123
|
+
});
|
|
124
|
+
let rules = undefined;
|
|
125
|
+
await this.session.withTransaction(async () => {
|
|
126
|
+
// Only have a single set of sync rules with PROCESSING.
|
|
127
|
+
await this.db.sync_rules.updateMany({
|
|
128
|
+
state: storage.SyncRuleState.PROCESSING
|
|
129
|
+
}, { $set: { state: storage.SyncRuleState.STOP } });
|
|
130
|
+
const id_doc = await this.db.op_id_sequence.findOneAndUpdate({
|
|
131
|
+
_id: 'sync_rules'
|
|
132
|
+
}, {
|
|
133
|
+
$inc: {
|
|
134
|
+
op_id: 1n
|
|
135
|
+
}
|
|
136
|
+
}, {
|
|
137
|
+
upsert: true,
|
|
138
|
+
returnDocument: 'after'
|
|
139
|
+
});
|
|
140
|
+
const id = Number(id_doc.op_id);
|
|
141
|
+
const slot_name = generateSlotName(this.slot_name_prefix, id);
|
|
142
|
+
const doc = {
|
|
143
|
+
_id: id,
|
|
144
|
+
content: options.content,
|
|
145
|
+
last_checkpoint: null,
|
|
146
|
+
last_checkpoint_lsn: null,
|
|
147
|
+
no_checkpoint_before: null,
|
|
148
|
+
keepalive_op: null,
|
|
149
|
+
snapshot_done: false,
|
|
150
|
+
state: storage.SyncRuleState.PROCESSING,
|
|
151
|
+
slot_name: slot_name,
|
|
152
|
+
last_checkpoint_ts: null,
|
|
153
|
+
last_fatal_error: null,
|
|
154
|
+
last_keepalive_ts: null
|
|
155
|
+
};
|
|
156
|
+
await this.db.sync_rules.insertOne(doc);
|
|
157
|
+
rules = new MongoPersistedSyncRulesContent(this.db, doc);
|
|
158
|
+
if (options.lock) {
|
|
159
|
+
const lock = await rules.lock();
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
return rules;
|
|
163
|
+
}
|
|
164
|
+
async getActiveSyncRulesContent() {
|
|
165
|
+
const doc = await this.db.sync_rules.findOne({
|
|
166
|
+
state: storage.SyncRuleState.ACTIVE
|
|
167
|
+
}, { sort: { _id: -1 }, limit: 1 });
|
|
168
|
+
if (doc == null) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
return new MongoPersistedSyncRulesContent(this.db, doc);
|
|
172
|
+
}
|
|
173
|
+
async getActiveSyncRules(options) {
|
|
174
|
+
const content = await this.getActiveSyncRulesContent();
|
|
175
|
+
return content?.parsed(options) ?? null;
|
|
176
|
+
}
|
|
177
|
+
async getNextSyncRulesContent() {
|
|
178
|
+
const doc = await this.db.sync_rules.findOne({
|
|
179
|
+
state: storage.SyncRuleState.PROCESSING
|
|
180
|
+
}, { sort: { _id: -1 }, limit: 1 });
|
|
181
|
+
if (doc == null) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
return new MongoPersistedSyncRulesContent(this.db, doc);
|
|
185
|
+
}
|
|
186
|
+
async getNextSyncRules(options) {
|
|
187
|
+
const content = await this.getNextSyncRulesContent();
|
|
188
|
+
return content?.parsed(options) ?? null;
|
|
189
|
+
}
|
|
190
|
+
async getReplicatingSyncRules() {
|
|
191
|
+
const docs = await this.db.sync_rules
|
|
192
|
+
.find({
|
|
193
|
+
$or: [{ state: storage.SyncRuleState.ACTIVE }, { state: storage.SyncRuleState.PROCESSING }]
|
|
194
|
+
})
|
|
195
|
+
.toArray();
|
|
196
|
+
return docs.map((doc) => {
|
|
197
|
+
return new MongoPersistedSyncRulesContent(this.db, doc);
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
async getStoppedSyncRules() {
|
|
201
|
+
const docs = await this.db.sync_rules
|
|
202
|
+
.find({
|
|
203
|
+
state: storage.SyncRuleState.STOP
|
|
204
|
+
})
|
|
205
|
+
.toArray();
|
|
206
|
+
return docs.map((doc) => {
|
|
207
|
+
return new MongoPersistedSyncRulesContent(this.db, doc);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
async getActiveCheckpoint() {
|
|
211
|
+
const doc = await this.db.sync_rules.findOne({
|
|
212
|
+
state: storage.SyncRuleState.ACTIVE
|
|
213
|
+
}, {
|
|
214
|
+
sort: { _id: -1 },
|
|
215
|
+
limit: 1,
|
|
216
|
+
projection: { _id: 1, last_checkpoint: 1, last_checkpoint_lsn: 1 }
|
|
217
|
+
});
|
|
218
|
+
return this.makeActiveCheckpoint(doc);
|
|
219
|
+
}
|
|
220
|
+
async getStorageMetrics() {
|
|
221
|
+
const ignoreNotExiting = (e) => {
|
|
222
|
+
if (e instanceof mongo.MongoServerError && e.codeName == 'NamespaceNotFound') {
|
|
223
|
+
// Collection doesn't exist - return 0
|
|
224
|
+
return [{ storageStats: { size: 0 } }];
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
return Promise.reject(e);
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
const active_sync_rules = await this.getActiveSyncRules({ defaultSchema: 'public' });
|
|
231
|
+
if (active_sync_rules == null) {
|
|
232
|
+
return {
|
|
233
|
+
operations_size_bytes: 0,
|
|
234
|
+
parameters_size_bytes: 0,
|
|
235
|
+
replication_size_bytes: 0
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
const operations_aggregate = await this.db.bucket_data
|
|
239
|
+
.aggregate([
|
|
240
|
+
{
|
|
241
|
+
$collStats: {
|
|
242
|
+
storageStats: {}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
])
|
|
246
|
+
.toArray()
|
|
247
|
+
.catch(ignoreNotExiting);
|
|
248
|
+
const parameters_aggregate = await this.db.bucket_parameters
|
|
249
|
+
.aggregate([
|
|
250
|
+
{
|
|
251
|
+
$collStats: {
|
|
252
|
+
storageStats: {}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
])
|
|
256
|
+
.toArray()
|
|
257
|
+
.catch(ignoreNotExiting);
|
|
258
|
+
const replication_aggregate = await this.db.current_data
|
|
259
|
+
.aggregate([
|
|
260
|
+
{
|
|
261
|
+
$collStats: {
|
|
262
|
+
storageStats: {}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
])
|
|
266
|
+
.toArray()
|
|
267
|
+
.catch(ignoreNotExiting);
|
|
268
|
+
return {
|
|
269
|
+
operations_size_bytes: operations_aggregate[0].storageStats.size,
|
|
270
|
+
parameters_size_bytes: parameters_aggregate[0].storageStats.size,
|
|
271
|
+
replication_size_bytes: replication_aggregate[0].storageStats.size
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
async getPowerSyncInstanceId() {
|
|
275
|
+
let instance = await this.db.instance.findOne({
|
|
276
|
+
_id: { $exists: true }
|
|
277
|
+
});
|
|
278
|
+
if (!instance) {
|
|
279
|
+
const manager = createMongoLockManager(this.db.locks, {
|
|
280
|
+
name: `instance-id-insertion-lock`
|
|
281
|
+
});
|
|
282
|
+
await manager.lock(async () => {
|
|
283
|
+
await this.db.instance.insertOne({
|
|
284
|
+
_id: uuid()
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
instance = await this.db.instance.findOne({
|
|
288
|
+
_id: { $exists: true }
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
return instance._id;
|
|
292
|
+
}
|
|
293
|
+
makeActiveCheckpoint(doc) {
|
|
294
|
+
return {
|
|
295
|
+
checkpoint: utils.timestampToOpId(doc?.last_checkpoint ?? 0n),
|
|
296
|
+
lsn: doc?.last_checkpoint_lsn ?? null,
|
|
297
|
+
hasSyncRules() {
|
|
298
|
+
return doc != null;
|
|
299
|
+
},
|
|
300
|
+
getBucketStorage: async () => {
|
|
301
|
+
if (doc == null) {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
return (await this.storageCache.fetch(doc._id)) ?? null;
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Instance-wide watch on the latest available checkpoint (op_id + lsn).
|
|
310
|
+
*/
|
|
311
|
+
async *watchActiveCheckpoint(signal) {
|
|
312
|
+
const pipeline = [
|
|
313
|
+
{
|
|
314
|
+
$match: {
|
|
315
|
+
'fullDocument.state': 'ACTIVE',
|
|
316
|
+
operationType: { $in: ['insert', 'update'] }
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
$project: {
|
|
321
|
+
operationType: 1,
|
|
322
|
+
'fullDocument._id': 1,
|
|
323
|
+
'fullDocument.last_checkpoint': 1,
|
|
324
|
+
'fullDocument.last_checkpoint_lsn': 1
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
];
|
|
328
|
+
// Use this form instead of (doc: SyncRuleDocument | null = null),
|
|
329
|
+
// otherwise we get weird "doc: never" issues.
|
|
330
|
+
let doc = null;
|
|
331
|
+
let clusterTime = null;
|
|
332
|
+
await this.client.withSession(async (session) => {
|
|
333
|
+
doc = await this.db.sync_rules.findOne({
|
|
334
|
+
state: storage.SyncRuleState.ACTIVE
|
|
335
|
+
}, {
|
|
336
|
+
session,
|
|
337
|
+
sort: { _id: -1 },
|
|
338
|
+
limit: 1,
|
|
339
|
+
projection: {
|
|
340
|
+
_id: 1,
|
|
341
|
+
last_checkpoint: 1,
|
|
342
|
+
last_checkpoint_lsn: 1
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
const time = session.clusterTime?.clusterTime ?? null;
|
|
346
|
+
clusterTime = time;
|
|
347
|
+
});
|
|
348
|
+
if (clusterTime == null) {
|
|
349
|
+
throw new Error('Could not get clusterTime');
|
|
350
|
+
}
|
|
351
|
+
if (signal.aborted) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (doc) {
|
|
355
|
+
yield this.makeActiveCheckpoint(doc);
|
|
356
|
+
}
|
|
357
|
+
const stream = this.db.sync_rules.watch(pipeline, {
|
|
358
|
+
fullDocument: 'updateLookup',
|
|
359
|
+
// Start at the cluster time where we got the initial doc, to make sure
|
|
360
|
+
// we don't skip any updates.
|
|
361
|
+
// This may result in the first operation being a duplicate, but we filter
|
|
362
|
+
// it out anyway.
|
|
363
|
+
startAtOperationTime: clusterTime
|
|
364
|
+
});
|
|
365
|
+
signal.addEventListener('abort', () => {
|
|
366
|
+
stream.close();
|
|
367
|
+
}, { once: true });
|
|
368
|
+
let lastOp = null;
|
|
369
|
+
for await (const update of stream.stream()) {
|
|
370
|
+
if (signal.aborted) {
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
if (update.operationType != 'insert' && update.operationType != 'update') {
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
const doc = update.fullDocument;
|
|
377
|
+
if (doc == null) {
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
const op = this.makeActiveCheckpoint(doc);
|
|
381
|
+
// Check for LSN / checkpoint changes - ignore other metadata changes
|
|
382
|
+
if (lastOp == null || op.lsn != lastOp.lsn || op.checkpoint != lastOp.checkpoint) {
|
|
383
|
+
lastOp = op;
|
|
384
|
+
yield op;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* User-specific watch on the latest checkpoint and/or write checkpoint.
|
|
390
|
+
*/
|
|
391
|
+
async *watchWriteCheckpoint(user_id, signal) {
|
|
392
|
+
let lastCheckpoint = null;
|
|
393
|
+
let lastWriteCheckpoint = null;
|
|
394
|
+
const iter = wrapWithAbort(this.sharedIter, signal);
|
|
395
|
+
for await (const cp of iter) {
|
|
396
|
+
const { checkpoint, lsn } = cp;
|
|
397
|
+
// lsn changes are not important by itself.
|
|
398
|
+
// What is important is:
|
|
399
|
+
// 1. checkpoint (op_id) changes.
|
|
400
|
+
// 2. write checkpoint changes for the specific user
|
|
401
|
+
const bucketStorage = await cp.getBucketStorage();
|
|
402
|
+
if (!bucketStorage) {
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
const lsnFilters = lsn ? { 1: lsn } : {};
|
|
406
|
+
const currentWriteCheckpoint = await bucketStorage.lastWriteCheckpoint({
|
|
407
|
+
user_id,
|
|
408
|
+
heads: {
|
|
409
|
+
...lsnFilters
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
if (currentWriteCheckpoint == lastWriteCheckpoint && checkpoint == lastCheckpoint) {
|
|
413
|
+
// No change - wait for next one
|
|
414
|
+
// In some cases, many LSNs may be produced in a short time.
|
|
415
|
+
// Add a delay to throttle the write checkpoint lookup a bit.
|
|
416
|
+
await timers.setTimeout(20 + 10 * Math.random());
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
lastWriteCheckpoint = currentWriteCheckpoint;
|
|
420
|
+
lastCheckpoint = checkpoint;
|
|
421
|
+
yield { base: cp, writeCheckpoint: currentWriteCheckpoint };
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
//# sourceMappingURL=MongoBucketStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MongoBucketStorage.js","sourceRoot":"","sources":["../../src/storage/MongoBucketStorage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { SqlEventDescriptor, SqlSyncRules } from '@powersync/service-sync-rules';
|
|
2
|
+
import * as mongo from 'mongodb';
|
|
3
|
+
import { DisposableObserver } from '@powersync/lib-services-framework';
|
|
4
|
+
import { storage } from '@powersync/service-core';
|
|
5
|
+
import { PowerSyncMongo } from './db.js';
|
|
6
|
+
import { CurrentBucket } from './models.js';
|
|
7
|
+
export interface MongoBucketBatchOptions {
|
|
8
|
+
db: PowerSyncMongo;
|
|
9
|
+
syncRules: SqlSyncRules;
|
|
10
|
+
groupId: number;
|
|
11
|
+
slotName: string;
|
|
12
|
+
lastCheckpointLsn: string | null;
|
|
13
|
+
keepaliveOp: string | null;
|
|
14
|
+
noCheckpointBeforeLsn: string;
|
|
15
|
+
storeCurrentData: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Set to true for initial replication.
|
|
18
|
+
*/
|
|
19
|
+
skipExistingRows: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare class MongoBucketBatch extends DisposableObserver<storage.BucketBatchStorageListener> implements storage.BucketStorageBatch {
|
|
22
|
+
private readonly client;
|
|
23
|
+
readonly db: PowerSyncMongo;
|
|
24
|
+
readonly session: mongo.ClientSession;
|
|
25
|
+
private readonly sync_rules;
|
|
26
|
+
private readonly group_id;
|
|
27
|
+
private readonly slot_name;
|
|
28
|
+
private readonly storeCurrentData;
|
|
29
|
+
private readonly skipExistingRows;
|
|
30
|
+
private batch;
|
|
31
|
+
private write_checkpoint_batch;
|
|
32
|
+
/**
|
|
33
|
+
* Last LSN received associated with a checkpoint.
|
|
34
|
+
*
|
|
35
|
+
* This could be either:
|
|
36
|
+
* 1. A commit LSN.
|
|
37
|
+
* 2. A keepalive message LSN.
|
|
38
|
+
*/
|
|
39
|
+
private last_checkpoint_lsn;
|
|
40
|
+
private no_checkpoint_before_lsn;
|
|
41
|
+
private persisted_op;
|
|
42
|
+
/**
|
|
43
|
+
* For tests only - not for persistence logic.
|
|
44
|
+
*/
|
|
45
|
+
last_flushed_op: bigint | null;
|
|
46
|
+
constructor(options: MongoBucketBatchOptions);
|
|
47
|
+
addCustomWriteCheckpoint(checkpoint: storage.BatchedCustomWriteCheckpointOptions): void;
|
|
48
|
+
get lastCheckpointLsn(): string | null;
|
|
49
|
+
flush(): Promise<storage.FlushedResult | null>;
|
|
50
|
+
private flushInner;
|
|
51
|
+
private replicateBatch;
|
|
52
|
+
private saveOperation;
|
|
53
|
+
private withTransaction;
|
|
54
|
+
private withReplicationTransaction;
|
|
55
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
56
|
+
private lastWaitingLogThottled;
|
|
57
|
+
commit(lsn: string): Promise<boolean>;
|
|
58
|
+
keepalive(lsn: string): Promise<boolean>;
|
|
59
|
+
save(record: storage.SaveOptions): Promise<storage.FlushedResult | null>;
|
|
60
|
+
/**
|
|
61
|
+
* Drop is equivalent to TRUNCATE, plus removing our record of the table.
|
|
62
|
+
*/
|
|
63
|
+
drop(sourceTables: storage.SourceTable[]): Promise<storage.FlushedResult | null>;
|
|
64
|
+
truncate(sourceTables: storage.SourceTable[]): Promise<storage.FlushedResult | null>;
|
|
65
|
+
truncateSingle(sourceTable: storage.SourceTable): Promise<bigint>;
|
|
66
|
+
markSnapshotDone(tables: storage.SourceTable[], no_checkpoint_before_lsn: string): Promise<storage.SourceTable[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Gets relevant {@link SqlEventDescriptor}s for the given {@link SourceTable}
|
|
69
|
+
*/
|
|
70
|
+
protected getTableEvents(table: storage.SourceTable): SqlEventDescriptor[];
|
|
71
|
+
}
|
|
72
|
+
export declare function currentBucketKey(b: CurrentBucket): string;
|