@powersync/service-core 0.0.0-dev-20240718134716 → 0.0.0-dev-20240918082156
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 +89 -6
- package/dist/api/RouteAPI.d.ts +68 -0
- package/dist/api/RouteAPI.js +2 -0
- package/dist/api/RouteAPI.js.map +1 -0
- package/dist/api/api-index.d.ts +1 -0
- package/dist/api/api-index.js +1 -0
- package/dist/api/api-index.js.map +1 -1
- package/dist/api/diagnostics.d.ts +4 -4
- package/dist/api/diagnostics.js +11 -65
- package/dist/api/diagnostics.js.map +1 -1
- package/dist/api/schema.d.ts +3 -5
- package/dist/api/schema.js +9 -79
- package/dist/api/schema.js.map +1 -1
- package/dist/auth/KeyStore.d.ts +7 -4
- package/dist/auth/KeyStore.js +1 -1
- package/dist/auth/KeyStore.js.map +1 -1
- package/dist/auth/auth-index.d.ts +0 -1
- package/dist/auth/auth-index.js +0 -1
- package/dist/auth/auth-index.js.map +1 -1
- package/dist/entry/cli-entry.js +4 -2
- package/dist/entry/cli-entry.js.map +1 -1
- package/dist/entry/commands/compact-action.d.ts +2 -0
- package/dist/entry/commands/compact-action.js +52 -0
- package/dist/entry/commands/compact-action.js.map +1 -0
- package/dist/entry/commands/migrate-action.js +4 -5
- package/dist/entry/commands/migrate-action.js.map +1 -1
- package/dist/entry/commands/teardown-action.js +2 -2
- package/dist/entry/commands/teardown-action.js.map +1 -1
- package/dist/entry/entry-index.d.ts +1 -0
- package/dist/entry/entry-index.js +1 -0
- package/dist/entry/entry-index.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/metrics/Metrics.d.ts +6 -5
- package/dist/metrics/Metrics.js +53 -10
- package/dist/metrics/Metrics.js.map +1 -1
- package/dist/migrations/db/migrations/1684951997326-init.d.ts +2 -2
- package/dist/migrations/db/migrations/1684951997326-init.js +4 -2
- package/dist/migrations/db/migrations/1684951997326-init.js.map +1 -1
- package/dist/migrations/db/migrations/1702295701188-sync-rule-state.d.ts +2 -2
- package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js +4 -2
- package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js.map +1 -1
- package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.d.ts +2 -2
- package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js +4 -2
- package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js.map +1 -1
- package/dist/migrations/migrations.d.ts +8 -0
- package/dist/migrations/migrations.js +19 -7
- package/dist/migrations/migrations.js.map +1 -1
- package/dist/modules/AbstractModule.d.ts +26 -0
- package/dist/modules/AbstractModule.js +11 -0
- package/dist/modules/AbstractModule.js.map +1 -0
- package/dist/modules/ModuleManager.d.ts +11 -0
- package/dist/modules/ModuleManager.js +32 -0
- package/dist/modules/ModuleManager.js.map +1 -0
- package/dist/modules/modules-index.d.ts +2 -0
- package/dist/modules/modules-index.js +3 -0
- package/dist/modules/modules-index.js.map +1 -0
- package/dist/replication/AbstractReplicationJob.d.ts +38 -0
- package/dist/replication/AbstractReplicationJob.js +51 -0
- package/dist/replication/AbstractReplicationJob.js.map +1 -0
- package/dist/replication/AbstractReplicator.d.ts +53 -0
- package/dist/replication/AbstractReplicator.js +187 -0
- package/dist/replication/AbstractReplicator.js.map +1 -0
- package/dist/replication/ErrorRateLimiter.d.ts +0 -9
- package/dist/replication/ErrorRateLimiter.js +1 -42
- package/dist/replication/ErrorRateLimiter.js.map +1 -1
- package/dist/replication/ReplicationEngine.d.ts +18 -0
- package/dist/replication/ReplicationEngine.js +41 -0
- package/dist/replication/ReplicationEngine.js.map +1 -0
- package/dist/replication/ReplicationModule.d.ts +39 -0
- package/dist/replication/ReplicationModule.js +65 -0
- package/dist/replication/ReplicationModule.js.map +1 -0
- package/dist/replication/replication-index.d.ts +4 -6
- package/dist/replication/replication-index.js +4 -6
- package/dist/replication/replication-index.js.map +1 -1
- package/dist/routes/RouterEngine.d.ts +42 -0
- package/dist/routes/RouterEngine.js +80 -0
- package/dist/routes/RouterEngine.js.map +1 -0
- package/dist/routes/auth.d.ts +2 -2
- package/dist/routes/auth.js +11 -11
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/configure-fastify.d.ts +737 -0
- package/dist/routes/configure-fastify.js +57 -0
- package/dist/routes/configure-fastify.js.map +1 -0
- package/dist/routes/configure-rsocket.d.ts +13 -0
- package/dist/routes/configure-rsocket.js +47 -0
- package/dist/routes/configure-rsocket.js.map +1 -0
- package/dist/routes/endpoints/admin.d.ts +0 -34
- package/dist/routes/endpoints/admin.js +48 -89
- package/dist/routes/endpoints/admin.js.map +1 -1
- package/dist/routes/endpoints/checkpointing.d.ts +56 -16
- package/dist/routes/endpoints/checkpointing.js +33 -12
- package/dist/routes/endpoints/checkpointing.js.map +1 -1
- package/dist/routes/endpoints/route-endpoints-index.d.ts +0 -1
- package/dist/routes/endpoints/route-endpoints-index.js +0 -1
- package/dist/routes/endpoints/route-endpoints-index.js.map +1 -1
- package/dist/routes/endpoints/socket-route.js +46 -39
- package/dist/routes/endpoints/socket-route.js.map +1 -1
- package/dist/routes/endpoints/sync-rules.d.ts +1 -1
- package/dist/routes/endpoints/sync-rules.js +32 -23
- package/dist/routes/endpoints/sync-rules.js.map +1 -1
- package/dist/routes/endpoints/sync-stream.d.ts +10 -0
- package/dist/routes/endpoints/sync-stream.js +17 -13
- package/dist/routes/endpoints/sync-stream.js.map +1 -1
- package/dist/routes/route-register.d.ts +1 -1
- package/dist/routes/route-register.js +1 -1
- package/dist/routes/route-register.js.map +1 -1
- package/dist/routes/router-socket.d.ts +5 -4
- package/dist/routes/router-socket.js +2 -1
- package/dist/routes/router-socket.js.map +1 -1
- package/dist/routes/router.d.ts +7 -2
- package/dist/routes/router.js.map +1 -1
- package/dist/routes/routes-index.d.ts +3 -0
- package/dist/routes/routes-index.js +3 -0
- package/dist/routes/routes-index.js.map +1 -1
- package/dist/runner/teardown.js +47 -76
- package/dist/runner/teardown.js.map +1 -1
- package/dist/storage/BucketStorage.d.ts +61 -20
- package/dist/storage/BucketStorage.js +0 -10
- package/dist/storage/BucketStorage.js.map +1 -1
- package/dist/storage/MongoBucketStorage.d.ts +4 -4
- package/dist/storage/MongoBucketStorage.js +19 -24
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/SourceEntity.d.ts +20 -0
- package/dist/storage/SourceEntity.js +2 -0
- package/dist/storage/SourceEntity.js.map +1 -0
- package/dist/storage/SourceTable.d.ts +4 -5
- package/dist/storage/SourceTable.js +3 -4
- package/dist/storage/SourceTable.js.map +1 -1
- package/dist/storage/StorageEngine.d.ts +24 -0
- package/dist/storage/StorageEngine.js +43 -0
- package/dist/storage/StorageEngine.js.map +1 -0
- package/dist/storage/StorageProvider.d.ts +21 -0
- package/dist/storage/StorageProvider.js +2 -0
- package/dist/storage/StorageProvider.js.map +1 -0
- package/dist/storage/mongo/MongoBucketBatch.d.ts +1 -1
- package/dist/storage/mongo/MongoBucketBatch.js +6 -7
- package/dist/storage/mongo/MongoBucketBatch.js.map +1 -1
- package/dist/storage/mongo/MongoCompactor.d.ts +40 -0
- package/dist/storage/mongo/MongoCompactor.js +293 -0
- package/dist/storage/mongo/MongoCompactor.js.map +1 -0
- package/dist/storage/mongo/MongoPersistedSyncRulesContent.d.ts +2 -2
- package/dist/storage/mongo/MongoPersistedSyncRulesContent.js +2 -2
- package/dist/storage/mongo/MongoPersistedSyncRulesContent.js.map +1 -1
- package/dist/storage/mongo/MongoStorageProvider.d.ts +5 -0
- package/dist/storage/mongo/MongoStorageProvider.js +26 -0
- package/dist/storage/mongo/MongoStorageProvider.js.map +1 -0
- package/dist/storage/mongo/MongoSyncBucketStorage.d.ts +9 -7
- package/dist/storage/mongo/MongoSyncBucketStorage.js +43 -28
- package/dist/storage/mongo/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/mongo/MongoSyncRulesLock.js +1 -1
- package/dist/storage/mongo/MongoSyncRulesLock.js.map +1 -1
- package/dist/storage/mongo/OperationBatch.d.ts +7 -3
- package/dist/storage/mongo/OperationBatch.js +16 -7
- package/dist/storage/mongo/OperationBatch.js.map +1 -1
- package/dist/storage/mongo/PersistedBatch.d.ts +3 -3
- package/dist/storage/mongo/PersistedBatch.js +2 -2
- package/dist/storage/mongo/PersistedBatch.js.map +1 -1
- package/dist/storage/mongo/models.d.ts +17 -7
- package/dist/storage/mongo/models.js.map +1 -1
- package/dist/storage/mongo/util.d.ts +14 -0
- package/dist/storage/mongo/util.js +70 -0
- package/dist/storage/mongo/util.js.map +1 -1
- package/dist/storage/storage-index.d.ts +5 -2
- package/dist/storage/storage-index.js +5 -2
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/sync/RequestTracker.js +2 -3
- package/dist/sync/RequestTracker.js.map +1 -1
- package/dist/sync/sync-index.d.ts +1 -0
- package/dist/sync/sync-index.js +1 -0
- package/dist/sync/sync-index.js.map +1 -1
- package/dist/sync/sync.d.ts +2 -1
- package/dist/sync/sync.js +56 -17
- package/dist/sync/sync.js.map +1 -1
- package/dist/system/ServiceContext.d.ts +37 -0
- package/dist/system/ServiceContext.js +48 -0
- package/dist/system/ServiceContext.js.map +1 -0
- package/dist/system/system-index.d.ts +1 -1
- package/dist/system/system-index.js +1 -1
- package/dist/system/system-index.js.map +1 -1
- package/dist/util/config/collectors/config-collector.d.ts +12 -0
- package/dist/util/config/collectors/config-collector.js +43 -0
- package/dist/util/config/collectors/config-collector.js.map +1 -1
- package/dist/util/config/compound-config-collector.d.ts +10 -29
- package/dist/util/config/compound-config-collector.js +28 -84
- package/dist/util/config/compound-config-collector.js.map +1 -1
- package/dist/util/config/sync-rules/sync-rules-provider.d.ts +9 -0
- package/dist/util/config/sync-rules/sync-rules-provider.js +15 -0
- package/dist/util/config/sync-rules/sync-rules-provider.js.map +1 -0
- package/dist/util/config/types.d.ts +6 -4
- package/dist/util/config/types.js.map +1 -1
- package/dist/util/config.d.ts +3 -4
- package/dist/util/config.js +5 -20
- package/dist/util/config.js.map +1 -1
- package/dist/util/protocol-types.d.ts +4 -0
- package/dist/util/protocol-types.js +5 -1
- package/dist/util/protocol-types.js.map +1 -1
- package/dist/util/util-index.d.ts +3 -6
- package/dist/util/util-index.js +3 -6
- package/dist/util/util-index.js.map +1 -1
- package/dist/util/utils.d.ts +10 -6
- package/dist/util/utils.js +45 -25
- package/dist/util/utils.js.map +1 -1
- package/package.json +7 -7
- package/src/api/RouteAPI.ts +78 -0
- package/src/api/api-index.ts +1 -0
- package/src/api/diagnostics.ts +16 -71
- package/src/api/schema.ts +13 -89
- package/src/auth/KeyStore.ts +9 -6
- package/src/auth/auth-index.ts +0 -1
- package/src/entry/cli-entry.ts +4 -2
- package/src/entry/commands/compact-action.ts +57 -0
- package/src/entry/commands/migrate-action.ts +5 -8
- package/src/entry/commands/teardown-action.ts +2 -2
- package/src/entry/entry-index.ts +1 -0
- package/src/index.ts +5 -2
- package/src/metrics/Metrics.ts +70 -15
- package/src/migrations/db/migrations/1684951997326-init.ts +9 -4
- package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +7 -4
- package/src/migrations/db/migrations/1711543888062-write-checkpoint-index.ts +6 -4
- package/src/migrations/migrations.ts +24 -8
- package/src/modules/AbstractModule.ts +37 -0
- package/src/modules/ModuleManager.ts +34 -0
- package/src/modules/modules-index.ts +2 -0
- package/src/replication/AbstractReplicationJob.ts +79 -0
- package/src/replication/AbstractReplicator.ts +227 -0
- package/src/replication/ErrorRateLimiter.ts +0 -44
- package/src/replication/ReplicationEngine.ts +43 -0
- package/src/replication/ReplicationModule.ts +101 -0
- package/src/replication/replication-index.ts +4 -6
- package/src/routes/RouterEngine.ts +120 -0
- package/src/routes/auth.ts +21 -12
- package/src/routes/configure-fastify.ts +101 -0
- package/src/routes/configure-rsocket.ts +60 -0
- package/src/routes/endpoints/admin.ts +74 -100
- package/src/routes/endpoints/checkpointing.ts +46 -12
- package/src/routes/endpoints/route-endpoints-index.ts +0 -1
- package/src/routes/endpoints/socket-route.ts +50 -42
- package/src/routes/endpoints/sync-rules.ts +41 -25
- package/src/routes/endpoints/sync-stream.ts +17 -13
- package/src/routes/route-register.ts +2 -2
- package/src/routes/router-socket.ts +6 -5
- package/src/routes/router.ts +7 -2
- package/src/routes/routes-index.ts +3 -0
- package/src/runner/teardown.ts +50 -88
- package/src/storage/BucketStorage.ts +74 -26
- package/src/storage/MongoBucketStorage.ts +23 -26
- package/src/storage/SourceEntity.ts +22 -0
- package/src/storage/SourceTable.ts +4 -6
- package/src/storage/StorageEngine.ts +55 -0
- package/src/storage/StorageProvider.ts +27 -0
- package/src/storage/mongo/MongoBucketBatch.ts +8 -8
- package/src/storage/mongo/MongoCompactor.ts +372 -0
- package/src/storage/mongo/MongoPersistedSyncRulesContent.ts +3 -3
- package/src/storage/mongo/MongoStorageProvider.ts +31 -0
- package/src/storage/mongo/MongoSyncBucketStorage.ts +64 -34
- package/src/storage/mongo/MongoSyncRulesLock.ts +1 -1
- package/src/storage/mongo/OperationBatch.ts +18 -11
- package/src/storage/mongo/PersistedBatch.ts +6 -5
- package/src/storage/mongo/models.ts +17 -7
- package/src/storage/mongo/util.ts +71 -1
- package/src/storage/storage-index.ts +5 -2
- package/src/sync/RequestTracker.ts +3 -3
- package/src/sync/sync-index.ts +1 -0
- package/src/sync/sync.ts +66 -17
- package/src/system/ServiceContext.ts +68 -0
- package/src/system/system-index.ts +1 -1
- package/src/util/config/collectors/config-collector.ts +48 -0
- package/src/util/config/compound-config-collector.ts +45 -110
- package/src/util/config/sync-rules/sync-rules-provider.ts +18 -0
- package/src/util/config/types.ts +6 -5
- package/src/util/config.ts +6 -23
- package/src/util/protocol-types.ts +6 -1
- package/src/util/util-index.ts +3 -6
- package/src/util/utils.ts +55 -39
- package/test/src/__snapshots__/sync.test.ts.snap +90 -5
- package/test/src/auth.test.ts +7 -7
- package/test/src/broadcast_iterable.test.ts +1 -1
- package/test/src/bucket_validation.test.ts +142 -0
- package/test/src/bucket_validation.ts +116 -0
- package/test/src/checksum_cache.test.ts +3 -3
- package/test/src/compacting.test.ts +216 -0
- package/test/src/data_storage.test.ts +275 -204
- package/test/src/env.ts +1 -3
- package/test/src/merge_iterable.test.ts +1 -6
- package/test/src/setup.ts +1 -1
- package/test/src/stream_utils.ts +42 -0
- package/test/src/sync.test.ts +209 -48
- package/test/src/util.ts +110 -55
- package/test/tsconfig.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/auth/SupabaseKeyCollector.d.ts +0 -22
- package/dist/auth/SupabaseKeyCollector.js +0 -61
- package/dist/auth/SupabaseKeyCollector.js.map +0 -1
- package/dist/replication/PgRelation.d.ts +0 -16
- package/dist/replication/PgRelation.js +0 -26
- package/dist/replication/PgRelation.js.map +0 -1
- package/dist/replication/WalConnection.d.ts +0 -34
- package/dist/replication/WalConnection.js +0 -190
- package/dist/replication/WalConnection.js.map +0 -1
- package/dist/replication/WalStream.d.ts +0 -57
- package/dist/replication/WalStream.js +0 -517
- package/dist/replication/WalStream.js.map +0 -1
- package/dist/replication/WalStreamManager.d.ts +0 -30
- package/dist/replication/WalStreamManager.js +0 -198
- package/dist/replication/WalStreamManager.js.map +0 -1
- package/dist/replication/WalStreamRunner.d.ts +0 -38
- package/dist/replication/WalStreamRunner.js +0 -155
- package/dist/replication/WalStreamRunner.js.map +0 -1
- package/dist/replication/util.d.ts +0 -9
- package/dist/replication/util.js +0 -62
- package/dist/replication/util.js.map +0 -1
- package/dist/routes/endpoints/dev.d.ts +0 -312
- package/dist/routes/endpoints/dev.js +0 -172
- package/dist/routes/endpoints/dev.js.map +0 -1
- package/dist/system/CorePowerSyncSystem.d.ts +0 -23
- package/dist/system/CorePowerSyncSystem.js +0 -52
- package/dist/system/CorePowerSyncSystem.js.map +0 -1
- package/dist/util/PgManager.d.ts +0 -24
- package/dist/util/PgManager.js +0 -55
- package/dist/util/PgManager.js.map +0 -1
- package/dist/util/migration_lib.d.ts +0 -11
- package/dist/util/migration_lib.js +0 -64
- package/dist/util/migration_lib.js.map +0 -1
- package/dist/util/pgwire_utils.d.ts +0 -24
- package/dist/util/pgwire_utils.js +0 -117
- package/dist/util/pgwire_utils.js.map +0 -1
- package/dist/util/populate_test_data.d.ts +0 -8
- package/dist/util/populate_test_data.js +0 -65
- package/dist/util/populate_test_data.js.map +0 -1
- package/src/auth/SupabaseKeyCollector.ts +0 -67
- package/src/replication/PgRelation.ts +0 -42
- package/src/replication/WalConnection.ts +0 -227
- package/src/replication/WalStream.ts +0 -628
- package/src/replication/WalStreamManager.ts +0 -213
- package/src/replication/WalStreamRunner.ts +0 -180
- package/src/replication/util.ts +0 -76
- package/src/routes/endpoints/dev.ts +0 -199
- package/src/system/CorePowerSyncSystem.ts +0 -64
- package/src/util/PgManager.ts +0 -64
- package/src/util/migration_lib.ts +0 -79
- package/src/util/pgwire_utils.ts +0 -139
- package/src/util/populate_test_data.ts +0 -78
- package/test/src/__snapshots__/pg_test.test.ts.snap +0 -256
- package/test/src/large_batch.test.ts +0 -194
- package/test/src/pg_test.test.ts +0 -450
- package/test/src/schema_changes.test.ts +0 -545
- package/test/src/slow_tests.test.ts +0 -296
- package/test/src/validation.test.ts +0 -63
- package/test/src/wal_stream.test.ts +0 -314
- package/test/src/wal_stream_utils.ts +0 -147
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import * as storage from '../storage/storage-index.js';
|
|
3
|
+
import { ErrorRateLimiter } from './ErrorRateLimiter.js';
|
|
4
|
+
import winston from 'winston';
|
|
5
|
+
export interface AbstractReplicationJobOptions {
|
|
6
|
+
id: string;
|
|
7
|
+
storage: storage.SyncRulesBucketStorage;
|
|
8
|
+
lock: storage.ReplicationLock;
|
|
9
|
+
rateLimiter: ErrorRateLimiter;
|
|
10
|
+
}
|
|
11
|
+
export declare abstract class AbstractReplicationJob {
|
|
12
|
+
protected options: AbstractReplicationJobOptions;
|
|
13
|
+
protected logger: winston.Logger;
|
|
14
|
+
protected abortController: AbortController;
|
|
15
|
+
protected isReplicatingPromise: Promise<void> | null;
|
|
16
|
+
protected constructor(options: AbstractReplicationJobOptions);
|
|
17
|
+
/**
|
|
18
|
+
* Copy the initial data set from the data source if required and then keep it in sync.
|
|
19
|
+
*/
|
|
20
|
+
abstract replicate(): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Ensure the connection to the data source remains active
|
|
23
|
+
*/
|
|
24
|
+
abstract keepAlive(): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Start the replication process
|
|
27
|
+
*/
|
|
28
|
+
start(): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Safely stop the replication process
|
|
31
|
+
*/
|
|
32
|
+
stop(): Promise<void>;
|
|
33
|
+
get id(): string;
|
|
34
|
+
get storage(): storage.SyncRulesBucketStorage;
|
|
35
|
+
protected get lock(): storage.ReplicationLock;
|
|
36
|
+
protected get rateLimiter(): ErrorRateLimiter;
|
|
37
|
+
get isStopped(): boolean;
|
|
38
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { container, logger } from '@powersync/lib-services-framework';
|
|
2
|
+
export class AbstractReplicationJob {
|
|
3
|
+
constructor(options) {
|
|
4
|
+
this.options = options;
|
|
5
|
+
this.abortController = new AbortController();
|
|
6
|
+
this.isReplicatingPromise = null;
|
|
7
|
+
this.logger = logger.child({ name: `ReplicationJob: ${options.id}` });
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Start the replication process
|
|
11
|
+
*/
|
|
12
|
+
async start() {
|
|
13
|
+
this.isReplicatingPromise = this.replicate()
|
|
14
|
+
.catch((ex) => {
|
|
15
|
+
container.reporter.captureException(ex, {
|
|
16
|
+
metadata: {
|
|
17
|
+
replicator: this.id
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
this.logger.error(`Replication failed.`, ex);
|
|
21
|
+
})
|
|
22
|
+
.finally(async () => {
|
|
23
|
+
this.abortController.abort();
|
|
24
|
+
await this.options.lock.release();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Safely stop the replication process
|
|
29
|
+
*/
|
|
30
|
+
async stop() {
|
|
31
|
+
this.logger.info(`Stopping ${this.id} replication job for sync rule iteration: ${this.storage.group_id}`);
|
|
32
|
+
this.abortController.abort();
|
|
33
|
+
await this.isReplicatingPromise;
|
|
34
|
+
}
|
|
35
|
+
get id() {
|
|
36
|
+
return this.options.id;
|
|
37
|
+
}
|
|
38
|
+
get storage() {
|
|
39
|
+
return this.options.storage;
|
|
40
|
+
}
|
|
41
|
+
get lock() {
|
|
42
|
+
return this.options.lock;
|
|
43
|
+
}
|
|
44
|
+
get rateLimiter() {
|
|
45
|
+
return this.options.rateLimiter;
|
|
46
|
+
}
|
|
47
|
+
get isStopped() {
|
|
48
|
+
return this.abortController.signal.aborted;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=AbstractReplicationJob.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbstractReplicationJob.js","sourceRoot":"","sources":["../../src/replication/AbstractReplicationJob.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAUtE,MAAM,OAAgB,sBAAsB;IAK1C,YAAgC,OAAsC;QAAtC,YAAO,GAAP,OAAO,CAA+B;QAH5D,oBAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QACxC,yBAAoB,GAAyB,IAAI,CAAC;QAG1D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,mBAAmB,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACxE,CAAC;IAYD;;OAEG;IACI,KAAK,CAAC,KAAK;QAChB,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,SAAS,EAAE;aACzC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE;YACZ,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAAE;gBACtC,QAAQ,EAAE;oBACR,UAAU,EAAE,IAAI,CAAC,EAAE;iBACpB;aACF,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC;aACD,OAAO,CAAC,KAAK,IAAI,EAAE;YAClB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YAC7B,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACpC,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI;QACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,EAAE,6CAA6C,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC1G,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC7B,MAAM,IAAI,CAAC,oBAAoB,CAAC;IAClC,CAAC;IAED,IAAW,EAAE;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IACzB,CAAC;IAED,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;IAC9B,CAAC;IAED,IAAc,IAAI;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,IAAc,WAAW;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;IAClC,CAAC;IAED,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC;IAC7C,CAAC;CACF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as storage from '../storage/storage-index.js';
|
|
2
|
+
import { SyncRulesProvider } from '../util/config/sync-rules/sync-rules-provider.js';
|
|
3
|
+
import winston from 'winston';
|
|
4
|
+
import { AbstractReplicationJob } from './AbstractReplicationJob.js';
|
|
5
|
+
import { StorageEngine } from '../storage/storage-index.js';
|
|
6
|
+
import { ErrorRateLimiter } from './ErrorRateLimiter.js';
|
|
7
|
+
export interface CreateJobOptions {
|
|
8
|
+
lock: storage.ReplicationLock;
|
|
9
|
+
storage: storage.SyncRulesBucketStorage;
|
|
10
|
+
}
|
|
11
|
+
export interface AbstractReplicatorOptions {
|
|
12
|
+
id: string;
|
|
13
|
+
storageEngine: StorageEngine;
|
|
14
|
+
syncRuleProvider: SyncRulesProvider;
|
|
15
|
+
/**
|
|
16
|
+
* This limits the effect of retries when there is a persistent issue.
|
|
17
|
+
*/
|
|
18
|
+
rateLimiter: ErrorRateLimiter;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A replicator manages the mechanics for replicating data from a data source to a storage bucket.
|
|
22
|
+
* This includes copying across the original data set and then keeping it in sync with the data source using Replication Jobs.
|
|
23
|
+
* It also handles any changes to the sync rules.
|
|
24
|
+
*/
|
|
25
|
+
export declare abstract class AbstractReplicator<T extends AbstractReplicationJob = AbstractReplicationJob> {
|
|
26
|
+
private options;
|
|
27
|
+
protected logger: winston.Logger;
|
|
28
|
+
/**
|
|
29
|
+
* Map of replication jobs by sync rule id. Usually there is only one running job, but there could be two when
|
|
30
|
+
* transitioning to a new set of sync rules.
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
private replicationJobs;
|
|
34
|
+
private stopped;
|
|
35
|
+
private lastPing;
|
|
36
|
+
protected constructor(options: AbstractReplicatorOptions);
|
|
37
|
+
abstract createJob(options: CreateJobOptions): T;
|
|
38
|
+
/**
|
|
39
|
+
* Clean up any configuration or state for the specified sync rule on the datasource.
|
|
40
|
+
* Should be a no-op if the configuration has already been cleared
|
|
41
|
+
*/
|
|
42
|
+
abstract cleanUp(syncRuleStorage: storage.SyncRulesBucketStorage): Promise<void>;
|
|
43
|
+
get id(): string;
|
|
44
|
+
protected get storage(): storage.BucketStorageFactory;
|
|
45
|
+
protected get syncRuleProvider(): SyncRulesProvider;
|
|
46
|
+
protected get rateLimiter(): ErrorRateLimiter;
|
|
47
|
+
start(): Promise<void>;
|
|
48
|
+
stop(): Promise<void>;
|
|
49
|
+
private runLoop;
|
|
50
|
+
private refresh;
|
|
51
|
+
protected createJobId(syncRuleId: number): string;
|
|
52
|
+
protected terminateSyncRules(syncRuleStorage: storage.SyncRulesBucketStorage): Promise<void>;
|
|
53
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { hrtime } from 'node:process';
|
|
2
|
+
import { container, logger } from '@powersync/lib-services-framework';
|
|
3
|
+
// 5 minutes
|
|
4
|
+
const PING_INTERVAL = 1000000000n * 300n;
|
|
5
|
+
/**
|
|
6
|
+
* A replicator manages the mechanics for replicating data from a data source to a storage bucket.
|
|
7
|
+
* This includes copying across the original data set and then keeping it in sync with the data source using Replication Jobs.
|
|
8
|
+
* It also handles any changes to the sync rules.
|
|
9
|
+
*/
|
|
10
|
+
export class AbstractReplicator {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.options = options;
|
|
13
|
+
/**
|
|
14
|
+
* Map of replication jobs by sync rule id. Usually there is only one running job, but there could be two when
|
|
15
|
+
* transitioning to a new set of sync rules.
|
|
16
|
+
* @private
|
|
17
|
+
*/
|
|
18
|
+
this.replicationJobs = new Map();
|
|
19
|
+
this.stopped = false;
|
|
20
|
+
// First ping is only after 5 minutes, not when starting
|
|
21
|
+
this.lastPing = hrtime.bigint();
|
|
22
|
+
this.logger = logger.child({ name: `Replicator:${options.id}` });
|
|
23
|
+
}
|
|
24
|
+
get id() {
|
|
25
|
+
return this.options.id;
|
|
26
|
+
}
|
|
27
|
+
get storage() {
|
|
28
|
+
return this.options.storageEngine.activeBucketStorage;
|
|
29
|
+
}
|
|
30
|
+
get syncRuleProvider() {
|
|
31
|
+
return this.options.syncRuleProvider;
|
|
32
|
+
}
|
|
33
|
+
get rateLimiter() {
|
|
34
|
+
return this.options.rateLimiter;
|
|
35
|
+
}
|
|
36
|
+
async start() {
|
|
37
|
+
this.runLoop().catch((e) => {
|
|
38
|
+
this.logger.error('Data source fatal replication error', e);
|
|
39
|
+
container.reporter.captureException(e);
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}, 1000);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async stop() {
|
|
46
|
+
this.stopped = true;
|
|
47
|
+
let promises = [];
|
|
48
|
+
for (const job of this.replicationJobs.values()) {
|
|
49
|
+
promises.push(job.stop());
|
|
50
|
+
}
|
|
51
|
+
await Promise.all(promises);
|
|
52
|
+
}
|
|
53
|
+
async runLoop() {
|
|
54
|
+
const syncRules = await this.syncRuleProvider.get();
|
|
55
|
+
let configuredLock = undefined;
|
|
56
|
+
if (syncRules != null) {
|
|
57
|
+
this.logger.info('Loaded sync rules');
|
|
58
|
+
try {
|
|
59
|
+
// Configure new sync rules, if they have changed.
|
|
60
|
+
// In that case, also immediately take out a lock, so that another process doesn't start replication on it.
|
|
61
|
+
const { lock } = await this.storage.configureSyncRules(syncRules, {
|
|
62
|
+
lock: true
|
|
63
|
+
});
|
|
64
|
+
if (lock) {
|
|
65
|
+
configuredLock = lock;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
// Log, but continue with previous sync rules
|
|
70
|
+
this.logger.error(`Failed to update sync rules from configuration`, e);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.logger.info('No sync rules configured - configure via API');
|
|
75
|
+
}
|
|
76
|
+
while (!this.stopped) {
|
|
77
|
+
await container.probes.touch();
|
|
78
|
+
try {
|
|
79
|
+
await this.refresh({ configured_lock: configuredLock });
|
|
80
|
+
// The lock is only valid on the first refresh.
|
|
81
|
+
configuredLock = undefined;
|
|
82
|
+
// Ensure that the replication jobs' connections are kept alive.
|
|
83
|
+
// We don't ping while in error retry back-off, to avoid having too failures.
|
|
84
|
+
if (this.rateLimiter.mayPing()) {
|
|
85
|
+
const now = hrtime.bigint();
|
|
86
|
+
if (now - this.lastPing >= PING_INTERVAL) {
|
|
87
|
+
for (const activeJob of this.replicationJobs.values()) {
|
|
88
|
+
await activeJob.keepAlive();
|
|
89
|
+
}
|
|
90
|
+
this.lastPing = now;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
this.logger.error('Failed to refresh replication jobs', e);
|
|
96
|
+
}
|
|
97
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async refresh(options) {
|
|
101
|
+
if (this.stopped) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
let configuredLock = options?.configured_lock;
|
|
105
|
+
const existingJobs = new Map(this.replicationJobs.entries());
|
|
106
|
+
const replicatingSyncRules = await this.storage.getReplicatingSyncRules();
|
|
107
|
+
const newJobs = new Map();
|
|
108
|
+
for (let syncRules of replicatingSyncRules) {
|
|
109
|
+
const existingJob = existingJobs.get(syncRules.id);
|
|
110
|
+
if (existingJob && !existingJob.isStopped) {
|
|
111
|
+
// No change
|
|
112
|
+
existingJobs.delete(syncRules.id);
|
|
113
|
+
newJobs.set(syncRules.id, existingJob);
|
|
114
|
+
}
|
|
115
|
+
else if (existingJob && existingJob.isStopped) {
|
|
116
|
+
// Stopped (e.g. fatal error).
|
|
117
|
+
// Remove from the list. Next refresh call will restart the job.
|
|
118
|
+
existingJobs.delete(syncRules.id);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// New sync rules were found (or resume after restart)
|
|
122
|
+
try {
|
|
123
|
+
let lock;
|
|
124
|
+
if (configuredLock?.sync_rules_id == syncRules.id) {
|
|
125
|
+
lock = configuredLock;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
lock = await syncRules.lock();
|
|
129
|
+
}
|
|
130
|
+
const storage = this.storage.getInstance(syncRules);
|
|
131
|
+
const newJob = this.createJob({
|
|
132
|
+
lock: lock,
|
|
133
|
+
storage: storage
|
|
134
|
+
});
|
|
135
|
+
newJobs.set(syncRules.id, newJob);
|
|
136
|
+
newJob.start();
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
// Could be a sync rules parse error,
|
|
140
|
+
// for example from stricter validation that was added.
|
|
141
|
+
// This will be retried every couple of seconds.
|
|
142
|
+
// When new (valid) sync rules are deployed and processed, this one be disabled.
|
|
143
|
+
this.logger.error('Failed to start replication for new sync rules', e);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
this.replicationJobs = newJobs;
|
|
148
|
+
// Terminate any orphaned jobs that no longer have sync rules
|
|
149
|
+
for (let job of existingJobs.values()) {
|
|
150
|
+
// Old - stop and clean up
|
|
151
|
+
try {
|
|
152
|
+
await job.stop();
|
|
153
|
+
await this.terminateSyncRules(job.storage);
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
// This will be retried
|
|
157
|
+
this.logger.warn('Failed to terminate old replication job}', e);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Sync rules stopped previously or by a different process.
|
|
161
|
+
const stopped = await this.storage.getStoppedSyncRules();
|
|
162
|
+
for (let syncRules of stopped) {
|
|
163
|
+
try {
|
|
164
|
+
const syncRuleStorage = this.storage.getInstance(syncRules);
|
|
165
|
+
await this.terminateSyncRules(syncRuleStorage);
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
this.logger.warn(`Failed clean up replication config for sync rule: ${syncRules.id}`, e);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
createJobId(syncRuleId) {
|
|
173
|
+
return `${this.id}-${syncRuleId}`;
|
|
174
|
+
}
|
|
175
|
+
async terminateSyncRules(syncRuleStorage) {
|
|
176
|
+
this.logger.info(`Terminating sync rules: ${syncRuleStorage.group_id}...`);
|
|
177
|
+
try {
|
|
178
|
+
await this.cleanUp(syncRuleStorage);
|
|
179
|
+
await syncRuleStorage.terminate();
|
|
180
|
+
this.logger.info(`Successfully terminated sync rules: ${syncRuleStorage.group_id}`);
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
this.logger.warn(`Failed clean up replication config for sync rules: ${syncRuleStorage.group_id}`, e);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=AbstractReplicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbstractReplicator.js","sourceRoot":"","sources":["../../src/replication/AbstractReplicator.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,12 +6,3 @@ export interface ErrorRateLimiter {
|
|
|
6
6
|
reportError(e: any): void;
|
|
7
7
|
mayPing(): boolean;
|
|
8
8
|
}
|
|
9
|
-
export declare class DefaultErrorRateLimiter implements ErrorRateLimiter {
|
|
10
|
-
nextAllowed: number;
|
|
11
|
-
waitUntilAllowed(options?: {
|
|
12
|
-
signal?: AbortSignal | undefined;
|
|
13
|
-
} | undefined): Promise<void>;
|
|
14
|
-
mayPing(): boolean;
|
|
15
|
-
reportError(e: any): void;
|
|
16
|
-
private setDelay;
|
|
17
|
-
}
|
|
@@ -1,43 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export class DefaultErrorRateLimiter {
|
|
3
|
-
constructor() {
|
|
4
|
-
this.nextAllowed = Date.now();
|
|
5
|
-
}
|
|
6
|
-
async waitUntilAllowed(options) {
|
|
7
|
-
const delay = Math.max(0, this.nextAllowed - Date.now());
|
|
8
|
-
// Minimum delay between connections, even without errors
|
|
9
|
-
this.setDelay(500);
|
|
10
|
-
await setTimeout(delay, undefined, { signal: options?.signal });
|
|
11
|
-
}
|
|
12
|
-
mayPing() {
|
|
13
|
-
return Date.now() >= this.nextAllowed;
|
|
14
|
-
}
|
|
15
|
-
reportError(e) {
|
|
16
|
-
const message = e.message ?? '';
|
|
17
|
-
if (message.includes('password authentication failed')) {
|
|
18
|
-
// Wait 15 minutes, to avoid triggering Supabase's fail2ban
|
|
19
|
-
this.setDelay(900000);
|
|
20
|
-
}
|
|
21
|
-
else if (message.includes('ENOTFOUND')) {
|
|
22
|
-
// DNS lookup issue - incorrect URI or deleted instance
|
|
23
|
-
this.setDelay(120000);
|
|
24
|
-
}
|
|
25
|
-
else if (message.includes('ECONNREFUSED')) {
|
|
26
|
-
// Could be fail2ban or similar
|
|
27
|
-
this.setDelay(120000);
|
|
28
|
-
}
|
|
29
|
-
else if (message.includes('Unable to do postgres query on ended pool') ||
|
|
30
|
-
message.includes('Postgres unexpectedly closed connection')) {
|
|
31
|
-
// Connection timed out - ignore / immediately retry
|
|
32
|
-
// We don't explicitly set the delay to 0, since there could have been another error that
|
|
33
|
-
// we need to respect.
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
this.setDelay(30000);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
setDelay(delay) {
|
|
40
|
-
this.nextAllowed = Math.max(this.nextAllowed, Date.now() + delay);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
1
|
+
export {};
|
|
43
2
|
//# sourceMappingURL=ErrorRateLimiter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorRateLimiter.js","sourceRoot":"","sources":["../../src/replication/ErrorRateLimiter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ErrorRateLimiter.js","sourceRoot":"","sources":["../../src/replication/ErrorRateLimiter.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AbstractReplicator } from './AbstractReplicator.js';
|
|
2
|
+
export declare class ReplicationEngine {
|
|
3
|
+
private readonly replicators;
|
|
4
|
+
/**
|
|
5
|
+
* Register a Replicator with the engine
|
|
6
|
+
*
|
|
7
|
+
* @param replicator
|
|
8
|
+
*/
|
|
9
|
+
register(replicator: AbstractReplicator): void;
|
|
10
|
+
/**
|
|
11
|
+
* Start replication on all managed Replicators
|
|
12
|
+
*/
|
|
13
|
+
start(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Stop replication on all managed Replicators
|
|
16
|
+
*/
|
|
17
|
+
shutDown(): Promise<void>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { logger } from '@powersync/lib-services-framework';
|
|
2
|
+
export class ReplicationEngine {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.replicators = new Map();
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Register a Replicator with the engine
|
|
8
|
+
*
|
|
9
|
+
* @param replicator
|
|
10
|
+
*/
|
|
11
|
+
register(replicator) {
|
|
12
|
+
if (this.replicators.has(replicator.id)) {
|
|
13
|
+
throw new Error(`Replicator with id: ${replicator.id} already registered`);
|
|
14
|
+
}
|
|
15
|
+
logger.info(`Successfully registered Replicator ${replicator.id} with ReplicationEngine`);
|
|
16
|
+
this.replicators.set(replicator.id, replicator);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Start replication on all managed Replicators
|
|
20
|
+
*/
|
|
21
|
+
start() {
|
|
22
|
+
logger.info('Starting Replication Engine...');
|
|
23
|
+
for (const replicator of this.replicators.values()) {
|
|
24
|
+
logger.info(`Starting Replicator: ${replicator.id}`);
|
|
25
|
+
replicator.start();
|
|
26
|
+
}
|
|
27
|
+
logger.info('Successfully started Replication Engine.');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Stop replication on all managed Replicators
|
|
31
|
+
*/
|
|
32
|
+
async shutDown() {
|
|
33
|
+
logger.info('Shutting down Replication Engine...');
|
|
34
|
+
for (const replicator of this.replicators.values()) {
|
|
35
|
+
logger.info(`Stopping Replicator: ${replicator.id}`);
|
|
36
|
+
await replicator.stop();
|
|
37
|
+
}
|
|
38
|
+
logger.info('Successfully shut down Replication Engine.');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=ReplicationEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReplicationEngine.js","sourceRoot":"","sources":["../../src/replication/ReplicationEngine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAE3D,MAAM,OAAO,iBAAiB;IAA9B;QACmB,gBAAW,GAAoC,IAAI,GAAG,EAAE,CAAC;IAsC5E,CAAC;IApCC;;;;OAIG;IACI,QAAQ,CAAC,UAA8B;QAC5C,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE;YACvC,MAAM,IAAI,KAAK,CAAC,uBAAuB,UAAU,CAAC,EAAE,qBAAqB,CAAC,CAAC;SAC5E;QACD,MAAM,CAAC,IAAI,CAAC,sCAAsC,UAAU,CAAC,EAAE,yBAAyB,CAAC,CAAC;QAC1F,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACI,KAAK;QACV,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAC9C,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE;YAClD,MAAM,CAAC,IAAI,CAAC,wBAAwB,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;YACrD,UAAU,CAAC,KAAK,EAAE,CAAC;SACpB;QACD,MAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,QAAQ;QACnB,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACnD,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE;YAClD,MAAM,CAAC,IAAI,CAAC,wBAAwB,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;YACrD,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;SACzB;QACD,MAAM,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IAC5D,CAAC;CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { DataSourceConfig } from '@powersync/service-types/dist/config/PowerSyncConfig.js';
|
|
2
|
+
import * as t from 'ts-codec';
|
|
3
|
+
import * as api from '../api/api-index.js';
|
|
4
|
+
import * as modules from '../modules/modules-index.js';
|
|
5
|
+
import * as system from '../system/system-index.js';
|
|
6
|
+
import { AbstractReplicator } from './AbstractReplicator.js';
|
|
7
|
+
export interface ReplicationModuleOptions extends modules.AbstractModuleOptions {
|
|
8
|
+
type: string;
|
|
9
|
+
configSchema: t.AnyCodec;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A replication module describes all the functionality that PowerSync requires to
|
|
13
|
+
* replicate data from a DataSource. Whenever a new data source is added to powersync this class should be extended.
|
|
14
|
+
*/
|
|
15
|
+
export declare abstract class ReplicationModule<TConfig extends DataSourceConfig> extends modules.AbstractModule {
|
|
16
|
+
protected type: string;
|
|
17
|
+
protected configSchema: t.AnyCodec;
|
|
18
|
+
protected decodedConfig: TConfig | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* @protected
|
|
21
|
+
* @param options
|
|
22
|
+
*/
|
|
23
|
+
protected constructor(options: ReplicationModuleOptions);
|
|
24
|
+
/**
|
|
25
|
+
* Create the RouteAPI adapter for the DataSource required to service the sync API
|
|
26
|
+
* endpoints.
|
|
27
|
+
*/
|
|
28
|
+
protected abstract createRouteAPIAdapter(): api.RouteAPI;
|
|
29
|
+
/**
|
|
30
|
+
* Create the Replicator to be used by the ReplicationEngine.
|
|
31
|
+
*/
|
|
32
|
+
protected abstract createReplicator(context: system.ServiceContext): AbstractReplicator;
|
|
33
|
+
/**
|
|
34
|
+
* Register this module's Replicators and RouteAPI adapters if the required configuration is present.
|
|
35
|
+
*/
|
|
36
|
+
initialize(context: system.ServiceContext): Promise<void>;
|
|
37
|
+
private validateConfig;
|
|
38
|
+
protected getDefaultId(dataSourceName: string): string;
|
|
39
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as t from 'ts-codec';
|
|
2
|
+
import * as types from '@powersync/service-types';
|
|
3
|
+
import * as modules from '../modules/modules-index.js';
|
|
4
|
+
import { schema } from '@powersync/lib-services-framework';
|
|
5
|
+
/**
|
|
6
|
+
* A replication module describes all the functionality that PowerSync requires to
|
|
7
|
+
* replicate data from a DataSource. Whenever a new data source is added to powersync this class should be extended.
|
|
8
|
+
*/
|
|
9
|
+
export class ReplicationModule extends modules.AbstractModule {
|
|
10
|
+
/**
|
|
11
|
+
* @protected
|
|
12
|
+
* @param options
|
|
13
|
+
*/
|
|
14
|
+
constructor(options) {
|
|
15
|
+
super(options);
|
|
16
|
+
this.type = options.type;
|
|
17
|
+
this.configSchema = options.configSchema;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Register this module's Replicators and RouteAPI adapters if the required configuration is present.
|
|
21
|
+
*/
|
|
22
|
+
async initialize(context) {
|
|
23
|
+
if (!context.configuration.connections) {
|
|
24
|
+
// No data source configuration found in the config skip for now
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const matchingConfig = context.configuration.connections.filter((dataSource) => dataSource.type === this.type);
|
|
28
|
+
if (!matchingConfig.length) {
|
|
29
|
+
// This module is needed given the config
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (matchingConfig.length > 1) {
|
|
33
|
+
this.logger.warning(`Multiple data sources of type ${this.type} found in the configuration. Only the first will be used.`);
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const baseMatchingConfig = matchingConfig[0];
|
|
37
|
+
// If validation fails, log the error and continue, no replication will happen for this data source
|
|
38
|
+
this.validateConfig(baseMatchingConfig);
|
|
39
|
+
this.decodedConfig = this.configSchema.decode(baseMatchingConfig);
|
|
40
|
+
context.replicationEngine?.register(this.createReplicator(context));
|
|
41
|
+
context.routerEngine?.registerAPI(this.createRouteAPIAdapter());
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
this.logger.error('Failed to initialize.', e);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
validateConfig(config) {
|
|
48
|
+
const validator = schema
|
|
49
|
+
.parseJSONSchema(
|
|
50
|
+
// This generates a schema for the encoded form of the codec
|
|
51
|
+
t.generateJSONSchema(this.configSchema, {
|
|
52
|
+
allowAdditional: true,
|
|
53
|
+
parsers: [types.configFile.portParser]
|
|
54
|
+
}))
|
|
55
|
+
.validator();
|
|
56
|
+
const valid = validator.validate(config);
|
|
57
|
+
if (!valid.valid) {
|
|
58
|
+
throw new Error(`Failed to validate Module ${this.name} configuration: ${valid.errors.join(', ')}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
getDefaultId(dataSourceName) {
|
|
62
|
+
return `${this.type}-${dataSourceName}`;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=ReplicationModule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReplicationModule.js","sourceRoot":"","sources":["../../src/replication/ReplicationModule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,OAAO,KAAK,KAAK,MAAM,0BAA0B,CAAC;AAElD,OAAO,KAAK,OAAO,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAQ3D;;;GAGG;AACH,MAAM,OAAgB,iBAAoD,SAAQ,OAAO,CAAC,cAAc;IAKtG;;;OAGG;IACH,YAAsB,OAAiC;QACrD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC3C,CAAC;IAaD;;OAEG;IACI,KAAK,CAAC,UAAU,CAAC,OAA8B;QACpD,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,WAAW,EAAE;YACtC,gEAAgE;YAChE,OAAO;SACR;QAED,MAAM,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/G,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;YAC1B,yCAAyC;YACzC,OAAO;SACR;QAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;YAC7B,IAAI,CAAC,MAAM,CAAC,OAAO,CACjB,iCAAiC,IAAI,CAAC,IAAI,2DAA2D,CACtG,CAAC;SACH;QAED,IAAI;YACF,MAAM,kBAAkB,GAAG,cAAc,CAAC,CAAC,CAAY,CAAC;YACxD,mGAAmG;YACnG,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;YACxC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAElE,OAAO,CAAC,iBAAiB,EAAE,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;YACpE,OAAO,CAAC,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;SACjE;QAAC,OAAO,CAAC,EAAE;YACV,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC;SAC/C;IACH,CAAC;IAEO,cAAc,CAAC,MAAe;QACpC,MAAM,SAAS,GAAG,MAAM;aACrB,eAAe;QACd,4DAA4D;QAC5D,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,EAAE;YACtC,eAAe,EAAE,IAAI;YACrB,OAAO,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC;SACvC,CAAC,CACH;aACA,SAAS,EAAE,CAAC;QAEf,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAEzC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;YAChB,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,IAAI,mBAAmB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACrG;IACH,CAAC;IAES,YAAY,CAAC,cAAsB;QAC3C,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;IAC1C,CAAC;CACF"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export * from './ErrorRateLimiter.js';
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './WalStreamManager.js';
|
|
7
|
-
export * from './WalStreamRunner.js';
|
|
2
|
+
export * from './AbstractReplicationJob.js';
|
|
3
|
+
export * from './AbstractReplicator.js';
|
|
4
|
+
export * from './ReplicationEngine.js';
|
|
5
|
+
export * from './ReplicationModule.js';
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export * from './ErrorRateLimiter.js';
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './WalStreamManager.js';
|
|
7
|
-
export * from './WalStreamRunner.js';
|
|
2
|
+
export * from './AbstractReplicationJob.js';
|
|
3
|
+
export * from './AbstractReplicator.js';
|
|
4
|
+
export * from './ReplicationEngine.js';
|
|
5
|
+
export * from './ReplicationModule.js';
|
|
8
6
|
//# sourceMappingURL=replication-index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replication-index.js","sourceRoot":"","sources":["../../src/replication/replication-index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,
|
|
1
|
+
{"version":3,"file":"replication-index.js","sourceRoot":"","sources":["../../src/replication/replication-index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC"}
|