@powersync/service-core 0.8.8 → 0.9.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 +31 -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/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/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 +16 -24
- 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/auth-index.ts +0 -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 +31 -31
- 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
|
@@ -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
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import * as t from 'ts-codec';
|
|
2
|
-
import type { FastifyPluginAsync } from 'fastify';
|
|
3
|
-
import * as pgwire from '@powersync/service-jpgwire';
|
|
4
1
|
import { errors, router, schema } from '@powersync/lib-services-framework';
|
|
5
2
|
import { SqlSyncRules, SyncRulesErrors } from '@powersync/service-sync-rules';
|
|
3
|
+
import type { FastifyPluginAsync } from 'fastify';
|
|
4
|
+
import * as t from 'ts-codec';
|
|
6
5
|
|
|
7
|
-
import
|
|
6
|
+
import { RouteAPI } from '../../api/RouteAPI.js';
|
|
8
7
|
import { authApi } from '../auth.js';
|
|
9
8
|
import { routeDefinition } from '../router.js';
|
|
10
9
|
|
|
@@ -39,7 +38,10 @@ export const deploySyncRules = routeDefinition({
|
|
|
39
38
|
plugins: [yamlPlugin],
|
|
40
39
|
validator: schema.createTsCodecValidator(DeploySyncRulesRequest, { allowAdditional: true }),
|
|
41
40
|
handler: async (payload) => {
|
|
42
|
-
|
|
41
|
+
const { service_context } = payload.context;
|
|
42
|
+
const { storageEngine } = service_context;
|
|
43
|
+
|
|
44
|
+
if (service_context.configuration.sync_rules.present) {
|
|
43
45
|
// If sync rules are configured via the config, disable deploy via the API.
|
|
44
46
|
throw new errors.JourneyError({
|
|
45
47
|
status: 422,
|
|
@@ -51,7 +53,12 @@ export const deploySyncRules = routeDefinition({
|
|
|
51
53
|
const content = payload.params.content;
|
|
52
54
|
|
|
53
55
|
try {
|
|
54
|
-
|
|
56
|
+
const apiHandler = service_context.routerEngine!.getAPI();
|
|
57
|
+
SqlSyncRules.fromYaml(payload.params.content, {
|
|
58
|
+
...apiHandler.getParseSyncRulesOptions(),
|
|
59
|
+
// We don't do any schema-level validation at this point
|
|
60
|
+
schema: undefined
|
|
61
|
+
});
|
|
55
62
|
} catch (e) {
|
|
56
63
|
throw new errors.JourneyError({
|
|
57
64
|
status: 422,
|
|
@@ -61,7 +68,7 @@ export const deploySyncRules = routeDefinition({
|
|
|
61
68
|
});
|
|
62
69
|
}
|
|
63
70
|
|
|
64
|
-
const sync_rules = await
|
|
71
|
+
const sync_rules = await storageEngine.activeBucketStorage.updateSyncRules({
|
|
65
72
|
content: content
|
|
66
73
|
});
|
|
67
74
|
|
|
@@ -84,8 +91,10 @@ export const validateSyncRules = routeDefinition({
|
|
|
84
91
|
validator: schema.createTsCodecValidator(ValidateSyncRulesRequest, { allowAdditional: true }),
|
|
85
92
|
handler: async (payload) => {
|
|
86
93
|
const content = payload.params.content;
|
|
94
|
+
const { service_context } = payload.context;
|
|
95
|
+
const apiHandler = service_context.routerEngine!.getAPI();
|
|
87
96
|
|
|
88
|
-
const info = await debugSyncRules(
|
|
97
|
+
const info = await debugSyncRules(apiHandler, content);
|
|
89
98
|
|
|
90
99
|
return replyPrettyJson(info);
|
|
91
100
|
}
|
|
@@ -96,8 +105,12 @@ export const currentSyncRules = routeDefinition({
|
|
|
96
105
|
method: router.HTTPMethod.GET,
|
|
97
106
|
authorize: authApi,
|
|
98
107
|
handler: async (payload) => {
|
|
99
|
-
const
|
|
100
|
-
const
|
|
108
|
+
const { service_context } = payload.context;
|
|
109
|
+
const {
|
|
110
|
+
storageEngine: { activeBucketStorage }
|
|
111
|
+
} = service_context;
|
|
112
|
+
|
|
113
|
+
const sync_rules = await activeBucketStorage.getActiveSyncRulesContent();
|
|
101
114
|
if (!sync_rules) {
|
|
102
115
|
throw new errors.JourneyError({
|
|
103
116
|
status: 422,
|
|
@@ -105,12 +118,12 @@ export const currentSyncRules = routeDefinition({
|
|
|
105
118
|
description: 'No active sync rules'
|
|
106
119
|
});
|
|
107
120
|
}
|
|
108
|
-
const info = await debugSyncRules(payload.context.system.requirePgPool(), sync_rules.sync_rules_content);
|
|
109
|
-
const next = await storage.getNextSyncRulesContent();
|
|
110
121
|
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
122
|
+
const apiHandler = service_context.routerEngine!.getAPI();
|
|
123
|
+
const info = await debugSyncRules(apiHandler, sync_rules.sync_rules_content);
|
|
124
|
+
const next = await activeBucketStorage.getNextSyncRulesContent();
|
|
125
|
+
|
|
126
|
+
const next_info = next ? await debugSyncRules(apiHandler, next.sync_rules_content) : null;
|
|
114
127
|
|
|
115
128
|
const response = {
|
|
116
129
|
current: {
|
|
@@ -140,8 +153,11 @@ export const reprocessSyncRules = routeDefinition({
|
|
|
140
153
|
authorize: authApi,
|
|
141
154
|
validator: schema.createTsCodecValidator(ReprocessSyncRulesRequest),
|
|
142
155
|
handler: async (payload) => {
|
|
143
|
-
const
|
|
144
|
-
|
|
156
|
+
const {
|
|
157
|
+
storageEngine: { activeBucketStorage }
|
|
158
|
+
} = payload.context.service_context;
|
|
159
|
+
const apiHandler = payload.context.service_context.routerEngine!.getAPI();
|
|
160
|
+
const sync_rules = await activeBucketStorage.getActiveSyncRules(apiHandler.getParseSyncRulesOptions());
|
|
145
161
|
if (sync_rules == null) {
|
|
146
162
|
throw new errors.JourneyError({
|
|
147
163
|
status: 422,
|
|
@@ -150,7 +166,7 @@ export const reprocessSyncRules = routeDefinition({
|
|
|
150
166
|
});
|
|
151
167
|
}
|
|
152
168
|
|
|
153
|
-
const new_rules = await
|
|
169
|
+
const new_rules = await activeBucketStorage.updateSyncRules({
|
|
154
170
|
content: sync_rules.sync_rules.content
|
|
155
171
|
});
|
|
156
172
|
return {
|
|
@@ -169,15 +185,15 @@ function replyPrettyJson(payload: any) {
|
|
|
169
185
|
});
|
|
170
186
|
}
|
|
171
187
|
|
|
172
|
-
async function debugSyncRules(
|
|
188
|
+
async function debugSyncRules(apiHandler: RouteAPI, sync_rules: string) {
|
|
173
189
|
try {
|
|
174
|
-
const rules = SqlSyncRules.fromYaml(sync_rules
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
sync_rules: rules
|
|
190
|
+
const rules = SqlSyncRules.fromYaml(sync_rules, {
|
|
191
|
+
...apiHandler.getParseSyncRulesOptions(),
|
|
192
|
+
// No schema-based validation at this point
|
|
193
|
+
schema: undefined
|
|
179
194
|
});
|
|
180
|
-
const
|
|
195
|
+
const source_table_patterns = rules.getSourceTables();
|
|
196
|
+
const resolved_tables = await apiHandler.getDebugTablesInfo(source_table_patterns, rules);
|
|
181
197
|
|
|
182
198
|
return {
|
|
183
199
|
valid: true,
|
|
@@ -8,7 +8,6 @@ import * as util from '../../util/util-index.js';
|
|
|
8
8
|
import { Metrics } from '../../metrics/Metrics.js';
|
|
9
9
|
import { authUser } from '../auth.js';
|
|
10
10
|
import { routeDefinition } from '../router.js';
|
|
11
|
-
import { RequestTracker } from '../../sync/RequestTracker.js';
|
|
12
11
|
|
|
13
12
|
export enum SyncRoutes {
|
|
14
13
|
STREAM = '/sync/stream'
|
|
@@ -20,12 +19,13 @@ export const syncStreamed = routeDefinition({
|
|
|
20
19
|
authorize: authUser,
|
|
21
20
|
validator: schema.createTsCodecValidator(util.StreamingSyncRequest, { allowAdditional: true }),
|
|
22
21
|
handler: async (payload) => {
|
|
23
|
-
const
|
|
22
|
+
const { service_context } = payload.context;
|
|
23
|
+
const { routerEngine, storageEngine } = service_context;
|
|
24
24
|
const headers = payload.request.headers;
|
|
25
25
|
const userAgent = headers['x-user-agent'] ?? headers['user-agent'];
|
|
26
26
|
const clientId = payload.params.client_id;
|
|
27
27
|
|
|
28
|
-
if (
|
|
28
|
+
if (routerEngine!.closed) {
|
|
29
29
|
throw new errors.JourneyError({
|
|
30
30
|
status: 503,
|
|
31
31
|
code: 'SERVICE_UNAVAILABLE',
|
|
@@ -36,9 +36,8 @@ export const syncStreamed = routeDefinition({
|
|
|
36
36
|
const params: util.StreamingSyncRequest = payload.params;
|
|
37
37
|
const syncParams = new RequestParameters(payload.context.token_payload!, payload.params.parameters ?? {});
|
|
38
38
|
|
|
39
|
-
const storage = system.storage;
|
|
40
39
|
// Sanity check before we start the stream
|
|
41
|
-
const cp = await
|
|
40
|
+
const cp = await storageEngine.activeBucketStorage.getActiveCheckpoint();
|
|
42
41
|
if (!cp.hasSyncRules()) {
|
|
43
42
|
throw new errors.JourneyError({
|
|
44
43
|
status: 500,
|
|
@@ -47,14 +46,15 @@ export const syncStreamed = routeDefinition({
|
|
|
47
46
|
});
|
|
48
47
|
}
|
|
49
48
|
const controller = new AbortController();
|
|
50
|
-
const tracker = new RequestTracker();
|
|
49
|
+
const tracker = new sync.RequestTracker();
|
|
51
50
|
try {
|
|
52
51
|
Metrics.getInstance().concurrent_connections.add(1);
|
|
53
52
|
const stream = Readable.from(
|
|
54
53
|
sync.transformToBytesTracked(
|
|
55
54
|
sync.ndjson(
|
|
56
55
|
sync.streamResponse({
|
|
57
|
-
storage,
|
|
56
|
+
storage: storageEngine.activeBucketStorage,
|
|
57
|
+
parseOptions: routerEngine!.getAPI().getParseSyncRulesOptions(),
|
|
58
58
|
params,
|
|
59
59
|
syncParams,
|
|
60
60
|
token: payload.context.token_payload!,
|
|
@@ -67,7 +67,7 @@ export const syncStreamed = routeDefinition({
|
|
|
67
67
|
{ objectMode: false, highWaterMark: 16 * 1024 }
|
|
68
68
|
);
|
|
69
69
|
|
|
70
|
-
const deregister =
|
|
70
|
+
const deregister = routerEngine!.addStopHandler(() => {
|
|
71
71
|
// This error is not currently propagated to the client
|
|
72
72
|
controller.abort();
|
|
73
73
|
stream.destroy(new Error('Shutting down system'));
|
package/src/routes/router.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { router } from '@powersync/lib-services-framework';
|
|
2
2
|
import type { JwtPayload } from '../auth/auth-index.js';
|
|
3
|
-
import
|
|
3
|
+
import { ServiceContext } from '../system/ServiceContext.js';
|
|
4
|
+
import { RouterEngine } from './RouterEngine.js';
|
|
4
5
|
|
|
6
|
+
/**
|
|
7
|
+
* The {@link RouterEngine} must be provided for these routes
|
|
8
|
+
*/
|
|
9
|
+
export type RouterServiceContext = ServiceContext & { routerEngine: RouterEngine };
|
|
5
10
|
/**
|
|
6
11
|
* Common context for routes
|
|
7
12
|
*/
|
|
8
13
|
export type Context = {
|
|
9
14
|
user_id?: string;
|
|
10
|
-
|
|
15
|
+
|
|
16
|
+
service_context: RouterServiceContext;
|
|
11
17
|
|
|
12
18
|
token_payload?: JwtPayload;
|
|
13
19
|
token_errors?: string[];
|
|
@@ -41,7 +47,6 @@ export type RequestEndpointHandlerPayload<
|
|
|
41
47
|
};
|
|
42
48
|
|
|
43
49
|
export type RouteDefinition<I = any, O = any> = RequestEndpoint<I, O>;
|
|
44
|
-
|
|
45
50
|
/**
|
|
46
51
|
* Helper function for making generics work well when defining routes
|
|
47
52
|
*/
|