@powersync/service-core 0.8.8 → 0.10.0
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 +43 -0
- package/dist/api/RouteAPI.d.ts +67 -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 +170 -158
- package/dist/api/diagnostics.js.map +1 -1
- package/dist/api/schema.d.ts +3 -5
- package/dist/api/schema.js +14 -80
- package/dist/api/schema.js.map +1 -1
- package/dist/auth/CachedKeyCollector.js.map +1 -1
- package/dist/auth/KeySpec.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/LeakyBucket.js.map +1 -1
- package/dist/auth/RemoteJWKSCollector.d.ts +0 -2
- package/dist/auth/RemoteJWKSCollector.js.map +1 -1
- package/dist/auth/StaticSupabaseKeyCollector.d.ts +19 -0
- package/dist/auth/StaticSupabaseKeyCollector.js +28 -0
- package/dist/auth/StaticSupabaseKeyCollector.js.map +1 -0
- package/dist/auth/auth-index.d.ts +1 -1
- package/dist/auth/auth-index.js +1 -1
- package/dist/auth/auth-index.js.map +1 -1
- package/dist/db/mongo.js +5 -3
- package/dist/db/mongo.js.map +1 -1
- package/dist/entry/cli-entry.js +3 -2
- package/dist/entry/cli-entry.js.map +1 -1
- package/dist/entry/commands/compact-action.js +90 -14
- package/dist/entry/commands/compact-action.js.map +1 -1
- 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/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/locks/MongoLocks.js.map +1 -1
- package/dist/metrics/Metrics.d.ts +2 -2
- package/dist/metrics/Metrics.js +5 -13
- 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/db/migrations/1727099539247-custom-write-checkpoint-index.d.ts +3 -0
- package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.js +31 -0
- package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.js.map +1 -0
- package/dist/migrations/executor.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/migrations/store/migration-store.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 +37 -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 +250 -0
- package/dist/replication/AbstractReplicator.js.map +1 -0
- package/dist/replication/ErrorRateLimiter.d.ts +0 -10
- 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 +51 -0
- package/dist/replication/ReplicationModule.js +68 -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 +37 -23
- package/dist/routes/configure-fastify.js +18 -18
- package/dist/routes/configure-fastify.js.map +1 -1
- package/dist/routes/configure-rsocket.d.ts +3 -4
- package/dist/routes/configure-rsocket.js +7 -4
- package/dist/routes/configure-rsocket.js.map +1 -1
- package/dist/routes/endpoints/admin.d.ts +30 -0
- package/dist/routes/endpoints/admin.js +46 -67
- package/dist/routes/endpoints/admin.js.map +1 -1
- package/dist/routes/endpoints/checkpointing.js +103 -15
- package/dist/routes/endpoints/checkpointing.js.map +1 -1
- package/dist/routes/endpoints/socket-route.js +8 -6
- 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 +0 -1
- package/dist/routes/endpoints/sync-stream.js +8 -8
- package/dist/routes/endpoints/sync-stream.js.map +1 -1
- package/dist/routes/hooks.js.map +1 -1
- package/dist/routes/route-register.js.map +1 -1
- package/dist/routes/router.d.ts +9 -2
- package/dist/routes/router.js.map +1 -1
- package/dist/routes/routes-index.d.ts +1 -0
- package/dist/routes/routes-index.js +1 -0
- package/dist/routes/routes-index.js.map +1 -1
- package/dist/runner/teardown.js +109 -76
- package/dist/runner/teardown.js.map +1 -1
- package/dist/storage/BucketStorage.d.ts +86 -36
- package/dist/storage/BucketStorage.js +6 -10
- package/dist/storage/BucketStorage.js.map +1 -1
- package/dist/storage/ChecksumCache.js.map +1 -1
- package/dist/storage/MongoBucketStorage.d.ts +7 -11
- package/dist/storage/MongoBucketStorage.js +48 -41
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/ReplicationEventPayload.d.ts +14 -0
- package/dist/storage/ReplicationEventPayload.js +2 -0
- package/dist/storage/ReplicationEventPayload.js.map +1 -0
- 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 +12 -5
- package/dist/storage/SourceTable.js +12 -5
- package/dist/storage/SourceTable.js.map +1 -1
- package/dist/storage/StorageEngine.d.ts +28 -0
- package/dist/storage/StorageEngine.js +45 -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/WriteCheckpointAPI.d.ts +74 -0
- package/dist/storage/WriteCheckpointAPI.js +16 -0
- package/dist/storage/WriteCheckpointAPI.js.map +1 -0
- package/dist/storage/mongo/MongoBucketBatch.d.ts +24 -5
- package/dist/storage/mongo/MongoBucketBatch.js +119 -62
- package/dist/storage/mongo/MongoBucketBatch.js.map +1 -1
- package/dist/storage/mongo/MongoCompactor.js +20 -3
- package/dist/storage/mongo/MongoCompactor.js.map +1 -1
- package/dist/storage/mongo/MongoIdSequence.js.map +1 -1
- 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 +18 -10
- package/dist/storage/mongo/MongoSyncBucketStorage.js +140 -25
- 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/MongoWriteCheckpointAPI.d.ts +20 -0
- package/dist/storage/mongo/MongoWriteCheckpointAPI.js +103 -0
- package/dist/storage/mongo/MongoWriteCheckpointAPI.js.map +1 -0
- package/dist/storage/mongo/OperationBatch.d.ts +13 -4
- package/dist/storage/mongo/OperationBatch.js +25 -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/config.d.ts +19 -0
- package/dist/storage/mongo/config.js +26 -0
- package/dist/storage/mongo/config.js.map +1 -0
- package/dist/storage/mongo/db.d.ts +3 -2
- package/dist/storage/mongo/db.js +1 -0
- package/dist/storage/mongo/db.js.map +1 -1
- package/dist/storage/mongo/models.d.ts +20 -5
- package/dist/storage/mongo/models.js.map +1 -1
- package/dist/storage/mongo/util.d.ts +12 -1
- package/dist/storage/mongo/util.js +50 -2
- package/dist/storage/mongo/util.js.map +1 -1
- package/dist/storage/storage-index.d.ts +8 -2
- package/dist/storage/storage-index.js +8 -2
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/sync/BroadcastIterable.d.ts +0 -1
- package/dist/sync/BroadcastIterable.js.map +1 -1
- package/dist/sync/LastValueSink.d.ts +0 -1
- package/dist/sync/LastValueSink.js.map +1 -1
- package/dist/sync/merge.d.ts +0 -1
- package/dist/sync/merge.js.map +1 -1
- package/dist/sync/safeRace.js.map +1 -1
- package/dist/sync/sync.d.ts +1 -1
- package/dist/sync/sync.js +5 -5
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/util.d.ts +0 -2
- package/dist/sync/util.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/Mutex.js.map +1 -1
- package/dist/util/config/collectors/config-collector.js.map +1 -1
- package/dist/util/config/collectors/impl/base64-config-collector.js.map +1 -1
- package/dist/util/config/collectors/impl/filesystem-config-collector.js.map +1 -1
- package/dist/util/config/compound-config-collector.d.ts +9 -2
- package/dist/util/config/compound-config-collector.js +31 -23
- package/dist/util/config/compound-config-collector.js.map +1 -1
- package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js.map +1 -1
- package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js.map +1 -1
- package/dist/util/config/sync-rules/impl/inline-sync-rules-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 +7 -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/memory-tracking.js.map +1 -1
- package/dist/util/secs.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 -7
- package/dist/util/utils.js +36 -25
- package/dist/util/utils.js.map +1 -1
- package/package.json +8 -12
- package/src/api/RouteAPI.ts +78 -0
- package/src/api/api-index.ts +1 -0
- package/src/api/diagnostics.ts +18 -70
- package/src/api/schema.ts +18 -90
- package/src/auth/KeyStore.ts +9 -6
- package/src/auth/RemoteJWKSCollector.ts +4 -1
- package/src/auth/StaticSupabaseKeyCollector.ts +31 -0
- package/src/auth/auth-index.ts +1 -1
- package/src/db/mongo.ts +5 -3
- package/src/entry/cli-entry.ts +3 -2
- package/src/entry/commands/compact-action.ts +24 -12
- package/src/entry/commands/migrate-action.ts +5 -8
- package/src/entry/commands/teardown-action.ts +2 -2
- package/src/index.ts +5 -2
- package/src/metrics/Metrics.ts +6 -16
- 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/db/migrations/1727099539247-custom-write-checkpoint-index.ts +37 -0
- 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 +228 -0
- package/src/replication/ErrorRateLimiter.ts +0 -44
- package/src/replication/ReplicationEngine.ts +43 -0
- package/src/replication/ReplicationModule.ts +122 -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 +26 -27
- package/src/routes/configure-rsocket.ts +13 -8
- package/src/routes/endpoints/admin.ts +72 -76
- package/src/routes/endpoints/checkpointing.ts +51 -11
- package/src/routes/endpoints/socket-route.ts +10 -6
- package/src/routes/endpoints/sync-rules.ts +41 -25
- package/src/routes/endpoints/sync-stream.ts +8 -8
- package/src/routes/router.ts +8 -3
- package/src/routes/routes-index.ts +1 -0
- package/src/runner/teardown.ts +50 -88
- package/src/storage/BucketStorage.ts +103 -41
- package/src/storage/MongoBucketStorage.ts +65 -53
- package/src/storage/ReplicationEventPayload.ts +16 -0
- package/src/storage/SourceEntity.ts +22 -0
- package/src/storage/SourceTable.ts +14 -7
- package/src/storage/StorageEngine.ts +62 -0
- package/src/storage/StorageProvider.ts +27 -0
- package/src/storage/WriteCheckpointAPI.ts +85 -0
- package/src/storage/mongo/MongoBucketBatch.ts +164 -84
- package/src/storage/mongo/MongoCompactor.ts +25 -4
- package/src/storage/mongo/MongoPersistedSyncRulesContent.ts +7 -4
- package/src/storage/mongo/MongoStorageProvider.ts +31 -0
- package/src/storage/mongo/MongoSyncBucketStorage.ts +118 -41
- package/src/storage/mongo/MongoSyncRulesLock.ts +7 -3
- package/src/storage/mongo/MongoWriteCheckpointAPI.ts +151 -0
- package/src/storage/mongo/OperationBatch.ts +28 -12
- package/src/storage/mongo/PersistedBatch.ts +10 -6
- package/src/storage/mongo/config.ts +40 -0
- package/src/storage/mongo/db.ts +4 -1
- package/src/storage/mongo/models.ts +21 -5
- package/src/storage/mongo/util.ts +48 -3
- package/src/storage/storage-index.ts +8 -2
- package/src/sync/sync.ts +7 -4
- package/src/sync/util.ts +0 -1
- package/src/system/ServiceContext.ts +68 -0
- package/src/system/system-index.ts +1 -1
- package/src/util/config/compound-config-collector.ts +48 -30
- package/src/util/config/sync-rules/sync-rules-provider.ts +18 -0
- package/src/util/config/types.ts +7 -5
- package/src/util/config.ts +6 -23
- package/src/util/util-index.ts +3 -6
- package/src/util/utils.ts +48 -41
- package/test/src/__snapshots__/sync.test.ts.snap +14 -14
- package/test/src/auth.test.ts +7 -7
- package/test/src/broadcast_iterable.test.ts +1 -1
- package/test/src/compacting.test.ts +50 -40
- package/test/src/data_storage.test.ts +382 -202
- package/test/src/env.ts +1 -3
- package/test/src/merge_iterable.test.ts +1 -6
- package/test/src/routes/probes.integration.test.ts +34 -30
- package/test/src/setup.ts +1 -1
- package/test/src/stream_utils.ts +42 -0
- package/test/src/sync.test.ts +115 -39
- package/test/src/util.ts +48 -51
- package/test/tsconfig.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +7 -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 -519
- 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/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 -631
- package/src/replication/WalStreamManager.ts +0 -213
- package/src/replication/WalStreamRunner.ts +0 -180
- package/src/replication/util.ts +0 -76
- 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 -338
- package/test/src/validation.test.ts +0 -63
- package/test/src/wal_stream.test.ts +0 -319
- package/test/src/wal_stream_utils.ts +0 -156
|
@@ -9,7 +9,7 @@ import { PROBES_ROUTES } from './endpoints/probes.js';
|
|
|
9
9
|
import { SYNC_RULES_ROUTES } from './endpoints/sync-rules.js';
|
|
10
10
|
import { SYNC_STREAM_ROUTES } from './endpoints/sync-stream.js';
|
|
11
11
|
import { createRequestQueueHook, CreateRequestQueueParams } from './hooks.js';
|
|
12
|
-
import { RouteDefinition } from './router.js';
|
|
12
|
+
import { RouteDefinition, RouterServiceContext } from './router.js';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* A list of route definitions to be registered as endpoints.
|
|
@@ -17,7 +17,7 @@ import { RouteDefinition } from './router.js';
|
|
|
17
17
|
*/
|
|
18
18
|
export type RouteRegistrationOptions = {
|
|
19
19
|
routes: RouteDefinition[];
|
|
20
|
-
|
|
20
|
+
queue_options: CreateRequestQueueParams;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -26,25 +26,25 @@ export type RouteRegistrationOptions = {
|
|
|
26
26
|
*/
|
|
27
27
|
export type RouteDefinitions = {
|
|
28
28
|
api?: Partial<RouteRegistrationOptions>;
|
|
29
|
-
|
|
29
|
+
sync_stream?: Partial<RouteRegistrationOptions>;
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
export type FastifyServerConfig = {
|
|
33
|
-
|
|
33
|
+
service_context: system.ServiceContext;
|
|
34
34
|
routes?: RouteDefinitions;
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
export const DEFAULT_ROUTE_OPTIONS = {
|
|
38
38
|
api: {
|
|
39
39
|
routes: [...ADMIN_ROUTES, ...CHECKPOINT_ROUTES, ...SYNC_RULES_ROUTES, ...PROBES_ROUTES],
|
|
40
|
-
|
|
40
|
+
queue_options: {
|
|
41
41
|
concurrency: 10,
|
|
42
42
|
max_queue_depth: 20
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
|
-
|
|
45
|
+
sync_stream: {
|
|
46
46
|
routes: [...SYNC_STREAM_ROUTES],
|
|
47
|
-
|
|
47
|
+
queue_options: {
|
|
48
48
|
concurrency: 200,
|
|
49
49
|
max_queue_depth: 0
|
|
50
50
|
}
|
|
@@ -56,7 +56,20 @@ export const DEFAULT_ROUTE_OPTIONS = {
|
|
|
56
56
|
* concurrency queue limits or override routes.
|
|
57
57
|
*/
|
|
58
58
|
export function configureFastifyServer(server: fastify.FastifyInstance, options: FastifyServerConfig) {
|
|
59
|
-
const {
|
|
59
|
+
const { service_context, routes = DEFAULT_ROUTE_OPTIONS } = options;
|
|
60
|
+
|
|
61
|
+
const generateContext = async () => {
|
|
62
|
+
const { routerEngine } = service_context;
|
|
63
|
+
if (!routerEngine) {
|
|
64
|
+
throw new Error(`RouterEngine has not been registered`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
user_id: undefined,
|
|
69
|
+
service_context: service_context as RouterServiceContext
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
60
73
|
/**
|
|
61
74
|
* Fastify creates an encapsulated context for each `.register` call.
|
|
62
75
|
* Creating a separate context here to separate the concurrency limits for Admin APIs
|
|
@@ -64,20 +77,11 @@ export function configureFastifyServer(server: fastify.FastifyInstance, options:
|
|
|
64
77
|
* https://github.com/fastify/fastify/blob/main/docs/Reference/Encapsulation.md
|
|
65
78
|
*/
|
|
66
79
|
server.register(async function (childContext) {
|
|
67
|
-
registerFastifyRoutes(
|
|
68
|
-
childContext,
|
|
69
|
-
async () => {
|
|
70
|
-
return {
|
|
71
|
-
user_id: undefined,
|
|
72
|
-
system: system
|
|
73
|
-
};
|
|
74
|
-
},
|
|
75
|
-
routes.api?.routes ?? DEFAULT_ROUTE_OPTIONS.api.routes
|
|
76
|
-
);
|
|
80
|
+
registerFastifyRoutes(childContext, generateContext, routes.api?.routes ?? DEFAULT_ROUTE_OPTIONS.api.routes);
|
|
77
81
|
// Limit the active concurrent requests
|
|
78
82
|
childContext.addHook(
|
|
79
83
|
'onRequest',
|
|
80
|
-
createRequestQueueHook(routes.api?.
|
|
84
|
+
createRequestQueueHook(routes.api?.queue_options ?? DEFAULT_ROUTE_OPTIONS.api.queue_options)
|
|
81
85
|
);
|
|
82
86
|
});
|
|
83
87
|
|
|
@@ -85,18 +89,13 @@ export function configureFastifyServer(server: fastify.FastifyInstance, options:
|
|
|
85
89
|
server.register(async function (childContext) {
|
|
86
90
|
registerFastifyRoutes(
|
|
87
91
|
childContext,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
user_id: undefined,
|
|
91
|
-
system: system
|
|
92
|
-
};
|
|
93
|
-
},
|
|
94
|
-
routes.syncStream?.routes ?? DEFAULT_ROUTE_OPTIONS.syncStream.routes
|
|
92
|
+
generateContext,
|
|
93
|
+
routes.sync_stream?.routes ?? DEFAULT_ROUTE_OPTIONS.sync_stream.routes
|
|
95
94
|
);
|
|
96
95
|
// Limit the active concurrent requests
|
|
97
96
|
childContext.addHook(
|
|
98
97
|
'onRequest',
|
|
99
|
-
createRequestQueueHook(routes.
|
|
98
|
+
createRequestQueueHook(routes.sync_stream?.queue_options ?? DEFAULT_ROUTE_OPTIONS.sync_stream.queue_options)
|
|
100
99
|
);
|
|
101
100
|
});
|
|
102
101
|
}
|
|
@@ -4,22 +4,22 @@ import * as http from 'http';
|
|
|
4
4
|
import { errors, logger } from '@powersync/lib-services-framework';
|
|
5
5
|
import { ReactiveSocketRouter, RSocketRequestMeta } from '@powersync/service-rsocket-router';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { ServiceContext } from '../system/ServiceContext.js';
|
|
8
8
|
import { generateContext, getTokenFromHeader } from './auth.js';
|
|
9
9
|
import { syncStreamReactive } from './endpoints/socket-route.js';
|
|
10
10
|
import { RSocketContextMeta, SocketRouteGenerator } from './router-socket.js';
|
|
11
|
-
import { Context } from './router.js';
|
|
11
|
+
import { Context, RouterServiceContext } from './router.js';
|
|
12
12
|
|
|
13
13
|
export type RSockerRouterConfig = {
|
|
14
|
-
|
|
14
|
+
service_context: ServiceContext;
|
|
15
15
|
server: http.Server;
|
|
16
|
-
|
|
16
|
+
route_generators?: SocketRouteGenerator[];
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
export const DEFAULT_SOCKET_ROUTES = [syncStreamReactive];
|
|
20
20
|
|
|
21
21
|
export function configureRSocket(router: ReactiveSocketRouter<Context>, options: RSockerRouterConfig) {
|
|
22
|
-
const {
|
|
22
|
+
const { route_generators = DEFAULT_SOCKET_ROUTES, server, service_context } = options;
|
|
23
23
|
|
|
24
24
|
router.applyWebSocketEndpoints(server, {
|
|
25
25
|
contextProvider: async (data: Buffer) => {
|
|
@@ -32,16 +32,21 @@ export function configureRSocket(router: ReactiveSocketRouter<Context>, options:
|
|
|
32
32
|
try {
|
|
33
33
|
const extracted_token = getTokenFromHeader(token);
|
|
34
34
|
if (extracted_token != null) {
|
|
35
|
-
const { context, errors: token_errors } = await generateContext(
|
|
35
|
+
const { context, errors: token_errors } = await generateContext(options.service_context, extracted_token);
|
|
36
36
|
if (context?.token_payload == null) {
|
|
37
37
|
throw new errors.AuthorizationError(token_errors ?? 'Authentication required');
|
|
38
38
|
}
|
|
39
|
+
|
|
40
|
+
if (!service_context.routerEngine) {
|
|
41
|
+
throw new Error(`RouterEngine has not been registered`);
|
|
42
|
+
}
|
|
43
|
+
|
|
39
44
|
return {
|
|
40
45
|
token,
|
|
41
46
|
user_agent,
|
|
42
47
|
...context,
|
|
43
48
|
token_errors: token_errors,
|
|
44
|
-
|
|
49
|
+
service_context: service_context as RouterServiceContext
|
|
45
50
|
};
|
|
46
51
|
} else {
|
|
47
52
|
throw new errors.AuthorizationError('No token provided');
|
|
@@ -51,7 +56,7 @@ export function configureRSocket(router: ReactiveSocketRouter<Context>, options:
|
|
|
51
56
|
throw ex;
|
|
52
57
|
}
|
|
53
58
|
},
|
|
54
|
-
endpoints:
|
|
59
|
+
endpoints: route_generators.map((generator) => generator(router)),
|
|
55
60
|
metaDecoder: async (meta: Buffer) => {
|
|
56
61
|
return RSocketRequestMeta.decode(deserialize(meta) as any);
|
|
57
62
|
},
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { errors, router, schema } from '@powersync/lib-services-framework';
|
|
2
|
-
import { SqlSyncRules,
|
|
2
|
+
import { SqlSyncRules, StaticSchema } from '@powersync/service-sync-rules';
|
|
3
3
|
import { internal_routes } from '@powersync/service-types';
|
|
4
4
|
|
|
5
5
|
import * as api from '../../api/api-index.js';
|
|
6
|
-
import * as
|
|
7
|
-
|
|
8
|
-
import { PersistedSyncRulesContent } from '../../storage/BucketStorage.js';
|
|
6
|
+
import * as storage from '../../storage/storage-index.js';
|
|
9
7
|
import { authApi } from '../auth.js';
|
|
10
8
|
import { routeDefinition } from '../router.js';
|
|
11
9
|
|
|
@@ -15,47 +13,27 @@ export const executeSql = routeDefinition({
|
|
|
15
13
|
authorize: authApi,
|
|
16
14
|
validator: schema.createTsCodecValidator(internal_routes.ExecuteSqlRequest, { allowAdditional: true }),
|
|
17
15
|
handler: async (payload) => {
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
rows: []
|
|
24
|
-
},
|
|
25
|
-
success: false,
|
|
26
|
-
error: 'SQL querying is not enabled'
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const pool = payload.context.system.requirePgPool();
|
|
31
|
-
|
|
32
|
-
const { query, args } = payload.params.sql;
|
|
16
|
+
const {
|
|
17
|
+
params: {
|
|
18
|
+
sql: { query, args }
|
|
19
|
+
}
|
|
20
|
+
} = payload;
|
|
33
21
|
|
|
34
|
-
|
|
35
|
-
const result = await pool.query({
|
|
36
|
-
statement: query,
|
|
37
|
-
params: args.map(util.autoParameter)
|
|
38
|
-
});
|
|
22
|
+
const apiHandler = payload.context.service_context.routerEngine!.getAPI();
|
|
39
23
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
results: {
|
|
43
|
-
columns: result.columns.map((c) => c.name),
|
|
44
|
-
rows: result.rows.map((row) => {
|
|
45
|
-
return row.map((value) => mapColumnValue(toSyncRulesValue(value)));
|
|
46
|
-
})
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
} catch (e) {
|
|
24
|
+
const sourceConfig = await apiHandler.getSourceConfig();
|
|
25
|
+
if (!sourceConfig.debug_api) {
|
|
50
26
|
return internal_routes.ExecuteSqlResponse.encode({
|
|
51
27
|
results: {
|
|
52
28
|
columns: [],
|
|
53
29
|
rows: []
|
|
54
30
|
},
|
|
55
31
|
success: false,
|
|
56
|
-
error:
|
|
32
|
+
error: 'SQL querying is not enabled'
|
|
57
33
|
});
|
|
58
34
|
}
|
|
35
|
+
|
|
36
|
+
return internal_routes.ExecuteSqlResponse.encode(await apiHandler.executeQuery(query, args));
|
|
59
37
|
}
|
|
60
38
|
});
|
|
61
39
|
|
|
@@ -65,34 +43,45 @@ export const diagnostics = routeDefinition({
|
|
|
65
43
|
authorize: authApi,
|
|
66
44
|
validator: schema.createTsCodecValidator(internal_routes.DiagnosticsRequest, { allowAdditional: true }),
|
|
67
45
|
handler: async (payload) => {
|
|
46
|
+
const { context } = payload;
|
|
47
|
+
const { service_context } = context;
|
|
68
48
|
const include_content = payload.params.sync_rules_content ?? false;
|
|
69
|
-
const system = payload.context.system;
|
|
70
49
|
|
|
71
|
-
const
|
|
72
|
-
|
|
50
|
+
const apiHandler = service_context.routerEngine!.getAPI();
|
|
51
|
+
|
|
52
|
+
const status = await apiHandler.getConnectionStatus();
|
|
53
|
+
if (!status) {
|
|
73
54
|
return internal_routes.DiagnosticsResponse.encode({
|
|
74
55
|
connections: []
|
|
75
56
|
});
|
|
76
57
|
}
|
|
77
58
|
|
|
78
|
-
const {
|
|
79
|
-
|
|
80
|
-
|
|
59
|
+
const {
|
|
60
|
+
storageEngine: { activeBucketStorage }
|
|
61
|
+
} = service_context;
|
|
62
|
+
const active = await activeBucketStorage.getActiveSyncRulesContent();
|
|
63
|
+
const next = await activeBucketStorage.getNextSyncRulesContent();
|
|
81
64
|
|
|
82
|
-
const active_status = await api.getSyncRulesStatus(
|
|
65
|
+
const active_status = await api.getSyncRulesStatus(activeBucketStorage, apiHandler, active, {
|
|
83
66
|
include_content,
|
|
84
67
|
check_connection: status.connected,
|
|
85
68
|
live_status: true
|
|
86
69
|
});
|
|
87
70
|
|
|
88
|
-
const next_status = await api.getSyncRulesStatus(
|
|
71
|
+
const next_status = await api.getSyncRulesStatus(activeBucketStorage, apiHandler, next, {
|
|
89
72
|
include_content,
|
|
90
73
|
check_connection: status.connected,
|
|
91
74
|
live_status: true
|
|
92
75
|
});
|
|
93
76
|
|
|
94
77
|
return internal_routes.DiagnosticsResponse.encode({
|
|
95
|
-
connections: [
|
|
78
|
+
connections: [
|
|
79
|
+
{
|
|
80
|
+
...status,
|
|
81
|
+
// TODO update this in future
|
|
82
|
+
postgres_uri: status.uri
|
|
83
|
+
}
|
|
84
|
+
],
|
|
96
85
|
active_sync_rules: active_status,
|
|
97
86
|
deploying_sync_rules: next_status
|
|
98
87
|
});
|
|
@@ -105,9 +94,9 @@ export const getSchema = routeDefinition({
|
|
|
105
94
|
authorize: authApi,
|
|
106
95
|
validator: schema.createTsCodecValidator(internal_routes.GetSchemaRequest, { allowAdditional: true }),
|
|
107
96
|
handler: async (payload) => {
|
|
108
|
-
const
|
|
97
|
+
const apiHandler = payload.context.service_context.routerEngine!.getAPI();
|
|
109
98
|
|
|
110
|
-
return internal_routes.GetSchemaResponse.encode(await api.getConnectionsSchema(
|
|
99
|
+
return internal_routes.GetSchemaResponse.encode(await api.getConnectionsSchema(apiHandler));
|
|
111
100
|
}
|
|
112
101
|
});
|
|
113
102
|
|
|
@@ -117,15 +106,19 @@ export const reprocess = routeDefinition({
|
|
|
117
106
|
authorize: authApi,
|
|
118
107
|
validator: schema.createTsCodecValidator(internal_routes.ReprocessRequest, { allowAdditional: true }),
|
|
119
108
|
handler: async (payload) => {
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
109
|
+
const {
|
|
110
|
+
context: { service_context }
|
|
111
|
+
} = payload;
|
|
112
|
+
const {
|
|
113
|
+
storageEngine: { activeBucketStorage }
|
|
114
|
+
} = service_context;
|
|
115
|
+
const apiHandler = service_context.routerEngine!.getAPI();
|
|
116
|
+
const next = await activeBucketStorage.getNextSyncRules(apiHandler.getParseSyncRulesOptions());
|
|
124
117
|
if (next != null) {
|
|
125
118
|
throw new Error(`Busy processing sync rules - cannot reprocess`);
|
|
126
119
|
}
|
|
127
120
|
|
|
128
|
-
const active = await
|
|
121
|
+
const active = await activeBucketStorage.getActiveSyncRules(apiHandler.getParseSyncRulesOptions());
|
|
129
122
|
if (active == null) {
|
|
130
123
|
throw new errors.JourneyError({
|
|
131
124
|
status: 422,
|
|
@@ -134,15 +127,18 @@ export const reprocess = routeDefinition({
|
|
|
134
127
|
});
|
|
135
128
|
}
|
|
136
129
|
|
|
137
|
-
const new_rules = await
|
|
130
|
+
const new_rules = await activeBucketStorage.updateSyncRules({
|
|
138
131
|
content: active.sync_rules.content
|
|
139
132
|
});
|
|
140
133
|
|
|
134
|
+
const baseConfig = await apiHandler.getSourceConfig();
|
|
135
|
+
|
|
141
136
|
return internal_routes.ReprocessResponse.encode({
|
|
142
137
|
connections: [
|
|
143
138
|
{
|
|
144
|
-
|
|
145
|
-
|
|
139
|
+
// Previously the connection was asserted with `!`
|
|
140
|
+
tag: baseConfig.tag,
|
|
141
|
+
id: baseConfig.id,
|
|
146
142
|
slot_name: new_rules.slot_name
|
|
147
143
|
}
|
|
148
144
|
]
|
|
@@ -156,14 +152,16 @@ export const validate = routeDefinition({
|
|
|
156
152
|
authorize: authApi,
|
|
157
153
|
validator: schema.createTsCodecValidator(internal_routes.ValidateRequest, { allowAdditional: true }),
|
|
158
154
|
handler: async (payload) => {
|
|
159
|
-
const
|
|
160
|
-
|
|
155
|
+
const {
|
|
156
|
+
context: { service_context }
|
|
157
|
+
} = payload;
|
|
161
158
|
const content = payload.params.sync_rules;
|
|
159
|
+
const apiHandler = service_context.routerEngine!.getAPI();
|
|
162
160
|
|
|
163
|
-
const schemaData = await api.getConnectionsSchema(
|
|
161
|
+
const schemaData = await api.getConnectionsSchema(apiHandler);
|
|
164
162
|
const schema = new StaticSchema(schemaData.connections);
|
|
165
163
|
|
|
166
|
-
const sync_rules: PersistedSyncRulesContent = {
|
|
164
|
+
const sync_rules: storage.PersistedSyncRulesContent = {
|
|
167
165
|
// Dummy values
|
|
168
166
|
id: 0,
|
|
169
167
|
slot_name: '',
|
|
@@ -171,7 +169,10 @@ export const validate = routeDefinition({
|
|
|
171
169
|
parsed() {
|
|
172
170
|
return {
|
|
173
171
|
...this,
|
|
174
|
-
sync_rules: SqlSyncRules.fromYaml(content, {
|
|
172
|
+
sync_rules: SqlSyncRules.fromYaml(content, {
|
|
173
|
+
...apiHandler.getParseSyncRulesOptions(),
|
|
174
|
+
schema
|
|
175
|
+
})
|
|
175
176
|
};
|
|
176
177
|
},
|
|
177
178
|
sync_rules_content: content,
|
|
@@ -180,19 +181,24 @@ export const validate = routeDefinition({
|
|
|
180
181
|
}
|
|
181
182
|
};
|
|
182
183
|
|
|
183
|
-
const connectionStatus = await
|
|
184
|
-
if (connectionStatus
|
|
184
|
+
const connectionStatus = await apiHandler.getConnectionStatus();
|
|
185
|
+
if (!connectionStatus) {
|
|
185
186
|
return internal_routes.ValidateResponse.encode({
|
|
186
187
|
errors: [{ level: 'fatal', message: 'No connection configured' }],
|
|
187
188
|
connections: []
|
|
188
189
|
});
|
|
189
190
|
}
|
|
190
191
|
|
|
191
|
-
const status = (await api.getSyncRulesStatus(
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
192
|
+
const status = (await api.getSyncRulesStatus(
|
|
193
|
+
service_context.storageEngine.activeBucketStorage,
|
|
194
|
+
apiHandler,
|
|
195
|
+
sync_rules,
|
|
196
|
+
{
|
|
197
|
+
include_content: false,
|
|
198
|
+
check_connection: connectionStatus.connected,
|
|
199
|
+
live_status: false
|
|
200
|
+
}
|
|
201
|
+
))!;
|
|
196
202
|
|
|
197
203
|
if (connectionStatus == null) {
|
|
198
204
|
status.errors.push({ level: 'fatal', message: 'No connection configured' });
|
|
@@ -202,14 +208,4 @@ export const validate = routeDefinition({
|
|
|
202
208
|
}
|
|
203
209
|
});
|
|
204
210
|
|
|
205
|
-
function mapColumnValue(value: SqliteValue) {
|
|
206
|
-
if (typeof value == 'bigint') {
|
|
207
|
-
return Number(value);
|
|
208
|
-
} else if (isJsonValue(value)) {
|
|
209
|
-
return value;
|
|
210
|
-
} else {
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
211
|
export const ADMIN_ROUTES = [executeSql, diagnostics, getSchema, reprocess, validate];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { logger, router, schema } from '@powersync/lib-services-framework';
|
|
1
2
|
import * as t from 'ts-codec';
|
|
2
|
-
import { router, schema } from '@powersync/lib-services-framework';
|
|
3
3
|
|
|
4
|
+
import * as framework from '@powersync/lib-services-framework';
|
|
4
5
|
import * as util from '../../util/util-index.js';
|
|
5
6
|
import { authUser } from '../auth.js';
|
|
6
7
|
import { routeDefinition } from '../router.js';
|
|
@@ -15,13 +16,33 @@ export const writeCheckpoint = routeDefinition({
|
|
|
15
16
|
authorize: authUser,
|
|
16
17
|
validator: schema.createTsCodecValidator(WriteCheckpointRequest, { allowAdditional: true }),
|
|
17
18
|
handler: async (payload) => {
|
|
18
|
-
const
|
|
19
|
-
|
|
19
|
+
const {
|
|
20
|
+
context: { service_context }
|
|
21
|
+
} = payload;
|
|
22
|
+
const apiHandler = service_context.routerEngine!.getAPI();
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
// This old API needs a persisted checkpoint id.
|
|
25
|
+
// Since we don't use LSNs anymore, the only way to get that is to wait.
|
|
26
|
+
const start = Date.now();
|
|
27
|
+
|
|
28
|
+
const head = await apiHandler.getReplicationHead();
|
|
29
|
+
|
|
30
|
+
const timeout = 50_000;
|
|
31
|
+
|
|
32
|
+
logger.info(`Waiting for LSN checkpoint: ${head}`);
|
|
33
|
+
while (Date.now() - start < timeout) {
|
|
34
|
+
const cp = await service_context.storageEngine.activeBucketStorage.getActiveCheckpoint();
|
|
35
|
+
if (!cp.hasSyncRules()) {
|
|
36
|
+
throw new Error('No sync rules available');
|
|
37
|
+
}
|
|
38
|
+
if (cp.lsn && cp.lsn >= head) {
|
|
39
|
+
logger.info(`Got write checkpoint: ${head} : ${cp.checkpoint}`);
|
|
40
|
+
return { checkpoint: cp.checkpoint };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
await new Promise((resolve) => setTimeout(resolve, 30));
|
|
44
|
+
}
|
|
45
|
+
throw new Error('Timeout while waiting for checkpoint');
|
|
25
46
|
}
|
|
26
47
|
});
|
|
27
48
|
|
|
@@ -31,13 +52,32 @@ export const writeCheckpoint2 = routeDefinition({
|
|
|
31
52
|
authorize: authUser,
|
|
32
53
|
validator: schema.createTsCodecValidator(WriteCheckpointRequest, { allowAdditional: true }),
|
|
33
54
|
handler: async (payload) => {
|
|
34
|
-
const { user_id,
|
|
55
|
+
const { user_id, service_context } = payload.context;
|
|
56
|
+
|
|
57
|
+
const apiHandler = service_context.routerEngine!.getAPI();
|
|
58
|
+
|
|
35
59
|
const client_id = payload.params.client_id;
|
|
36
60
|
const full_user_id = util.checkpointUserId(user_id, client_id);
|
|
37
|
-
|
|
38
|
-
const
|
|
61
|
+
|
|
62
|
+
const currentCheckpoint = await apiHandler.getReplicationHead();
|
|
63
|
+
const {
|
|
64
|
+
storageEngine: { activeBucketStorage }
|
|
65
|
+
} = service_context;
|
|
66
|
+
|
|
67
|
+
const activeSyncRules = await activeBucketStorage.getActiveSyncRulesContent();
|
|
68
|
+
if (!activeSyncRules) {
|
|
69
|
+
throw new framework.errors.ValidationError(`Cannot create Write Checkpoint since no sync rules are active.`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
using syncBucketStorage = activeBucketStorage.getInstance(activeSyncRules);
|
|
73
|
+
const writeCheckpoint = await syncBucketStorage.createManagedWriteCheckpoint({
|
|
74
|
+
user_id: full_user_id,
|
|
75
|
+
heads: { '1': currentCheckpoint }
|
|
76
|
+
});
|
|
77
|
+
logger.info(`Write checkpoint 2: ${JSON.stringify({ currentCheckpoint, id: String(full_user_id) })}`);
|
|
78
|
+
|
|
39
79
|
return {
|
|
40
|
-
write_checkpoint: String(
|
|
80
|
+
write_checkpoint: String(writeCheckpoint)
|
|
41
81
|
};
|
|
42
82
|
}
|
|
43
83
|
});
|
|
@@ -12,7 +12,8 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
12
12
|
router.reactiveStream<util.StreamingSyncRequest, any>(SyncRoutes.STREAM, {
|
|
13
13
|
validator: schema.createTsCodecValidator(util.StreamingSyncRequest, { allowAdditional: true }),
|
|
14
14
|
handler: async ({ context, params, responder, observer, initialN, signal: upstreamSignal }) => {
|
|
15
|
-
const {
|
|
15
|
+
const { service_context } = context;
|
|
16
|
+
const { routerEngine } = service_context;
|
|
16
17
|
|
|
17
18
|
// Create our own controller that we can abort directly
|
|
18
19
|
const controller = new AbortController();
|
|
@@ -31,7 +32,7 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
31
32
|
}
|
|
32
33
|
});
|
|
33
34
|
|
|
34
|
-
if (
|
|
35
|
+
if (routerEngine!.closed) {
|
|
35
36
|
responder.onError(
|
|
36
37
|
new errors.JourneyError({
|
|
37
38
|
status: 503,
|
|
@@ -45,9 +46,11 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
45
46
|
|
|
46
47
|
const syncParams = new RequestParameters(context.token_payload!, params.parameters ?? {});
|
|
47
48
|
|
|
48
|
-
const
|
|
49
|
+
const {
|
|
50
|
+
storageEngine: { activeBucketStorage }
|
|
51
|
+
} = service_context;
|
|
49
52
|
// Sanity check before we start the stream
|
|
50
|
-
const cp = await
|
|
53
|
+
const cp = await activeBucketStorage.getActiveCheckpoint();
|
|
51
54
|
if (!cp.hasSyncRules()) {
|
|
52
55
|
responder.onError(
|
|
53
56
|
new errors.JourneyError({
|
|
@@ -60,7 +63,7 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
60
63
|
return;
|
|
61
64
|
}
|
|
62
65
|
|
|
63
|
-
const removeStopHandler =
|
|
66
|
+
const removeStopHandler = routerEngine!.addStopHandler(() => {
|
|
64
67
|
controller.abort();
|
|
65
68
|
});
|
|
66
69
|
|
|
@@ -68,7 +71,8 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
68
71
|
const tracker = new sync.RequestTracker();
|
|
69
72
|
try {
|
|
70
73
|
for await (const data of sync.streamResponse({
|
|
71
|
-
storage,
|
|
74
|
+
storage: activeBucketStorage,
|
|
75
|
+
parseOptions: routerEngine!.getAPI().getParseSyncRulesOptions(),
|
|
72
76
|
params: {
|
|
73
77
|
...params,
|
|
74
78
|
binary_data: true // always true for web sockets
|