@powersync/service-core 0.0.0-dev-20240620165206
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/.probes/.gitkeep +0 -0
- package/CHANGELOG.md +82 -0
- package/LICENSE +67 -0
- package/README.md +3 -0
- package/dist/api/api-index.d.ts +2 -0
- package/dist/api/api-index.js +3 -0
- package/dist/api/api-index.js.map +1 -0
- package/dist/api/diagnostics.d.ts +21 -0
- package/dist/api/diagnostics.js +183 -0
- package/dist/api/diagnostics.js.map +1 -0
- package/dist/api/schema.d.ts +5 -0
- package/dist/api/schema.js +88 -0
- package/dist/api/schema.js.map +1 -0
- package/dist/auth/CachedKeyCollector.d.ts +46 -0
- package/dist/auth/CachedKeyCollector.js +116 -0
- package/dist/auth/CachedKeyCollector.js.map +1 -0
- package/dist/auth/CompoundKeyCollector.d.ts +8 -0
- package/dist/auth/CompoundKeyCollector.js +23 -0
- package/dist/auth/CompoundKeyCollector.js.map +1 -0
- package/dist/auth/JwtPayload.d.ts +10 -0
- package/dist/auth/JwtPayload.js +2 -0
- package/dist/auth/JwtPayload.js.map +1 -0
- package/dist/auth/KeyCollector.d.ts +24 -0
- package/dist/auth/KeyCollector.js +2 -0
- package/dist/auth/KeyCollector.js.map +1 -0
- package/dist/auth/KeySpec.d.ts +26 -0
- package/dist/auth/KeySpec.js +49 -0
- package/dist/auth/KeySpec.js.map +1 -0
- package/dist/auth/KeyStore.d.ts +39 -0
- package/dist/auth/KeyStore.js +131 -0
- package/dist/auth/KeyStore.js.map +1 -0
- package/dist/auth/LeakyBucket.d.ts +39 -0
- package/dist/auth/LeakyBucket.js +57 -0
- package/dist/auth/LeakyBucket.js.map +1 -0
- package/dist/auth/RemoteJWKSCollector.d.ts +24 -0
- package/dist/auth/RemoteJWKSCollector.js +106 -0
- package/dist/auth/RemoteJWKSCollector.js.map +1 -0
- package/dist/auth/StaticKeyCollector.d.ts +14 -0
- package/dist/auth/StaticKeyCollector.js +19 -0
- package/dist/auth/StaticKeyCollector.js.map +1 -0
- package/dist/auth/SupabaseKeyCollector.d.ts +22 -0
- package/dist/auth/SupabaseKeyCollector.js +61 -0
- package/dist/auth/SupabaseKeyCollector.js.map +1 -0
- package/dist/auth/auth-index.d.ts +10 -0
- package/dist/auth/auth-index.js +11 -0
- package/dist/auth/auth-index.js.map +1 -0
- package/dist/db/db-index.d.ts +1 -0
- package/dist/db/db-index.js +2 -0
- package/dist/db/db-index.js.map +1 -0
- package/dist/db/mongo.d.ts +29 -0
- package/dist/db/mongo.js +65 -0
- package/dist/db/mongo.js.map +1 -0
- package/dist/entry/cli-entry.d.ts +15 -0
- package/dist/entry/cli-entry.js +36 -0
- package/dist/entry/cli-entry.js.map +1 -0
- package/dist/entry/commands/config-command.d.ts +10 -0
- package/dist/entry/commands/config-command.js +21 -0
- package/dist/entry/commands/config-command.js.map +1 -0
- package/dist/entry/commands/migrate-action.d.ts +2 -0
- package/dist/entry/commands/migrate-action.js +18 -0
- package/dist/entry/commands/migrate-action.js.map +1 -0
- package/dist/entry/commands/start-action.d.ts +3 -0
- package/dist/entry/commands/start-action.js +15 -0
- package/dist/entry/commands/start-action.js.map +1 -0
- package/dist/entry/commands/teardown-action.d.ts +2 -0
- package/dist/entry/commands/teardown-action.js +17 -0
- package/dist/entry/commands/teardown-action.js.map +1 -0
- package/dist/entry/entry-index.d.ts +5 -0
- package/dist/entry/entry-index.js +6 -0
- package/dist/entry/entry-index.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/locks/LockManager.d.ts +10 -0
- package/dist/locks/LockManager.js +7 -0
- package/dist/locks/LockManager.js.map +1 -0
- package/dist/locks/MongoLocks.d.ts +36 -0
- package/dist/locks/MongoLocks.js +81 -0
- package/dist/locks/MongoLocks.js.map +1 -0
- package/dist/locks/locks-index.d.ts +2 -0
- package/dist/locks/locks-index.js +3 -0
- package/dist/locks/locks-index.js.map +1 -0
- package/dist/metrics/Metrics.d.ts +30 -0
- package/dist/metrics/Metrics.js +176 -0
- package/dist/metrics/Metrics.js.map +1 -0
- package/dist/migrations/db/migrations/1684951997326-init.d.ts +3 -0
- package/dist/migrations/db/migrations/1684951997326-init.js +31 -0
- package/dist/migrations/db/migrations/1684951997326-init.js.map +1 -0
- package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.d.ts +2 -0
- package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.js +5 -0
- package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.js.map +1 -0
- package/dist/migrations/db/migrations/1702295701188-sync-rule-state.d.ts +3 -0
- package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js +54 -0
- package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js.map +1 -0
- package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.d.ts +3 -0
- package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js +27 -0
- package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js.map +1 -0
- package/dist/migrations/definitions.d.ts +18 -0
- package/dist/migrations/definitions.js +6 -0
- package/dist/migrations/definitions.js.map +1 -0
- package/dist/migrations/executor.d.ts +16 -0
- package/dist/migrations/executor.js +64 -0
- package/dist/migrations/executor.js.map +1 -0
- package/dist/migrations/migrations-index.d.ts +3 -0
- package/dist/migrations/migrations-index.js +4 -0
- package/dist/migrations/migrations-index.js.map +1 -0
- package/dist/migrations/migrations.d.ts +10 -0
- package/dist/migrations/migrations.js +90 -0
- package/dist/migrations/migrations.js.map +1 -0
- package/dist/migrations/store/migration-store.d.ts +11 -0
- package/dist/migrations/store/migration-store.js +46 -0
- package/dist/migrations/store/migration-store.js.map +1 -0
- package/dist/replication/ErrorRateLimiter.d.ts +17 -0
- package/dist/replication/ErrorRateLimiter.js +43 -0
- package/dist/replication/ErrorRateLimiter.js.map +1 -0
- package/dist/replication/PgRelation.d.ts +16 -0
- package/dist/replication/PgRelation.js +26 -0
- package/dist/replication/PgRelation.js.map +1 -0
- package/dist/replication/WalConnection.d.ts +34 -0
- package/dist/replication/WalConnection.js +190 -0
- package/dist/replication/WalConnection.js.map +1 -0
- package/dist/replication/WalStream.d.ts +57 -0
- package/dist/replication/WalStream.js +515 -0
- package/dist/replication/WalStream.js.map +1 -0
- package/dist/replication/WalStreamManager.d.ts +30 -0
- package/dist/replication/WalStreamManager.js +198 -0
- package/dist/replication/WalStreamManager.js.map +1 -0
- package/dist/replication/WalStreamRunner.d.ts +38 -0
- package/dist/replication/WalStreamRunner.js +155 -0
- package/dist/replication/WalStreamRunner.js.map +1 -0
- package/dist/replication/replication-index.d.ts +7 -0
- package/dist/replication/replication-index.js +8 -0
- package/dist/replication/replication-index.js.map +1 -0
- package/dist/replication/util.d.ts +9 -0
- package/dist/replication/util.js +62 -0
- package/dist/replication/util.js.map +1 -0
- package/dist/routes/auth.d.ts +56 -0
- package/dist/routes/auth.js +182 -0
- package/dist/routes/auth.js.map +1 -0
- package/dist/routes/endpoints/admin.d.ts +1011 -0
- package/dist/routes/endpoints/admin.js +207 -0
- package/dist/routes/endpoints/admin.js.map +1 -0
- package/dist/routes/endpoints/checkpointing.d.ts +76 -0
- package/dist/routes/endpoints/checkpointing.js +36 -0
- package/dist/routes/endpoints/checkpointing.js.map +1 -0
- package/dist/routes/endpoints/dev.d.ts +312 -0
- package/dist/routes/endpoints/dev.js +172 -0
- package/dist/routes/endpoints/dev.js.map +1 -0
- package/dist/routes/endpoints/route-endpoints-index.d.ts +6 -0
- package/dist/routes/endpoints/route-endpoints-index.js +7 -0
- package/dist/routes/endpoints/route-endpoints-index.js.map +1 -0
- package/dist/routes/endpoints/socket-route.d.ts +2 -0
- package/dist/routes/endpoints/socket-route.js +119 -0
- package/dist/routes/endpoints/socket-route.js.map +1 -0
- package/dist/routes/endpoints/sync-rules.d.ts +174 -0
- package/dist/routes/endpoints/sync-rules.js +202 -0
- package/dist/routes/endpoints/sync-rules.js.map +1 -0
- package/dist/routes/endpoints/sync-stream.d.ts +132 -0
- package/dist/routes/endpoints/sync-stream.js +83 -0
- package/dist/routes/endpoints/sync-stream.js.map +1 -0
- package/dist/routes/hooks.d.ts +10 -0
- package/dist/routes/hooks.js +32 -0
- package/dist/routes/hooks.js.map +1 -0
- package/dist/routes/route-register.d.ts +10 -0
- package/dist/routes/route-register.js +87 -0
- package/dist/routes/route-register.js.map +1 -0
- package/dist/routes/router-socket.d.ts +10 -0
- package/dist/routes/router-socket.js +5 -0
- package/dist/routes/router-socket.js.map +1 -0
- package/dist/routes/router.d.ts +26 -0
- package/dist/routes/router.js +7 -0
- package/dist/routes/router.js.map +1 -0
- package/dist/routes/routes-index.d.ts +6 -0
- package/dist/routes/routes-index.js +7 -0
- package/dist/routes/routes-index.js.map +1 -0
- package/dist/runner/teardown.d.ts +2 -0
- package/dist/runner/teardown.js +94 -0
- package/dist/runner/teardown.js.map +1 -0
- package/dist/storage/BucketStorage.d.ts +307 -0
- package/dist/storage/BucketStorage.js +25 -0
- package/dist/storage/BucketStorage.js.map +1 -0
- package/dist/storage/ChecksumCache.d.ts +50 -0
- package/dist/storage/ChecksumCache.js +234 -0
- package/dist/storage/ChecksumCache.js.map +1 -0
- package/dist/storage/MongoBucketStorage.d.ts +52 -0
- package/dist/storage/MongoBucketStorage.js +409 -0
- package/dist/storage/MongoBucketStorage.js.map +1 -0
- package/dist/storage/SourceTable.d.ts +39 -0
- package/dist/storage/SourceTable.js +50 -0
- package/dist/storage/SourceTable.js.map +1 -0
- package/dist/storage/mongo/MongoBucketBatch.d.ts +48 -0
- package/dist/storage/mongo/MongoBucketBatch.js +581 -0
- package/dist/storage/mongo/MongoBucketBatch.js.map +1 -0
- package/dist/storage/mongo/MongoIdSequence.d.ts +12 -0
- package/dist/storage/mongo/MongoIdSequence.js +21 -0
- package/dist/storage/mongo/MongoIdSequence.js.map +1 -0
- package/dist/storage/mongo/MongoPersistedSyncRules.d.ts +9 -0
- package/dist/storage/mongo/MongoPersistedSyncRules.js +9 -0
- package/dist/storage/mongo/MongoPersistedSyncRules.js.map +1 -0
- package/dist/storage/mongo/MongoPersistedSyncRulesContent.d.ts +20 -0
- package/dist/storage/mongo/MongoPersistedSyncRulesContent.js +26 -0
- package/dist/storage/mongo/MongoPersistedSyncRulesContent.js.map +1 -0
- package/dist/storage/mongo/MongoSyncBucketStorage.d.ts +29 -0
- package/dist/storage/mongo/MongoSyncBucketStorage.js +391 -0
- package/dist/storage/mongo/MongoSyncBucketStorage.js.map +1 -0
- package/dist/storage/mongo/MongoSyncRulesLock.d.ts +16 -0
- package/dist/storage/mongo/MongoSyncRulesLock.js +65 -0
- package/dist/storage/mongo/MongoSyncRulesLock.js.map +1 -0
- package/dist/storage/mongo/OperationBatch.d.ts +26 -0
- package/dist/storage/mongo/OperationBatch.js +101 -0
- package/dist/storage/mongo/OperationBatch.js.map +1 -0
- package/dist/storage/mongo/PersistedBatch.d.ts +46 -0
- package/dist/storage/mongo/PersistedBatch.js +213 -0
- package/dist/storage/mongo/PersistedBatch.js.map +1 -0
- package/dist/storage/mongo/db.d.ts +26 -0
- package/dist/storage/mongo/db.js +35 -0
- package/dist/storage/mongo/db.js.map +1 -0
- package/dist/storage/mongo/models.d.ts +140 -0
- package/dist/storage/mongo/models.js +27 -0
- package/dist/storage/mongo/models.js.map +1 -0
- package/dist/storage/mongo/util.d.ts +26 -0
- package/dist/storage/mongo/util.js +81 -0
- package/dist/storage/mongo/util.js.map +1 -0
- package/dist/storage/storage-index.d.ts +14 -0
- package/dist/storage/storage-index.js +15 -0
- package/dist/storage/storage-index.js.map +1 -0
- package/dist/sync/BroadcastIterable.d.ts +38 -0
- package/dist/sync/BroadcastIterable.js +153 -0
- package/dist/sync/BroadcastIterable.js.map +1 -0
- package/dist/sync/LastValueSink.d.ts +25 -0
- package/dist/sync/LastValueSink.js +84 -0
- package/dist/sync/LastValueSink.js.map +1 -0
- package/dist/sync/merge.d.ts +39 -0
- package/dist/sync/merge.js +175 -0
- package/dist/sync/merge.js.map +1 -0
- package/dist/sync/safeRace.d.ts +1 -0
- package/dist/sync/safeRace.js +91 -0
- package/dist/sync/safeRace.js.map +1 -0
- package/dist/sync/sync-index.d.ts +6 -0
- package/dist/sync/sync-index.js +7 -0
- package/dist/sync/sync-index.js.map +1 -0
- package/dist/sync/sync.d.ts +18 -0
- package/dist/sync/sync.js +259 -0
- package/dist/sync/sync.js.map +1 -0
- package/dist/sync/util.d.ts +26 -0
- package/dist/sync/util.js +73 -0
- package/dist/sync/util.js.map +1 -0
- package/dist/system/CorePowerSyncSystem.d.ts +23 -0
- package/dist/system/CorePowerSyncSystem.js +52 -0
- package/dist/system/CorePowerSyncSystem.js.map +1 -0
- package/dist/system/system-index.d.ts +1 -0
- package/dist/system/system-index.js +2 -0
- package/dist/system/system-index.js.map +1 -0
- package/dist/util/Mutex.d.ts +47 -0
- package/dist/util/Mutex.js +132 -0
- package/dist/util/Mutex.js.map +1 -0
- package/dist/util/PgManager.d.ts +24 -0
- package/dist/util/PgManager.js +55 -0
- package/dist/util/PgManager.js.map +1 -0
- package/dist/util/alerting.d.ts +2 -0
- package/dist/util/alerting.js +8 -0
- package/dist/util/alerting.js.map +1 -0
- package/dist/util/config/collectors/config-collector.d.ts +29 -0
- package/dist/util/config/collectors/config-collector.js +116 -0
- package/dist/util/config/collectors/config-collector.js.map +1 -0
- package/dist/util/config/collectors/impl/base64-config-collector.d.ts +6 -0
- package/dist/util/config/collectors/impl/base64-config-collector.js +15 -0
- package/dist/util/config/collectors/impl/base64-config-collector.js.map +1 -0
- package/dist/util/config/collectors/impl/fallback-config-collector.d.ts +11 -0
- package/dist/util/config/collectors/impl/fallback-config-collector.js +19 -0
- package/dist/util/config/collectors/impl/fallback-config-collector.js.map +1 -0
- package/dist/util/config/collectors/impl/filesystem-config-collector.d.ts +6 -0
- package/dist/util/config/collectors/impl/filesystem-config-collector.js +37 -0
- package/dist/util/config/collectors/impl/filesystem-config-collector.js.map +1 -0
- package/dist/util/config/compound-config-collector.d.ts +32 -0
- package/dist/util/config/compound-config-collector.js +130 -0
- package/dist/util/config/compound-config-collector.js.map +1 -0
- package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.d.ts +7 -0
- package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js +17 -0
- package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js.map +1 -0
- package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.d.ts +7 -0
- package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js +21 -0
- package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js.map +1 -0
- package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.d.ts +7 -0
- package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.js +17 -0
- package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.js.map +1 -0
- package/dist/util/config/sync-rules/sync-collector.d.ts +6 -0
- package/dist/util/config/sync-rules/sync-collector.js +3 -0
- package/dist/util/config/sync-rules/sync-collector.js.map +1 -0
- package/dist/util/config/types.d.ts +57 -0
- package/dist/util/config/types.js +7 -0
- package/dist/util/config/types.js.map +1 -0
- package/dist/util/config.d.ts +7 -0
- package/dist/util/config.js +35 -0
- package/dist/util/config.js.map +1 -0
- package/dist/util/env.d.ts +9 -0
- package/dist/util/env.js +26 -0
- package/dist/util/env.js.map +1 -0
- package/dist/util/memory-tracking.d.ts +7 -0
- package/dist/util/memory-tracking.js +58 -0
- package/dist/util/memory-tracking.js.map +1 -0
- package/dist/util/migration_lib.d.ts +11 -0
- package/dist/util/migration_lib.js +64 -0
- package/dist/util/migration_lib.js.map +1 -0
- package/dist/util/pgwire_utils.d.ts +24 -0
- package/dist/util/pgwire_utils.js +117 -0
- package/dist/util/pgwire_utils.js.map +1 -0
- package/dist/util/populate_test_data.d.ts +8 -0
- package/dist/util/populate_test_data.js +65 -0
- package/dist/util/populate_test_data.js.map +1 -0
- package/dist/util/protocol-types.d.ts +182 -0
- package/dist/util/protocol-types.js +42 -0
- package/dist/util/protocol-types.js.map +1 -0
- package/dist/util/secs.d.ts +2 -0
- package/dist/util/secs.js +49 -0
- package/dist/util/secs.js.map +1 -0
- package/dist/util/util-index.d.ts +22 -0
- package/dist/util/util-index.js +23 -0
- package/dist/util/util-index.js.map +1 -0
- package/dist/util/utils.d.ts +17 -0
- package/dist/util/utils.js +92 -0
- package/dist/util/utils.js.map +1 -0
- package/package.json +59 -0
- package/src/api/api-index.ts +2 -0
- package/src/api/diagnostics.ts +221 -0
- package/src/api/schema.ts +99 -0
- package/src/auth/CachedKeyCollector.ts +132 -0
- package/src/auth/CompoundKeyCollector.ts +33 -0
- package/src/auth/JwtPayload.ts +11 -0
- package/src/auth/KeyCollector.ts +27 -0
- package/src/auth/KeySpec.ts +67 -0
- package/src/auth/KeyStore.ts +156 -0
- package/src/auth/LeakyBucket.ts +66 -0
- package/src/auth/RemoteJWKSCollector.ts +130 -0
- package/src/auth/StaticKeyCollector.ts +21 -0
- package/src/auth/SupabaseKeyCollector.ts +67 -0
- package/src/auth/auth-index.ts +10 -0
- package/src/db/db-index.ts +1 -0
- package/src/db/mongo.ts +72 -0
- package/src/entry/cli-entry.ts +40 -0
- package/src/entry/commands/config-command.ts +36 -0
- package/src/entry/commands/migrate-action.ts +25 -0
- package/src/entry/commands/start-action.ts +24 -0
- package/src/entry/commands/teardown-action.ts +23 -0
- package/src/entry/entry-index.ts +5 -0
- package/src/index.ts +40 -0
- package/src/locks/LockManager.ts +16 -0
- package/src/locks/MongoLocks.ts +142 -0
- package/src/locks/locks-index.ts +2 -0
- package/src/metrics/Metrics.ts +265 -0
- package/src/migrations/db/migrations/1684951997326-init.ts +33 -0
- package/src/migrations/db/migrations/1688556755264-initial-sync-rules.ts +5 -0
- package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +99 -0
- package/src/migrations/db/migrations/1711543888062-write-checkpoint-index.ts +32 -0
- package/src/migrations/definitions.ts +21 -0
- package/src/migrations/executor.ts +87 -0
- package/src/migrations/migrations-index.ts +3 -0
- package/src/migrations/migrations.ts +118 -0
- package/src/migrations/store/migration-store.ts +63 -0
- package/src/replication/ErrorRateLimiter.ts +50 -0
- package/src/replication/PgRelation.ts +42 -0
- package/src/replication/WalConnection.ts +227 -0
- package/src/replication/WalStream.ts +624 -0
- package/src/replication/WalStreamManager.ts +213 -0
- package/src/replication/WalStreamRunner.ts +180 -0
- package/src/replication/replication-index.ts +7 -0
- package/src/replication/util.ts +76 -0
- package/src/routes/auth.ts +215 -0
- package/src/routes/endpoints/admin.ts +237 -0
- package/src/routes/endpoints/checkpointing.ts +41 -0
- package/src/routes/endpoints/dev.ts +199 -0
- package/src/routes/endpoints/route-endpoints-index.ts +6 -0
- package/src/routes/endpoints/socket-route.ts +135 -0
- package/src/routes/endpoints/sync-rules.ts +227 -0
- package/src/routes/endpoints/sync-stream.ts +101 -0
- package/src/routes/hooks.ts +46 -0
- package/src/routes/route-register.ts +104 -0
- package/src/routes/router-socket.ts +13 -0
- package/src/routes/router.ts +46 -0
- package/src/routes/routes-index.ts +6 -0
- package/src/runner/teardown.ts +108 -0
- package/src/storage/BucketStorage.ts +396 -0
- package/src/storage/ChecksumCache.ts +294 -0
- package/src/storage/MongoBucketStorage.ts +519 -0
- package/src/storage/SourceTable.ts +60 -0
- package/src/storage/mongo/MongoBucketBatch.ts +752 -0
- package/src/storage/mongo/MongoIdSequence.ts +24 -0
- package/src/storage/mongo/MongoPersistedSyncRules.ts +16 -0
- package/src/storage/mongo/MongoPersistedSyncRulesContent.ts +47 -0
- package/src/storage/mongo/MongoSyncBucketStorage.ts +533 -0
- package/src/storage/mongo/MongoSyncRulesLock.ts +81 -0
- package/src/storage/mongo/OperationBatch.ts +115 -0
- package/src/storage/mongo/PersistedBatch.ts +268 -0
- package/src/storage/mongo/db.ts +73 -0
- package/src/storage/mongo/models.ts +162 -0
- package/src/storage/mongo/util.ts +88 -0
- package/src/storage/storage-index.ts +15 -0
- package/src/sync/BroadcastIterable.ts +161 -0
- package/src/sync/LastValueSink.ts +100 -0
- package/src/sync/merge.ts +200 -0
- package/src/sync/safeRace.ts +99 -0
- package/src/sync/sync-index.ts +6 -0
- package/src/sync/sync.ts +319 -0
- package/src/sync/util.ts +98 -0
- package/src/system/CorePowerSyncSystem.ts +64 -0
- package/src/system/system-index.ts +1 -0
- package/src/util/Mutex.ts +159 -0
- package/src/util/PgManager.ts +64 -0
- package/src/util/alerting.ts +9 -0
- package/src/util/config/collectors/config-collector.ts +143 -0
- package/src/util/config/collectors/impl/base64-config-collector.ts +18 -0
- package/src/util/config/collectors/impl/fallback-config-collector.ts +22 -0
- package/src/util/config/collectors/impl/filesystem-config-collector.ts +43 -0
- package/src/util/config/compound-config-collector.ts +176 -0
- package/src/util/config/sync-rules/impl/base64-sync-rules-collector.ts +21 -0
- package/src/util/config/sync-rules/impl/filesystem-sync-rules-collector.ts +26 -0
- package/src/util/config/sync-rules/impl/inline-sync-rules-collector.ts +21 -0
- package/src/util/config/sync-rules/sync-collector.ts +8 -0
- package/src/util/config/types.ts +66 -0
- package/src/util/config.ts +39 -0
- package/src/util/env.ts +30 -0
- package/src/util/memory-tracking.ts +67 -0
- package/src/util/migration_lib.ts +79 -0
- package/src/util/pgwire_utils.ts +139 -0
- package/src/util/populate_test_data.ts +78 -0
- package/src/util/protocol-types.ts +228 -0
- package/src/util/secs.ts +54 -0
- package/src/util/util-index.ts +25 -0
- package/src/util/utils.ts +122 -0
- package/test/src/__snapshots__/pg_test.test.ts.snap +256 -0
- package/test/src/__snapshots__/sync.test.ts.snap +247 -0
- package/test/src/auth.test.ts +342 -0
- package/test/src/broadcast_iterable.test.ts +156 -0
- package/test/src/checksum_cache.test.ts +436 -0
- package/test/src/data_storage.test.ts +1176 -0
- package/test/src/env.ts +8 -0
- package/test/src/large_batch.test.ts +194 -0
- package/test/src/merge_iterable.test.ts +355 -0
- package/test/src/pg_test.test.ts +450 -0
- package/test/src/schema_changes.test.ts +545 -0
- package/test/src/setup.ts +7 -0
- package/test/src/slow_tests.test.ts +257 -0
- package/test/src/sql_functions.test.ts +254 -0
- package/test/src/sql_operators.test.ts +132 -0
- package/test/src/sync.test.ts +293 -0
- package/test/src/sync_rules.test.ts +1053 -0
- package/test/src/util.ts +76 -0
- package/test/src/validation.test.ts +63 -0
- package/test/src/wal_stream.test.ts +319 -0
- package/test/src/wal_stream_utils.ts +147 -0
- package/test/tsconfig.json +20 -0
- package/tsconfig.json +31 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Source: https://github.com/ReactiveX/IxJS/blob/ff1cef03d91a4a7c527fa8c8dbdac025a652c236/src/util/safeRace.ts
|
|
2
|
+
/*
|
|
3
|
+
This is free and unencumbered software released into the public domain.
|
|
4
|
+
|
|
5
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
6
|
+
distribute this software, either in source code form or as a compiled
|
|
7
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
|
8
|
+
means.
|
|
9
|
+
|
|
10
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
|
11
|
+
of this software dedicate any and all copyright interest in the
|
|
12
|
+
software to the public domain. We make this dedication for the benefit
|
|
13
|
+
of the public at large and to the detriment of our heirs and
|
|
14
|
+
successors. We intend this dedication to be an overt act of
|
|
15
|
+
relinquishment in perpetuity of all present and future rights to this
|
|
16
|
+
software under copyright law.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
19
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
20
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
21
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
22
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
23
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
24
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
|
25
|
+
|
|
26
|
+
For more information, please refer to <http://unlicense.org/>
|
|
27
|
+
*/
|
|
28
|
+
// see: https://github.com/nodejs/node/issues/17469#issuecomment-685216777
|
|
29
|
+
// see: https://github.com/ReactiveX/IxJS/pull/323
|
|
30
|
+
function isPrimitive(value) {
|
|
31
|
+
return value === null || (typeof value !== 'object' && typeof value !== 'function');
|
|
32
|
+
}
|
|
33
|
+
// Keys are the values passed to race, values are a record of data containing a
|
|
34
|
+
// set of deferreds and whether the value has settled.
|
|
35
|
+
const wm = new WeakMap();
|
|
36
|
+
export function safeRace(contenders) {
|
|
37
|
+
let deferred;
|
|
38
|
+
const result = new Promise((resolve, reject) => {
|
|
39
|
+
deferred = { resolve, reject };
|
|
40
|
+
for (const contender of contenders) {
|
|
41
|
+
if (isPrimitive(contender)) {
|
|
42
|
+
// If the contender is a primitive, attempting to use it as a key in the
|
|
43
|
+
// weakmap would throw an error. Luckily, it is safe to call
|
|
44
|
+
// `Promise.resolve(contender).then` on a primitive value multiple times
|
|
45
|
+
// because the promise fulfills immediately.
|
|
46
|
+
Promise.resolve(contender).then(resolve, reject);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
let record = wm.get(contender);
|
|
50
|
+
if (record === undefined) {
|
|
51
|
+
record = { deferreds: new Set([deferred]), settled: false };
|
|
52
|
+
wm.set(contender, record);
|
|
53
|
+
// This call to `then` happens once for the lifetime of the value.
|
|
54
|
+
Promise.resolve(contender).then((value) => {
|
|
55
|
+
// eslint-disable-next-line no-shadow
|
|
56
|
+
for (const { resolve } of record.deferreds) {
|
|
57
|
+
resolve(value);
|
|
58
|
+
}
|
|
59
|
+
record.deferreds.clear();
|
|
60
|
+
record.settled = true;
|
|
61
|
+
}, (err) => {
|
|
62
|
+
// eslint-disable-next-line no-shadow
|
|
63
|
+
for (const { reject } of record.deferreds) {
|
|
64
|
+
reject(err);
|
|
65
|
+
}
|
|
66
|
+
record.deferreds.clear();
|
|
67
|
+
record.settled = true;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
else if (record.settled) {
|
|
71
|
+
// If the value has settled, it is safe to call
|
|
72
|
+
// `Promise.resolve(contender).then` on it.
|
|
73
|
+
Promise.resolve(contender).then(resolve, reject);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
record.deferreds.add(deferred);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
// The finally callback executes when any value settles, preventing any of
|
|
81
|
+
// the unresolved values from retaining a reference to the resolved value.
|
|
82
|
+
return result.finally(() => {
|
|
83
|
+
for (const contender of contenders) {
|
|
84
|
+
if (!isPrimitive(contender)) {
|
|
85
|
+
const record = wm.get(contender);
|
|
86
|
+
record.deferreds.delete(deferred);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=safeRace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeRace.js","sourceRoot":"","sources":["../../src/sync/safeRace.ts"],"names":[],"mappings":"AAAA,+GAA+G;AAE/G;;;;;;;;;;;;;;;;;;;;;;;;;EAyBE;AAEF,0EAA0E;AAC1E,kDAAkD;AAElD,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC;AACtF,CAAC;AAED,+EAA+E;AAC/E,sDAAsD;AACtD,MAAM,EAAE,GAAG,IAAI,OAAO,EAAY,CAAC;AACnC,MAAM,UAAU,QAAQ,CAAI,UAAwB;IAClD,IAAI,QAAa,CAAC;IAClB,MAAM,MAAM,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAChD,QAAQ,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAC/B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;YAClC,IAAI,WAAW,CAAC,SAAS,CAAC,EAAE;gBAC1B,wEAAwE;gBACxE,4DAA4D;gBAC5D,wEAAwE;gBACxE,4CAA4C;gBAC5C,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBACjD,SAAS;aACV;YAED,IAAI,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC/B,IAAI,MAAM,KAAK,SAAS,EAAE;gBACxB,MAAM,GAAG,EAAE,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;gBAC5D,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBAC1B,kEAAkE;gBAClE,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAC7B,CAAC,KAAK,EAAE,EAAE;oBACR,qCAAqC;oBACrC,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,MAAM,CAAC,SAAS,EAAE;wBAC1C,OAAO,CAAC,KAAK,CAAC,CAAC;qBAChB;oBAED,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;oBACzB,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;gBACxB,CAAC,EACD,CAAC,GAAG,EAAE,EAAE;oBACN,qCAAqC;oBACrC,KAAK,MAAM,EAAE,MAAM,EAAE,IAAI,MAAM,CAAC,SAAS,EAAE;wBACzC,MAAM,CAAC,GAAG,CAAC,CAAC;qBACb;oBAED,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;oBACzB,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;gBACxB,CAAC,CACF,CAAC;aACH;iBAAM,IAAI,MAAM,CAAC,OAAO,EAAE;gBACzB,+CAA+C;gBAC/C,2CAA2C;gBAC3C,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;aAClD;iBAAM;gBACL,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;aAChC;SACF;IACH,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,0EAA0E;IAC1E,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE;QACzB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;YAClC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE;gBAC3B,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBACjC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;aACnC;SACF;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-index.js","sourceRoot":"","sources":["../../src/sync/sync-index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { SyncParameters } from '@powersync/service-sync-rules';
|
|
3
|
+
import * as auth from '../auth/auth-index.js';
|
|
4
|
+
import * as storage from '../storage/storage-index.js';
|
|
5
|
+
import * as util from '../util/util-index.js';
|
|
6
|
+
import { TokenStreamOptions } from './util.js';
|
|
7
|
+
export interface SyncStreamParameters {
|
|
8
|
+
storage: storage.BucketStorageFactory;
|
|
9
|
+
params: util.StreamingSyncRequest;
|
|
10
|
+
syncParams: SyncParameters;
|
|
11
|
+
token: auth.JwtPayload;
|
|
12
|
+
/**
|
|
13
|
+
* If this signal is aborted, the stream response ends as soon as possible, without error.
|
|
14
|
+
*/
|
|
15
|
+
signal?: AbortSignal;
|
|
16
|
+
tokenStreamOptions?: Partial<TokenStreamOptions>;
|
|
17
|
+
}
|
|
18
|
+
export declare function streamResponse(options: SyncStreamParameters): AsyncIterable<util.StreamingSyncLine | string | null>;
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { JSONBig, JsonContainer } from '@powersync/service-jsonbig';
|
|
2
|
+
import { Semaphore } from 'async-mutex';
|
|
3
|
+
import { AbortError } from 'ix/aborterror.js';
|
|
4
|
+
import * as util from '../util/util-index.js';
|
|
5
|
+
import { mergeAsyncIterables } from './merge.js';
|
|
6
|
+
import { tokenStream } from './util.js';
|
|
7
|
+
import { Metrics } from '../metrics/Metrics.js';
|
|
8
|
+
import { logger } from '@powersync/lib-services-framework';
|
|
9
|
+
/**
|
|
10
|
+
* Maximum number of connections actively fetching data.
|
|
11
|
+
*/
|
|
12
|
+
const MAX_ACTIVE_CONNECTIONS = 10;
|
|
13
|
+
const syncSemaphore = new Semaphore(MAX_ACTIVE_CONNECTIONS);
|
|
14
|
+
export async function* streamResponse(options) {
|
|
15
|
+
const { storage, params, syncParams, token, tokenStreamOptions, signal } = options;
|
|
16
|
+
// We also need to be able to abort, so we create our own controller.
|
|
17
|
+
const controller = new AbortController();
|
|
18
|
+
if (signal) {
|
|
19
|
+
signal.addEventListener('abort', () => {
|
|
20
|
+
controller.abort();
|
|
21
|
+
}, { once: true });
|
|
22
|
+
if (signal.aborted) {
|
|
23
|
+
controller.abort();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const ki = tokenStream(token, controller.signal, tokenStreamOptions);
|
|
27
|
+
const stream = streamResponseInner(storage, params, syncParams, controller.signal);
|
|
28
|
+
// Merge the two streams, and abort as soon as one of the streams end.
|
|
29
|
+
const merged = mergeAsyncIterables([stream, ki], controller.signal);
|
|
30
|
+
try {
|
|
31
|
+
yield* merged;
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
if (e instanceof AbortError) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
throw e;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
// This ensures all the underlying streams are aborted as soon as possible if the
|
|
43
|
+
// parent loop stops.
|
|
44
|
+
controller.abort();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function* streamResponseInner(storage, params, syncParams, signal) {
|
|
48
|
+
// Bucket state of bucket id -> op_id.
|
|
49
|
+
// This starts with the state from the client. May contain buckets that the user do not have access to (anymore).
|
|
50
|
+
let dataBuckets = new Map();
|
|
51
|
+
let lastChecksums = null;
|
|
52
|
+
let lastWriteCheckpoint = null;
|
|
53
|
+
const { raw_data, binary_data } = params;
|
|
54
|
+
if (params.buckets) {
|
|
55
|
+
for (let { name, after: start } of params.buckets) {
|
|
56
|
+
dataBuckets.set(name, start);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const stream = storage.watchWriteCheckpoint(syncParams.token_parameters.user_id, signal);
|
|
60
|
+
for await (const next of stream) {
|
|
61
|
+
const { base, writeCheckpoint } = next;
|
|
62
|
+
const checkpoint = base.checkpoint;
|
|
63
|
+
const storage = await base.getBucketStorage();
|
|
64
|
+
if (storage == null) {
|
|
65
|
+
// Sync rules deleted in the meantime - try again with the next checkpoint.
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const sync_rules = storage.sync_rules;
|
|
69
|
+
const allBuckets = await sync_rules.queryBucketIds({
|
|
70
|
+
getParameterSets(lookups) {
|
|
71
|
+
return storage.getParameterSets(checkpoint, lookups);
|
|
72
|
+
},
|
|
73
|
+
parameters: syncParams
|
|
74
|
+
});
|
|
75
|
+
if (allBuckets.length > 1000) {
|
|
76
|
+
// TODO: Limit number of buckets even before we get to this point
|
|
77
|
+
throw new Error(`Too many buckets: ${allBuckets.length}`);
|
|
78
|
+
}
|
|
79
|
+
let dataBucketsNew = new Map();
|
|
80
|
+
for (let bucket of allBuckets) {
|
|
81
|
+
dataBucketsNew.set(bucket, dataBuckets.get(bucket) ?? '0');
|
|
82
|
+
}
|
|
83
|
+
dataBuckets = dataBucketsNew;
|
|
84
|
+
const bucketList = [...dataBuckets.keys()];
|
|
85
|
+
const checksumMap = await storage.getChecksums(checkpoint, bucketList);
|
|
86
|
+
// Subset of buckets for which there may be new data in this batch.
|
|
87
|
+
let bucketsToFetch;
|
|
88
|
+
if (lastChecksums) {
|
|
89
|
+
const diff = util.checksumsDiff(lastChecksums, checksumMap);
|
|
90
|
+
if (lastWriteCheckpoint == writeCheckpoint &&
|
|
91
|
+
diff.removedBuckets.length == 0 &&
|
|
92
|
+
diff.updatedBuckets.length == 0) {
|
|
93
|
+
// No changes - don't send anything to the client
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
bucketsToFetch = diff.updatedBuckets.map((c) => c.bucket);
|
|
97
|
+
let message = `Updated checkpoint: ${checkpoint} | write: ${writeCheckpoint} | `;
|
|
98
|
+
message += `buckets: ${allBuckets.length} | `;
|
|
99
|
+
message += `updated: ${limitedBuckets(diff.updatedBuckets, 20)} | `;
|
|
100
|
+
message += `removed: ${limitedBuckets(diff.removedBuckets, 20)} | `;
|
|
101
|
+
logger.info(message);
|
|
102
|
+
const checksum_line = {
|
|
103
|
+
checkpoint_diff: {
|
|
104
|
+
last_op_id: checkpoint,
|
|
105
|
+
write_checkpoint: writeCheckpoint ? String(writeCheckpoint) : undefined,
|
|
106
|
+
removed_buckets: diff.removedBuckets,
|
|
107
|
+
updated_buckets: diff.updatedBuckets
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
yield checksum_line;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
let message = `New checkpoint: ${checkpoint} | write: ${writeCheckpoint} | `;
|
|
114
|
+
message += `buckets: ${allBuckets.length} ${limitedBuckets(allBuckets, 20)}`;
|
|
115
|
+
logger.info(message);
|
|
116
|
+
bucketsToFetch = allBuckets;
|
|
117
|
+
const checksum_line = {
|
|
118
|
+
checkpoint: {
|
|
119
|
+
last_op_id: checkpoint,
|
|
120
|
+
write_checkpoint: writeCheckpoint ? String(writeCheckpoint) : undefined,
|
|
121
|
+
buckets: [...checksumMap.values()]
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
yield checksum_line;
|
|
125
|
+
}
|
|
126
|
+
lastChecksums = checksumMap;
|
|
127
|
+
lastWriteCheckpoint = writeCheckpoint;
|
|
128
|
+
// This incrementally updates dataBuckets with each individual bucket position.
|
|
129
|
+
// At the end of this, we can be sure that all buckets have data up to the checkpoint.
|
|
130
|
+
yield* bucketDataInBatches({ storage, checkpoint, bucketsToFetch, dataBuckets, raw_data, binary_data, signal });
|
|
131
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async function* bucketDataInBatches(request) {
|
|
135
|
+
let isDone = false;
|
|
136
|
+
while (!request.signal.aborted && !isDone) {
|
|
137
|
+
// The code below is functionally the same as this for-await loop below.
|
|
138
|
+
// However, the for-await loop appears to have a memory leak, so we avoid it.
|
|
139
|
+
// for await (const { done, data } of bucketDataBatch(storage, checkpoint, dataBuckets, raw_data, signal)) {
|
|
140
|
+
// yield data;
|
|
141
|
+
// if (done) {
|
|
142
|
+
// isDone = true;
|
|
143
|
+
// }
|
|
144
|
+
// break;
|
|
145
|
+
// }
|
|
146
|
+
const iter = bucketDataBatch(request);
|
|
147
|
+
try {
|
|
148
|
+
while (true) {
|
|
149
|
+
const { value, done: iterDone } = await iter.next();
|
|
150
|
+
if (iterDone) {
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
const { done, data } = value;
|
|
155
|
+
yield data;
|
|
156
|
+
if (done) {
|
|
157
|
+
isDone = true;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
await iter.return();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Extracted as a separate internal function just to avoid memory leaks.
|
|
169
|
+
*/
|
|
170
|
+
async function* bucketDataBatch(request) {
|
|
171
|
+
const { storage, checkpoint, bucketsToFetch, dataBuckets, raw_data, binary_data, signal } = request;
|
|
172
|
+
const [_, release] = await syncSemaphore.acquire();
|
|
173
|
+
try {
|
|
174
|
+
// Optimization: Only fetch buckets for which the checksums have changed since the last checkpoint
|
|
175
|
+
// For the first batch, this will be all buckets.
|
|
176
|
+
const filteredBuckets = new Map(bucketsToFetch.map((bucket) => [bucket, dataBuckets.get(bucket)]));
|
|
177
|
+
const data = storage.getBucketDataBatch(checkpoint, filteredBuckets);
|
|
178
|
+
let has_more = false;
|
|
179
|
+
for await (let r of data) {
|
|
180
|
+
if (signal.aborted) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (r.has_more) {
|
|
184
|
+
has_more = true;
|
|
185
|
+
}
|
|
186
|
+
if (r.data.length == 0) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
logger.debug(`Sending data for ${r.bucket}`);
|
|
190
|
+
let send_data;
|
|
191
|
+
if (binary_data) {
|
|
192
|
+
// Send the object as is, will most likely be encoded as a BSON document
|
|
193
|
+
send_data = { data: r };
|
|
194
|
+
}
|
|
195
|
+
else if (raw_data) {
|
|
196
|
+
// Data is a raw string - we can use the more efficient JSON.stringify.
|
|
197
|
+
const response = {
|
|
198
|
+
data: r
|
|
199
|
+
};
|
|
200
|
+
send_data = JSON.stringify(response);
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
// We need to preserve the embedded data exactly, so this uses a JsonContainer
|
|
204
|
+
// and JSONBig to stringify.
|
|
205
|
+
const response = {
|
|
206
|
+
data: transformLegacyResponse(r)
|
|
207
|
+
};
|
|
208
|
+
send_data = JSONBig.stringify(response);
|
|
209
|
+
}
|
|
210
|
+
yield { data: send_data, done: false };
|
|
211
|
+
if (send_data.length > 50000) {
|
|
212
|
+
// IMPORTANT: This does not affect the output stream, but is used to flush
|
|
213
|
+
// iterator memory in case if large data sent.
|
|
214
|
+
yield { data: null, done: false };
|
|
215
|
+
}
|
|
216
|
+
Metrics.getInstance().operations_synced_total.add(r.data.length);
|
|
217
|
+
dataBuckets.set(r.bucket, r.next_after);
|
|
218
|
+
}
|
|
219
|
+
if (!has_more) {
|
|
220
|
+
const line = {
|
|
221
|
+
checkpoint_complete: {
|
|
222
|
+
last_op_id: checkpoint
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
yield { data: line, done: true };
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
release();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function transformLegacyResponse(bucketData) {
|
|
233
|
+
return {
|
|
234
|
+
...bucketData,
|
|
235
|
+
data: bucketData.data.map((entry) => {
|
|
236
|
+
return {
|
|
237
|
+
...entry,
|
|
238
|
+
data: entry.data == null ? null : new JsonContainer(entry.data),
|
|
239
|
+
checksum: BigInt(entry.checksum)
|
|
240
|
+
};
|
|
241
|
+
})
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function limitedBuckets(buckets, limit) {
|
|
245
|
+
buckets = buckets.map((b) => {
|
|
246
|
+
if (typeof b != 'string') {
|
|
247
|
+
return b.bucket;
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
return b;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
if (buckets.length <= limit) {
|
|
254
|
+
return JSON.stringify(buckets);
|
|
255
|
+
}
|
|
256
|
+
const limited = buckets.slice(0, limit);
|
|
257
|
+
return `${JSON.stringify(limited)}...`;
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/sync/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
3
|
+
import * as util from '../util/util-index.js';
|
|
4
|
+
export type TokenStreamOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* Adds periodic keepalive events
|
|
7
|
+
*/
|
|
8
|
+
keep_alive: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Warn before the token is going to expire
|
|
11
|
+
*/
|
|
12
|
+
expire_warning_period: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* An iterator that periodically yields token and optionally keepalive events, and returns once the
|
|
16
|
+
* provided token expiry is reached.
|
|
17
|
+
*
|
|
18
|
+
* @param token exp is expiry as a unix timestamp (seconds)
|
|
19
|
+
* @param signal abort the iterator with this
|
|
20
|
+
* @param options configure keepalive and expire warnings
|
|
21
|
+
*/
|
|
22
|
+
export declare function tokenStream(token: {
|
|
23
|
+
exp: number;
|
|
24
|
+
}, signal: AbortSignal, options?: Partial<TokenStreamOptions>): AsyncGenerator<util.StreamingSyncKeepalive>;
|
|
25
|
+
export declare function ndjson(iterator: AsyncIterable<string | null | Record<string, any>>): AsyncGenerator<string>;
|
|
26
|
+
export declare function transformToBytesTracked(iterator: AsyncIterable<string>): AsyncGenerator<Buffer>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as timers from 'timers/promises';
|
|
2
|
+
import { Metrics } from '../metrics/Metrics.js';
|
|
3
|
+
const KEEPALIVE_INTERVAL = 20000;
|
|
4
|
+
const DEFAULT_TOKEN_STREAM_OPTIONS = {
|
|
5
|
+
keep_alive: true,
|
|
6
|
+
expire_warning_period: 20000
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* An iterator that periodically yields token and optionally keepalive events, and returns once the
|
|
10
|
+
* provided token expiry is reached.
|
|
11
|
+
*
|
|
12
|
+
* @param token exp is expiry as a unix timestamp (seconds)
|
|
13
|
+
* @param signal abort the iterator with this
|
|
14
|
+
* @param options configure keepalive and expire warnings
|
|
15
|
+
*/
|
|
16
|
+
export async function* tokenStream(token, signal, options) {
|
|
17
|
+
const resolved_options = {
|
|
18
|
+
...DEFAULT_TOKEN_STREAM_OPTIONS,
|
|
19
|
+
...(options ?? {})
|
|
20
|
+
};
|
|
21
|
+
const { keep_alive, expire_warning_period } = resolved_options;
|
|
22
|
+
// Real tokens always have an integer for exp.
|
|
23
|
+
// In tests, we may use fractional seconds to reduce the delay.
|
|
24
|
+
// Both cases are handled here.
|
|
25
|
+
const expires_at = token.exp * 1000;
|
|
26
|
+
const expire_warning_at = expires_at - expire_warning_period;
|
|
27
|
+
let first_expire_test = true;
|
|
28
|
+
while (!signal.aborted) {
|
|
29
|
+
const token_expires_in = Math.max(0, Math.ceil(token.exp - Date.now() / 1000));
|
|
30
|
+
if (first_expire_test && token_expires_in > 0) {
|
|
31
|
+
first_expire_test = false;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
yield { token_expires_in: token_expires_in };
|
|
35
|
+
if (token_expires_in == 0) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const keep_alive_delay = KEEPALIVE_INTERVAL * (0.9 + Math.random() * 0.2);
|
|
40
|
+
// Add margin due to setTimeout inaccuracies
|
|
41
|
+
const expiry_delay = Math.max(0, expires_at - Date.now() + 3);
|
|
42
|
+
const expiry_warning_delay = Math.max(0, expire_warning_at - Date.now() + 3);
|
|
43
|
+
// Either the warning has past or it's before
|
|
44
|
+
const relevant_expiry_delay = expiry_warning_delay != 0 ? expiry_warning_delay : expiry_delay;
|
|
45
|
+
const delay = keep_alive ? Math.min(relevant_expiry_delay, keep_alive_delay) : relevant_expiry_delay;
|
|
46
|
+
await timers.setTimeout(delay, null, { signal }).catch(() => {
|
|
47
|
+
// Ignore AbortError
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export async function* ndjson(iterator) {
|
|
52
|
+
for await (let data of iterator) {
|
|
53
|
+
if (data == null) {
|
|
54
|
+
// Empty value to flush iterator memory
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
else if (typeof data == 'string') {
|
|
58
|
+
// Pre-serialized value
|
|
59
|
+
yield data + '\n';
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
yield JSON.stringify(data) + '\n';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export async function* transformToBytesTracked(iterator) {
|
|
67
|
+
for await (let data of iterator) {
|
|
68
|
+
const encoded = Buffer.from(data, 'utf8');
|
|
69
|
+
Metrics.getInstance().data_synced_bytes.add(encoded.length);
|
|
70
|
+
yield encoded;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/sync/util.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as pgwire from '@powersync/service-jpgwire';
|
|
2
|
+
import { LifeCycledSystem } from '@powersync/lib-services-framework';
|
|
3
|
+
import * as storage from '../storage/storage-index.js';
|
|
4
|
+
import * as utils from '../util/util-index.js';
|
|
5
|
+
export declare abstract class CorePowerSyncSystem extends LifeCycledSystem {
|
|
6
|
+
config: utils.ResolvedPowerSyncConfig;
|
|
7
|
+
abstract storage: storage.BucketStorageFactory;
|
|
8
|
+
abstract pgwire_pool?: pgwire.PgClient;
|
|
9
|
+
closed: boolean;
|
|
10
|
+
protected stopHandlers: Set<() => void>;
|
|
11
|
+
constructor(config: utils.ResolvedPowerSyncConfig);
|
|
12
|
+
get client_keystore(): import("../index.js").KeyStore;
|
|
13
|
+
get dev_client_keystore(): import("../index.js").KeyStore;
|
|
14
|
+
/**
|
|
15
|
+
* Adds a termination handler which will call handlers registered via
|
|
16
|
+
* [addStopHandler].
|
|
17
|
+
* This should be called after the server is started and it's termination handler is added.
|
|
18
|
+
* This is so that the handler is run before the server's handler, allowing streams to be interrupted on exit
|
|
19
|
+
*/
|
|
20
|
+
addTerminationHandler(): void;
|
|
21
|
+
addStopHandler(handler: () => void): () => void;
|
|
22
|
+
requirePgPool(): pgwire.PgClient;
|
|
23
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { LifeCycledSystem, container, logger } from '@powersync/lib-services-framework';
|
|
2
|
+
export class CorePowerSyncSystem extends LifeCycledSystem {
|
|
3
|
+
constructor(config) {
|
|
4
|
+
super();
|
|
5
|
+
this.config = config;
|
|
6
|
+
this.stopHandlers = new Set();
|
|
7
|
+
this.closed = false;
|
|
8
|
+
}
|
|
9
|
+
get client_keystore() {
|
|
10
|
+
return this.config.client_keystore;
|
|
11
|
+
}
|
|
12
|
+
get dev_client_keystore() {
|
|
13
|
+
return this.config.dev_client_keystore;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Adds a termination handler which will call handlers registered via
|
|
17
|
+
* [addStopHandler].
|
|
18
|
+
* This should be called after the server is started and it's termination handler is added.
|
|
19
|
+
* This is so that the handler is run before the server's handler, allowing streams to be interrupted on exit
|
|
20
|
+
*/
|
|
21
|
+
addTerminationHandler() {
|
|
22
|
+
container.terminationHandler.handleTerminationSignal(async () => {
|
|
23
|
+
// Close open streams, so that they don't block the server from closing.
|
|
24
|
+
// Note: This does not work well when streaming requests are queued. In that case, the server still doesn't
|
|
25
|
+
// close in the 30-second timeout.
|
|
26
|
+
this.closed = true;
|
|
27
|
+
logger.info(`Closing ${this.stopHandlers.size} streams`);
|
|
28
|
+
for (let handler of this.stopHandlers) {
|
|
29
|
+
handler();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
addStopHandler(handler) {
|
|
34
|
+
if (this.closed) {
|
|
35
|
+
handler();
|
|
36
|
+
return () => { };
|
|
37
|
+
}
|
|
38
|
+
this.stopHandlers.add(handler);
|
|
39
|
+
return () => {
|
|
40
|
+
this.stopHandlers.delete(handler);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
requirePgPool() {
|
|
44
|
+
if (this.pgwire_pool == null) {
|
|
45
|
+
throw new Error('No source connection configured');
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return this.pgwire_pool;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=CorePowerSyncSystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CorePowerSyncSystem.js","sourceRoot":"","sources":["../../src/system/CorePowerSyncSystem.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAKxF,MAAM,OAAgB,mBAAoB,SAAQ,gBAAgB;IAOhE,YAAmB,MAAqC;QACtD,KAAK,EAAE,CAAC;QADS,WAAM,GAAN,MAAM,CAA+B;QAF9C,iBAAY,GAAoB,IAAI,GAAG,EAAE,CAAC;QAIlD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,IAAI,eAAe;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;IACrC,CAAC;IAED,IAAI,mBAAmB;QACrB,OAAO,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC;IACzC,CAAC;IAED;;;;;OAKG;IACH,qBAAqB;QACnB,SAAS,CAAC,kBAAkB,CAAC,uBAAuB,CAAC,KAAK,IAAI,EAAE;YAC9D,wEAAwE;YACxE,2GAA2G;YAC3G,kCAAkC;YAClC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,IAAI,UAAU,CAAC,CAAC;YACzD,KAAK,IAAI,OAAO,IAAI,IAAI,CAAC,YAAY,EAAE;gBACrC,OAAO,EAAE,CAAC;aACX;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,cAAc,CAAC,OAAmB;QAChC,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,OAAO,EAAE,CAAC;YACV,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;SACjB;QACD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC,CAAC;IACJ,CAAC;IAED,aAAa;QACX,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,EAAE;YAC5B,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;SACpD;aAAM;YACL,OAAO,IAAI,CAAC,WAAY,CAAC;SAC1B;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CorePowerSyncSystem.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-index.js","sourceRoot":"","sources":["../../src/system/system-index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type PromiseFunction<T> = (context: MutexContext) => Promise<T>;
|
|
2
|
+
export type SharedPromiseFunction<T> = (context: SharedMutexContext) => Promise<T>;
|
|
3
|
+
export interface SharedMutexContext {
|
|
4
|
+
sharedLock<T>(promiseFn: SharedPromiseFunction<T>): Promise<T>;
|
|
5
|
+
}
|
|
6
|
+
export interface MutexContext extends SharedMutexContext {
|
|
7
|
+
exclusiveLock<T>(promiseFn: PromiseFunction<T>): Promise<T>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Mutex maintains a queue of Promise-returning functions that
|
|
11
|
+
* are executed sequentially (whereas normally they would execute their async code concurrently).
|
|
12
|
+
*/
|
|
13
|
+
export declare class Mutex implements MutexContext {
|
|
14
|
+
private queue;
|
|
15
|
+
private sharedCount;
|
|
16
|
+
private exclusiveLocked;
|
|
17
|
+
constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Place a function on the queue.
|
|
20
|
+
* The function may either return a Promise or a value.
|
|
21
|
+
* Return a Promise that is resolved with the result of the function.
|
|
22
|
+
*/
|
|
23
|
+
exclusiveLock<T>(promiseFn: PromiseFunction<T>): Promise<T>;
|
|
24
|
+
/**
|
|
25
|
+
* Place a function on the queue.
|
|
26
|
+
* This function may execute in parallel with other "multi" functions, but not with other functions on the exclusive
|
|
27
|
+
* queue.
|
|
28
|
+
*/
|
|
29
|
+
sharedLock<T>(promiseFn: SharedPromiseFunction<T>): Promise<T>;
|
|
30
|
+
private lock;
|
|
31
|
+
/**
|
|
32
|
+
* Convert a normal Promise-returning function into one that is automatically enqueued.
|
|
33
|
+
* The signature of the function stays the same - only the execution is potentially delayed.
|
|
34
|
+
* The only exception is that if the function would have returned a scalar value, it now
|
|
35
|
+
* returns a Promise.
|
|
36
|
+
*/
|
|
37
|
+
qu<T>(fn: PromiseFunction<T>): () => Promise<T>;
|
|
38
|
+
/**
|
|
39
|
+
* Wait until we are ready to execute the next task on the queue.
|
|
40
|
+
*
|
|
41
|
+
* This places a "Task" marker on the queue, and waits until we get to it.
|
|
42
|
+
*
|
|
43
|
+
* @param exclusive
|
|
44
|
+
*/
|
|
45
|
+
private _lockNext;
|
|
46
|
+
private _tryNext;
|
|
47
|
+
}
|