@powersync/service-core 0.0.0-dev-20240725112650 → 0.0.0-dev-20240918092408
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 +80 -2
- package/dist/api/RouteAPI.d.ts +68 -0
- package/dist/api/RouteAPI.js +2 -0
- package/dist/api/RouteAPI.js.map +1 -0
- package/dist/api/api-index.d.ts +1 -0
- package/dist/api/api-index.js +1 -0
- package/dist/api/api-index.js.map +1 -1
- package/dist/api/diagnostics.d.ts +4 -4
- package/dist/api/diagnostics.js +11 -65
- package/dist/api/diagnostics.js.map +1 -1
- package/dist/api/schema.d.ts +3 -5
- package/dist/api/schema.js +9 -79
- package/dist/api/schema.js.map +1 -1
- package/dist/auth/KeyStore.d.ts +7 -4
- package/dist/auth/KeyStore.js +1 -1
- package/dist/auth/KeyStore.js.map +1 -1
- package/dist/auth/auth-index.d.ts +0 -1
- package/dist/auth/auth-index.js +0 -1
- package/dist/auth/auth-index.js.map +1 -1
- package/dist/entry/cli-entry.js +3 -2
- package/dist/entry/cli-entry.js.map +1 -1
- package/dist/entry/commands/compact-action.js +12 -8
- 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/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/migrations.d.ts +8 -0
- package/dist/migrations/migrations.js +19 -7
- package/dist/migrations/migrations.js.map +1 -1
- package/dist/modules/AbstractModule.d.ts +26 -0
- package/dist/modules/AbstractModule.js +11 -0
- package/dist/modules/AbstractModule.js.map +1 -0
- package/dist/modules/ModuleManager.d.ts +11 -0
- package/dist/modules/ModuleManager.js +32 -0
- package/dist/modules/ModuleManager.js.map +1 -0
- package/dist/modules/modules-index.d.ts +2 -0
- package/dist/modules/modules-index.js +3 -0
- package/dist/modules/modules-index.js.map +1 -0
- package/dist/replication/AbstractReplicationJob.d.ts +38 -0
- package/dist/replication/AbstractReplicationJob.js +51 -0
- package/dist/replication/AbstractReplicationJob.js.map +1 -0
- package/dist/replication/AbstractReplicator.d.ts +53 -0
- package/dist/replication/AbstractReplicator.js +187 -0
- package/dist/replication/AbstractReplicator.js.map +1 -0
- package/dist/replication/ErrorRateLimiter.d.ts +0 -9
- package/dist/replication/ErrorRateLimiter.js +1 -42
- package/dist/replication/ErrorRateLimiter.js.map +1 -1
- package/dist/replication/ReplicationEngine.d.ts +18 -0
- package/dist/replication/ReplicationEngine.js +41 -0
- package/dist/replication/ReplicationEngine.js.map +1 -0
- package/dist/replication/ReplicationModule.d.ts +39 -0
- package/dist/replication/ReplicationModule.js +65 -0
- package/dist/replication/ReplicationModule.js.map +1 -0
- package/dist/replication/replication-index.d.ts +4 -6
- package/dist/replication/replication-index.js +4 -6
- package/dist/replication/replication-index.js.map +1 -1
- package/dist/routes/RouterEngine.d.ts +42 -0
- package/dist/routes/RouterEngine.js +80 -0
- package/dist/routes/RouterEngine.js.map +1 -0
- package/dist/routes/auth.d.ts +2 -2
- package/dist/routes/auth.js +11 -11
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/configure-fastify.d.ts +30 -176
- package/dist/routes/configure-fastify.js +10 -11
- package/dist/routes/configure-fastify.js.map +1 -1
- package/dist/routes/configure-rsocket.d.ts +3 -3
- package/dist/routes/configure-rsocket.js +6 -5
- package/dist/routes/configure-rsocket.js.map +1 -1
- package/dist/routes/endpoints/admin.d.ts +0 -34
- package/dist/routes/endpoints/admin.js +48 -89
- package/dist/routes/endpoints/admin.js.map +1 -1
- package/dist/routes/endpoints/checkpointing.d.ts +56 -16
- package/dist/routes/endpoints/checkpointing.js +33 -12
- package/dist/routes/endpoints/checkpointing.js.map +1 -1
- package/dist/routes/endpoints/route-endpoints-index.d.ts +0 -1
- package/dist/routes/endpoints/route-endpoints-index.js +0 -1
- package/dist/routes/endpoints/route-endpoints-index.js.map +1 -1
- package/dist/routes/endpoints/socket-route.js +40 -25
- package/dist/routes/endpoints/socket-route.js.map +1 -1
- package/dist/routes/endpoints/sync-rules.d.ts +1 -1
- package/dist/routes/endpoints/sync-rules.js +32 -23
- package/dist/routes/endpoints/sync-rules.js.map +1 -1
- package/dist/routes/endpoints/sync-stream.d.ts +10 -0
- package/dist/routes/endpoints/sync-stream.js +13 -8
- package/dist/routes/endpoints/sync-stream.js.map +1 -1
- package/dist/routes/router-socket.d.ts +1 -0
- package/dist/routes/router-socket.js +2 -1
- package/dist/routes/router-socket.js.map +1 -1
- package/dist/routes/router.d.ts +6 -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 +47 -76
- package/dist/runner/teardown.js.map +1 -1
- package/dist/storage/BucketStorage.d.ts +30 -19
- package/dist/storage/BucketStorage.js +0 -10
- package/dist/storage/BucketStorage.js.map +1 -1
- package/dist/storage/MongoBucketStorage.d.ts +4 -4
- package/dist/storage/MongoBucketStorage.js +19 -24
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/SourceEntity.d.ts +20 -0
- package/dist/storage/SourceEntity.js +2 -0
- package/dist/storage/SourceEntity.js.map +1 -0
- package/dist/storage/SourceTable.d.ts +4 -5
- package/dist/storage/SourceTable.js +3 -4
- package/dist/storage/SourceTable.js.map +1 -1
- package/dist/storage/StorageEngine.d.ts +24 -0
- package/dist/storage/StorageEngine.js +43 -0
- package/dist/storage/StorageEngine.js.map +1 -0
- package/dist/storage/StorageProvider.d.ts +21 -0
- package/dist/storage/StorageProvider.js +2 -0
- package/dist/storage/StorageProvider.js.map +1 -0
- package/dist/storage/mongo/MongoBucketBatch.d.ts +1 -1
- package/dist/storage/mongo/MongoBucketBatch.js +6 -7
- package/dist/storage/mongo/MongoBucketBatch.js.map +1 -1
- package/dist/storage/mongo/MongoCompactor.js +2 -1
- package/dist/storage/mongo/MongoCompactor.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 +7 -6
- package/dist/storage/mongo/MongoSyncBucketStorage.js +24 -15
- package/dist/storage/mongo/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/mongo/MongoSyncRulesLock.js +1 -1
- package/dist/storage/mongo/MongoSyncRulesLock.js.map +1 -1
- package/dist/storage/mongo/OperationBatch.d.ts +7 -3
- package/dist/storage/mongo/OperationBatch.js +16 -7
- package/dist/storage/mongo/OperationBatch.js.map +1 -1
- package/dist/storage/mongo/PersistedBatch.d.ts +3 -3
- package/dist/storage/mongo/PersistedBatch.js +2 -2
- package/dist/storage/mongo/PersistedBatch.js.map +1 -1
- package/dist/storage/mongo/models.d.ts +13 -4
- 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 +5 -2
- package/dist/storage/storage-index.js +5 -2
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/sync/sync.d.ts +2 -1
- package/dist/sync/sync.js +36 -10
- package/dist/sync/sync.js.map +1 -1
- 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/config/compound-config-collector.d.ts +9 -2
- package/dist/util/config/compound-config-collector.js +14 -23
- package/dist/util/config/compound-config-collector.js.map +1 -1
- package/dist/util/config/sync-rules/sync-rules-provider.d.ts +9 -0
- package/dist/util/config/sync-rules/sync-rules-provider.js +15 -0
- package/dist/util/config/sync-rules/sync-rules-provider.js.map +1 -0
- package/dist/util/config/types.d.ts +6 -4
- package/dist/util/config/types.js.map +1 -1
- package/dist/util/config.d.ts +3 -4
- package/dist/util/config.js +5 -20
- package/dist/util/config.js.map +1 -1
- package/dist/util/protocol-types.d.ts +4 -0
- package/dist/util/protocol-types.js +5 -1
- package/dist/util/protocol-types.js.map +1 -1
- package/dist/util/util-index.d.ts +3 -6
- package/dist/util/util-index.js +3 -6
- package/dist/util/util-index.js.map +1 -1
- package/dist/util/utils.d.ts +10 -6
- package/dist/util/utils.js +45 -25
- package/dist/util/utils.js.map +1 -1
- package/package.json +5 -7
- package/src/api/RouteAPI.ts +78 -0
- package/src/api/api-index.ts +1 -0
- package/src/api/diagnostics.ts +16 -71
- package/src/api/schema.ts +13 -89
- package/src/auth/KeyStore.ts +9 -6
- package/src/auth/auth-index.ts +0 -1
- package/src/entry/cli-entry.ts +3 -2
- package/src/entry/commands/compact-action.ts +12 -9
- 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/migrations.ts +24 -8
- package/src/modules/AbstractModule.ts +37 -0
- package/src/modules/ModuleManager.ts +34 -0
- package/src/modules/modules-index.ts +2 -0
- package/src/replication/AbstractReplicationJob.ts +79 -0
- package/src/replication/AbstractReplicator.ts +227 -0
- package/src/replication/ErrorRateLimiter.ts +0 -44
- package/src/replication/ReplicationEngine.ts +43 -0
- package/src/replication/ReplicationModule.ts +101 -0
- package/src/replication/replication-index.ts +4 -6
- package/src/routes/RouterEngine.ts +120 -0
- package/src/routes/auth.ts +21 -12
- package/src/routes/configure-fastify.ts +13 -14
- package/src/routes/configure-rsocket.ts +9 -8
- package/src/routes/endpoints/admin.ts +74 -100
- package/src/routes/endpoints/checkpointing.ts +46 -12
- package/src/routes/endpoints/route-endpoints-index.ts +0 -1
- package/src/routes/endpoints/socket-route.ts +44 -27
- package/src/routes/endpoints/sync-rules.ts +41 -25
- package/src/routes/endpoints/sync-stream.ts +13 -8
- package/src/routes/router-socket.ts +2 -1
- package/src/routes/router.ts +6 -3
- package/src/routes/routes-index.ts +1 -0
- package/src/runner/teardown.ts +50 -88
- package/src/storage/BucketStorage.ts +38 -25
- package/src/storage/MongoBucketStorage.ts +23 -26
- package/src/storage/SourceEntity.ts +22 -0
- package/src/storage/SourceTable.ts +4 -6
- package/src/storage/StorageEngine.ts +55 -0
- package/src/storage/StorageProvider.ts +27 -0
- package/src/storage/mongo/MongoBucketBatch.ts +8 -8
- package/src/storage/mongo/MongoCompactor.ts +2 -1
- package/src/storage/mongo/MongoPersistedSyncRulesContent.ts +3 -3
- package/src/storage/mongo/MongoStorageProvider.ts +31 -0
- package/src/storage/mongo/MongoSyncBucketStorage.ts +39 -20
- package/src/storage/mongo/MongoSyncRulesLock.ts +1 -1
- package/src/storage/mongo/OperationBatch.ts +18 -11
- package/src/storage/mongo/PersistedBatch.ts +6 -5
- package/src/storage/mongo/models.ts +13 -4
- package/src/storage/mongo/util.ts +49 -4
- package/src/storage/storage-index.ts +5 -2
- package/src/sync/sync.ts +46 -11
- 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 +30 -31
- package/src/util/config/sync-rules/sync-rules-provider.ts +18 -0
- package/src/util/config/types.ts +6 -5
- package/src/util/config.ts +6 -23
- package/src/util/protocol-types.ts +6 -1
- package/src/util/util-index.ts +3 -6
- package/src/util/utils.ts +55 -39
- package/test/src/__snapshots__/sync.test.ts.snap +7 -7
- package/test/src/auth.test.ts +7 -7
- package/test/src/broadcast_iterable.test.ts +1 -1
- package/test/src/checksum_cache.test.ts +3 -3
- package/test/src/compacting.test.ts +26 -17
- package/test/src/data_storage.test.ts +258 -146
- package/test/src/env.ts +1 -3
- package/test/src/merge_iterable.test.ts +1 -6
- package/test/src/setup.ts +1 -1
- package/test/src/stream_utils.ts +42 -0
- package/test/src/sync.test.ts +52 -31
- package/test/src/util.ts +48 -51
- package/test/tsconfig.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/auth/SupabaseKeyCollector.d.ts +0 -22
- package/dist/auth/SupabaseKeyCollector.js +0 -61
- package/dist/auth/SupabaseKeyCollector.js.map +0 -1
- package/dist/replication/PgRelation.d.ts +0 -16
- package/dist/replication/PgRelation.js +0 -26
- package/dist/replication/PgRelation.js.map +0 -1
- package/dist/replication/WalConnection.d.ts +0 -34
- package/dist/replication/WalConnection.js +0 -190
- package/dist/replication/WalConnection.js.map +0 -1
- package/dist/replication/WalStream.d.ts +0 -57
- package/dist/replication/WalStream.js +0 -515
- package/dist/replication/WalStream.js.map +0 -1
- package/dist/replication/WalStreamManager.d.ts +0 -30
- package/dist/replication/WalStreamManager.js +0 -198
- package/dist/replication/WalStreamManager.js.map +0 -1
- package/dist/replication/WalStreamRunner.d.ts +0 -38
- package/dist/replication/WalStreamRunner.js +0 -155
- package/dist/replication/WalStreamRunner.js.map +0 -1
- package/dist/replication/util.d.ts +0 -9
- package/dist/replication/util.js +0 -62
- package/dist/replication/util.js.map +0 -1
- package/dist/routes/endpoints/dev.d.ts +0 -312
- package/dist/routes/endpoints/dev.js +0 -172
- package/dist/routes/endpoints/dev.js.map +0 -1
- package/dist/system/CorePowerSyncSystem.d.ts +0 -23
- package/dist/system/CorePowerSyncSystem.js +0 -52
- package/dist/system/CorePowerSyncSystem.js.map +0 -1
- package/dist/util/PgManager.d.ts +0 -24
- package/dist/util/PgManager.js +0 -55
- package/dist/util/PgManager.js.map +0 -1
- package/dist/util/migration_lib.d.ts +0 -11
- package/dist/util/migration_lib.js +0 -64
- package/dist/util/migration_lib.js.map +0 -1
- package/dist/util/pgwire_utils.d.ts +0 -24
- package/dist/util/pgwire_utils.js +0 -117
- package/dist/util/pgwire_utils.js.map +0 -1
- package/dist/util/populate_test_data.d.ts +0 -8
- package/dist/util/populate_test_data.js +0 -65
- package/dist/util/populate_test_data.js.map +0 -1
- package/src/auth/SupabaseKeyCollector.ts +0 -67
- package/src/replication/PgRelation.ts +0 -42
- package/src/replication/WalConnection.ts +0 -227
- package/src/replication/WalStream.ts +0 -624
- package/src/replication/WalStreamManager.ts +0 -213
- package/src/replication/WalStreamRunner.ts +0 -180
- package/src/replication/util.ts +0 -76
- package/src/routes/endpoints/dev.ts +0 -199
- package/src/system/CorePowerSyncSystem.ts +0 -64
- package/src/util/PgManager.ts +0 -64
- package/src/util/migration_lib.ts +0 -79
- package/src/util/pgwire_utils.ts +0 -139
- package/src/util/populate_test_data.ts +0 -78
- package/test/src/__snapshots__/pg_test.test.ts.snap +0 -256
- package/test/src/large_batch.test.ts +0 -194
- package/test/src/pg_test.test.ts +0 -450
- package/test/src/schema_changes.test.ts +0 -545
- package/test/src/slow_tests.test.ts +0 -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,12 +1,11 @@
|
|
|
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 * as replication from '../../replication/replication-index.js';
|
|
8
6
|
import { authApi } from '../auth.js';
|
|
9
7
|
import { routeDefinition } from '../router.js';
|
|
8
|
+
import { RouteAPI } from '../../api/RouteAPI.js';
|
|
10
9
|
|
|
11
10
|
const DeploySyncRulesRequest = t.object({
|
|
12
11
|
content: t.string
|
|
@@ -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,9 +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
|
+
const headers = payload.request.headers;
|
|
25
|
+
const userAgent = headers['x-user-agent'] ?? headers['user-agent'];
|
|
26
|
+
const clientId = payload.params.client_id;
|
|
24
27
|
|
|
25
|
-
if (
|
|
28
|
+
if (routerEngine!.closed) {
|
|
26
29
|
throw new errors.JourneyError({
|
|
27
30
|
status: 503,
|
|
28
31
|
code: 'SERVICE_UNAVAILABLE',
|
|
@@ -33,9 +36,8 @@ export const syncStreamed = routeDefinition({
|
|
|
33
36
|
const params: util.StreamingSyncRequest = payload.params;
|
|
34
37
|
const syncParams = new RequestParameters(payload.context.token_payload!, payload.params.parameters ?? {});
|
|
35
38
|
|
|
36
|
-
const storage = system.storage;
|
|
37
39
|
// Sanity check before we start the stream
|
|
38
|
-
const cp = await
|
|
40
|
+
const cp = await storageEngine.activeBucketStorage.getActiveCheckpoint();
|
|
39
41
|
if (!cp.hasSyncRules()) {
|
|
40
42
|
throw new errors.JourneyError({
|
|
41
43
|
status: 500,
|
|
@@ -44,14 +46,15 @@ export const syncStreamed = routeDefinition({
|
|
|
44
46
|
});
|
|
45
47
|
}
|
|
46
48
|
const controller = new AbortController();
|
|
47
|
-
const tracker = new RequestTracker();
|
|
49
|
+
const tracker = new sync.RequestTracker();
|
|
48
50
|
try {
|
|
49
51
|
Metrics.getInstance().concurrent_connections.add(1);
|
|
50
52
|
const stream = Readable.from(
|
|
51
53
|
sync.transformToBytesTracked(
|
|
52
54
|
sync.ndjson(
|
|
53
55
|
sync.streamResponse({
|
|
54
|
-
storage,
|
|
56
|
+
storage: storageEngine.activeBucketStorage,
|
|
57
|
+
parseOptions: routerEngine!.getAPI().getParseSyncRulesOptions(),
|
|
55
58
|
params,
|
|
56
59
|
syncParams,
|
|
57
60
|
token: payload.context.token_payload!,
|
|
@@ -64,7 +67,7 @@ export const syncStreamed = routeDefinition({
|
|
|
64
67
|
{ objectMode: false, highWaterMark: 16 * 1024 }
|
|
65
68
|
);
|
|
66
69
|
|
|
67
|
-
const deregister =
|
|
70
|
+
const deregister = routerEngine!.addStopHandler(() => {
|
|
68
71
|
// This error is not currently propagated to the client
|
|
69
72
|
controller.abort();
|
|
70
73
|
stream.destroy(new Error('Shutting down system'));
|
|
@@ -92,6 +95,8 @@ export const syncStreamed = routeDefinition({
|
|
|
92
95
|
Metrics.getInstance().concurrent_connections.add(-1);
|
|
93
96
|
logger.info(`Sync stream complete`, {
|
|
94
97
|
user_id: syncParams.user_id,
|
|
98
|
+
client_id: clientId,
|
|
99
|
+
user_agent: userAgent,
|
|
95
100
|
operations_synced: tracker.operationsSynced,
|
|
96
101
|
data_synced_bytes: tracker.dataSyncedBytes
|
|
97
102
|
});
|
|
@@ -9,5 +9,6 @@ import { Context } from './router.js';
|
|
|
9
9
|
export type SocketRouteGenerator = (router: ReactiveSocketRouter<Context>) => IReactiveStream;
|
|
10
10
|
|
|
11
11
|
export const RSocketContextMeta = t.object({
|
|
12
|
-
token: t.string
|
|
12
|
+
token: t.string,
|
|
13
|
+
user_agent: t.string.optional()
|
|
13
14
|
});
|
package/src/routes/router.ts
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { router } from '@powersync/lib-services-framework';
|
|
2
2
|
import * as auth from '../auth/auth-index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { ServiceContext } from '../system/ServiceContext.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Common context for routes
|
|
7
7
|
*/
|
|
8
8
|
export type Context = {
|
|
9
9
|
user_id?: string;
|
|
10
|
-
|
|
10
|
+
service_context: ServiceContext;
|
|
11
11
|
|
|
12
12
|
token_payload?: auth.JwtPayload;
|
|
13
13
|
token_errors?: string[];
|
|
14
|
+
/**
|
|
15
|
+
* Only on websocket endpoints.
|
|
16
|
+
*/
|
|
17
|
+
user_agent?: string;
|
|
14
18
|
};
|
|
15
19
|
|
|
16
20
|
export type BasicRouterRequest = {
|
|
@@ -37,7 +41,6 @@ export type RequestEndpointHandlerPayload<
|
|
|
37
41
|
};
|
|
38
42
|
|
|
39
43
|
export type RouteDefinition<I = any, O = any> = RequestEndpoint<I, O>;
|
|
40
|
-
|
|
41
44
|
/**
|
|
42
45
|
* Helper function for making generics work well when defining routes
|
|
43
46
|
*/
|
package/src/runner/teardown.ts
CHANGED
|
@@ -1,108 +1,70 @@
|
|
|
1
1
|
// Script to tear down the data when deleting an instance.
|
|
2
|
-
// This
|
|
3
|
-
// 1.
|
|
4
|
-
// 2.
|
|
2
|
+
// This should:
|
|
3
|
+
// 1. Attempt to clean up any remote configuration of data sources that was set up.
|
|
4
|
+
// 2. Delete the storage
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
import * as
|
|
6
|
+
import { container, logger } from '@powersync/lib-services-framework';
|
|
7
|
+
import * as modules from '../modules/modules-index.js';
|
|
8
|
+
import * as system from '../system/system-index.js';
|
|
9
9
|
import * as storage from '../storage/storage-index.js';
|
|
10
10
|
import * as utils from '../util/util-index.js';
|
|
11
|
-
import
|
|
12
|
-
import { logger } from '@powersync/lib-services-framework';
|
|
11
|
+
import timers from 'timers/promises';
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
* Attempt to terminate a single sync rules instance.
|
|
16
|
-
*
|
|
17
|
-
* This may fail with a lock error.
|
|
18
|
-
*/
|
|
19
|
-
async function terminateReplicator(
|
|
20
|
-
storageFactory: storage.BucketStorageFactory,
|
|
21
|
-
connection: utils.ResolvedConnection,
|
|
22
|
-
syncRules: storage.PersistedSyncRulesContent
|
|
23
|
-
) {
|
|
24
|
-
// The lock may still be active if the current replication instance
|
|
25
|
-
// hasn't stopped yet.
|
|
26
|
-
const lock = await syncRules.lock();
|
|
13
|
+
export async function teardown(runnerConfig: utils.RunnerConfig) {
|
|
27
14
|
try {
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
});
|
|
15
|
+
logger.info(`Tearing down PowerSync instance...`);
|
|
16
|
+
const config = await utils.loadConfig(runnerConfig);
|
|
17
|
+
const serviceContext = new system.ServiceContextContainer(config);
|
|
18
|
+
const moduleManager = container.getImplementation(modules.ModuleManager);
|
|
19
|
+
await moduleManager.initialize(serviceContext);
|
|
20
|
+
// This is mostly done to ensure that the storage is ready
|
|
21
|
+
await serviceContext.lifeCycleEngine.start();
|
|
36
22
|
|
|
37
|
-
|
|
38
|
-
await
|
|
39
|
-
logger.info(`
|
|
40
|
-
|
|
41
|
-
|
|
23
|
+
await terminateSyncRules(serviceContext.storageEngine.activeBucketStorage, moduleManager);
|
|
24
|
+
await serviceContext.storageEngine.activeStorage.tearDown();
|
|
25
|
+
logger.info(`Teardown complete.`);
|
|
26
|
+
process.exit(0);
|
|
27
|
+
} catch (e) {
|
|
28
|
+
logger.error(`Teardown failure`, e);
|
|
29
|
+
process.exit(1);
|
|
42
30
|
}
|
|
43
31
|
}
|
|
44
32
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
*
|
|
48
|
-
* Retries lock and other errors for up to two minutes.
|
|
49
|
-
*
|
|
50
|
-
* This is a best-effot attempt. In some cases it may not be possible to delete the replication
|
|
51
|
-
* slot, such as when the postgres instance is unreachable.
|
|
52
|
-
*/
|
|
53
|
-
async function terminateReplicators(
|
|
54
|
-
storageFactory: storage.BucketStorageFactory,
|
|
55
|
-
connection: utils.ResolvedConnection
|
|
56
|
-
) {
|
|
33
|
+
async function terminateSyncRules(storageFactory: storage.BucketStorageFactory, moduleManager: modules.ModuleManager) {
|
|
34
|
+
logger.info(`Terminating sync rules...`);
|
|
57
35
|
const start = Date.now();
|
|
58
|
-
|
|
36
|
+
const locks: storage.ReplicationLock[] = [];
|
|
37
|
+
while (Date.now() - start < 120_000) {
|
|
59
38
|
let retry = false;
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
39
|
+
const replicatingSyncRules = await storageFactory.getReplicatingSyncRules();
|
|
40
|
+
// Lock all the replicating sync rules
|
|
41
|
+
for (const replicatingSyncRule of replicatingSyncRules) {
|
|
42
|
+
const lock = await replicatingSyncRule.lock();
|
|
43
|
+
locks.push(lock);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const stoppedSyncRules = await storageFactory.getStoppedSyncRules();
|
|
47
|
+
const combinedSyncRules = [...replicatingSyncRules, ...stoppedSyncRules];
|
|
48
|
+
try {
|
|
49
|
+
// Clean up any module specific configuration for the sync rules
|
|
50
|
+
await moduleManager.tearDown({ syncRules: combinedSyncRules });
|
|
51
|
+
|
|
52
|
+
// Mark the sync rules as terminated
|
|
53
|
+
for (let syncRules of combinedSyncRules) {
|
|
54
|
+
const syncRulesStorage = storageFactory.getInstance(syncRules);
|
|
55
|
+
// The storage will be dropped at the end of the teardown, so we don't need to clear it here
|
|
56
|
+
await syncRulesStorage.terminate({ clearStorage: false });
|
|
57
|
+
}
|
|
58
|
+
} catch (e) {
|
|
59
|
+
retry = true;
|
|
60
|
+
for (const lock of locks) {
|
|
61
|
+
await lock.release();
|
|
68
62
|
}
|
|
69
63
|
}
|
|
64
|
+
|
|
70
65
|
if (!retry) {
|
|
71
66
|
break;
|
|
72
67
|
}
|
|
73
68
|
await timers.setTimeout(5_000);
|
|
74
69
|
}
|
|
75
70
|
}
|
|
76
|
-
|
|
77
|
-
export async function teardown(runnerConfig: utils.RunnerConfig) {
|
|
78
|
-
const config = await utils.loadConfig(runnerConfig);
|
|
79
|
-
const mongoDB = storage.createPowerSyncMongo(config.storage);
|
|
80
|
-
try {
|
|
81
|
-
logger.info(`Waiting for auth`);
|
|
82
|
-
await db.mongo.waitForAuth(mongoDB.db);
|
|
83
|
-
|
|
84
|
-
const bucketStorage = new storage.MongoBucketStorage(mongoDB, { slot_name_prefix: config.slot_name_prefix });
|
|
85
|
-
const connection = config.connection;
|
|
86
|
-
|
|
87
|
-
logger.info(`Terminating replication slots`);
|
|
88
|
-
|
|
89
|
-
if (connection) {
|
|
90
|
-
await terminateReplicators(bucketStorage, connection);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const database = mongoDB.db;
|
|
94
|
-
logger.info(`Dropping database ${database.namespace}`);
|
|
95
|
-
await database.dropDatabase();
|
|
96
|
-
logger.info(`Done`);
|
|
97
|
-
await mongoDB.client.close();
|
|
98
|
-
|
|
99
|
-
// If there was an error connecting to postgress, the process may stay open indefinitely.
|
|
100
|
-
// This forces an exit.
|
|
101
|
-
// We do not consider those errors a teardown failure.
|
|
102
|
-
process.exit(0);
|
|
103
|
-
} catch (e) {
|
|
104
|
-
logger.error(`Teardown failure`, e);
|
|
105
|
-
await mongoDB.client.close();
|
|
106
|
-
process.exit(1);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
SqliteRow,
|
|
8
8
|
ToastableSqliteRow
|
|
9
9
|
} from '@powersync/service-sync-rules';
|
|
10
|
-
|
|
11
|
-
import * as replication from '../replication/replication-index.js';
|
|
12
10
|
import * as util from '../util/util-index.js';
|
|
13
11
|
import { SourceTable } from './SourceTable.js';
|
|
12
|
+
import { SourceEntityDescriptor } from './SourceEntity.js';
|
|
13
|
+
import { ReplicaId } from './storage-index.js';
|
|
14
14
|
|
|
15
15
|
export interface BucketStorageFactory {
|
|
16
16
|
/**
|
|
@@ -24,7 +24,7 @@ export interface BucketStorageFactory {
|
|
|
24
24
|
/**
|
|
25
25
|
* Get a storage instance to query sync data for specific sync rules.
|
|
26
26
|
*/
|
|
27
|
-
getInstance(options:
|
|
27
|
+
getInstance(options: PersistedSyncRulesContent): SyncRulesBucketStorage;
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Deploy new sync rules.
|
|
@@ -48,7 +48,7 @@ export interface BucketStorageFactory {
|
|
|
48
48
|
/**
|
|
49
49
|
* Get the sync rules used for querying.
|
|
50
50
|
*/
|
|
51
|
-
getActiveSyncRules(): Promise<PersistedSyncRules | null>;
|
|
51
|
+
getActiveSyncRules(options: ParseSyncRulesOptions): Promise<PersistedSyncRules | null>;
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* Get the sync rules used for querying.
|
|
@@ -58,7 +58,7 @@ export interface BucketStorageFactory {
|
|
|
58
58
|
/**
|
|
59
59
|
* Get the sync rules that will be active next once done with initial replicatino.
|
|
60
60
|
*/
|
|
61
|
-
getNextSyncRules(): Promise<PersistedSyncRules | null>;
|
|
61
|
+
getNextSyncRules(options: ParseSyncRulesOptions): Promise<PersistedSyncRules | null>;
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* Get the sync rules that will be active next once done with initial replicatino.
|
|
@@ -105,7 +105,7 @@ export interface WriteCheckpoint {
|
|
|
105
105
|
|
|
106
106
|
export interface ActiveCheckpoint {
|
|
107
107
|
readonly checkpoint: util.OpId;
|
|
108
|
-
readonly lsn: string;
|
|
108
|
+
readonly lsn: string | null;
|
|
109
109
|
|
|
110
110
|
hasSyncRules(): boolean;
|
|
111
111
|
|
|
@@ -131,6 +131,10 @@ export interface StorageMetrics {
|
|
|
131
131
|
replication_size_bytes: number;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
export interface ParseSyncRulesOptions {
|
|
135
|
+
defaultSchema: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
134
138
|
export interface PersistedSyncRulesContent {
|
|
135
139
|
readonly id: number;
|
|
136
140
|
readonly sync_rules_content: string;
|
|
@@ -140,7 +144,7 @@ export interface PersistedSyncRulesContent {
|
|
|
140
144
|
readonly last_keepalive_ts?: Date | null;
|
|
141
145
|
readonly last_checkpoint_ts?: Date | null;
|
|
142
146
|
|
|
143
|
-
parsed(): PersistedSyncRules;
|
|
147
|
+
parsed(options: ParseSyncRulesOptions): PersistedSyncRules;
|
|
144
148
|
|
|
145
149
|
lock(): Promise<ReplicationLock>;
|
|
146
150
|
}
|
|
@@ -157,18 +161,6 @@ export interface PersistedSyncRules {
|
|
|
157
161
|
readonly slot_name: string;
|
|
158
162
|
}
|
|
159
163
|
|
|
160
|
-
export class DefaultPersistedSyncRules implements PersistedSyncRules {
|
|
161
|
-
public readonly checkpoint_lsn: string | null;
|
|
162
|
-
|
|
163
|
-
constructor(public readonly id: number, public readonly sync_rules: SqlSyncRules, checkpoint_lsn: string | null) {
|
|
164
|
-
this.checkpoint_lsn = checkpoint_lsn;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
get slot_name(): string {
|
|
168
|
-
return `powersync_${this.id}`;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
164
|
export interface UpdateSyncRulesOptions {
|
|
173
165
|
content: string;
|
|
174
166
|
lock?: boolean;
|
|
@@ -198,8 +190,11 @@ export interface BucketDataBatchOptions {
|
|
|
198
190
|
chunkLimitBytes?: number;
|
|
199
191
|
}
|
|
200
192
|
|
|
193
|
+
export interface StartBatchOptions extends ParseSyncRulesOptions {
|
|
194
|
+
zeroLSN: string;
|
|
195
|
+
}
|
|
196
|
+
|
|
201
197
|
export interface SyncRulesBucketStorage {
|
|
202
|
-
readonly sync_rules: SqlSyncRules;
|
|
203
198
|
readonly group_id: number;
|
|
204
199
|
readonly slot_name: string;
|
|
205
200
|
|
|
@@ -207,9 +202,14 @@ export interface SyncRulesBucketStorage {
|
|
|
207
202
|
|
|
208
203
|
resolveTable(options: ResolveTableOptions): Promise<ResolveTableResult>;
|
|
209
204
|
|
|
210
|
-
startBatch(
|
|
205
|
+
startBatch(
|
|
206
|
+
options: StartBatchOptions,
|
|
207
|
+
callback: (batch: BucketStorageBatch) => Promise<void>
|
|
208
|
+
): Promise<FlushedResult | null>;
|
|
211
209
|
|
|
212
|
-
getCheckpoint(): Promise<{ checkpoint: util.OpId
|
|
210
|
+
getCheckpoint(): Promise<{ checkpoint: util.OpId }>;
|
|
211
|
+
|
|
212
|
+
getParsedSyncRules(options: ParseSyncRulesOptions): SqlSyncRules;
|
|
213
213
|
|
|
214
214
|
getParameterSets(checkpoint: util.OpId, lookups: SqliteJsonValue[][]): Promise<SqliteJsonRow[]>;
|
|
215
215
|
|
|
@@ -244,7 +244,7 @@ export interface SyncRulesBucketStorage {
|
|
|
244
244
|
*
|
|
245
245
|
* Must only be called on stopped sync rules.
|
|
246
246
|
*/
|
|
247
|
-
terminate(): Promise<void>;
|
|
247
|
+
terminate(options?: TerminateOptions): Promise<void>;
|
|
248
248
|
|
|
249
249
|
getStatus(): Promise<SyncRuleStatus>;
|
|
250
250
|
|
|
@@ -279,7 +279,7 @@ export interface ResolveTableOptions {
|
|
|
279
279
|
group_id: number;
|
|
280
280
|
connection_id: number;
|
|
281
281
|
connection_tag: string;
|
|
282
|
-
|
|
282
|
+
entity_descriptor: SourceEntityDescriptor;
|
|
283
283
|
|
|
284
284
|
sync_rules: SqlSyncRules;
|
|
285
285
|
}
|
|
@@ -363,7 +363,9 @@ export interface SaveInsert {
|
|
|
363
363
|
tag: 'insert';
|
|
364
364
|
sourceTable: SourceTable;
|
|
365
365
|
before?: undefined;
|
|
366
|
+
beforeReplicaId?: undefined;
|
|
366
367
|
after: SqliteRow;
|
|
368
|
+
afterReplicaId: ReplicaId;
|
|
367
369
|
}
|
|
368
370
|
|
|
369
371
|
export interface SaveUpdate {
|
|
@@ -374,6 +376,7 @@ export interface SaveUpdate {
|
|
|
374
376
|
* This is only present when the id has changed, and will only contain replica identity columns.
|
|
375
377
|
*/
|
|
376
378
|
before?: SqliteRow;
|
|
379
|
+
beforeReplicaId?: ReplicaId;
|
|
377
380
|
|
|
378
381
|
/**
|
|
379
382
|
* A null value means null column.
|
|
@@ -381,13 +384,16 @@ export interface SaveUpdate {
|
|
|
381
384
|
* An undefined value means it's a TOAST value - must be copied from another record.
|
|
382
385
|
*/
|
|
383
386
|
after: ToastableSqliteRow;
|
|
387
|
+
afterReplicaId: ReplicaId;
|
|
384
388
|
}
|
|
385
389
|
|
|
386
390
|
export interface SaveDelete {
|
|
387
391
|
tag: 'delete';
|
|
388
392
|
sourceTable: SourceTable;
|
|
389
|
-
before
|
|
393
|
+
before?: SqliteRow;
|
|
394
|
+
beforeReplicaId: ReplicaId;
|
|
390
395
|
after?: undefined;
|
|
396
|
+
afterReplicaId?: undefined;
|
|
391
397
|
}
|
|
392
398
|
|
|
393
399
|
export interface SyncBucketDataBatch {
|
|
@@ -434,3 +440,10 @@ export interface CompactOptions {
|
|
|
434
440
|
*/
|
|
435
441
|
compactBuckets?: string[];
|
|
436
442
|
}
|
|
443
|
+
|
|
444
|
+
export interface TerminateOptions {
|
|
445
|
+
/**
|
|
446
|
+
* If true, also clear the storage before terminating.
|
|
447
|
+
*/
|
|
448
|
+
clearStorage: boolean;
|
|
449
|
+
}
|