@powersync/service-core 0.0.0-dev-20250122110924 → 0.0.0-dev-20250227082606
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 +84 -9
- package/dist/api/RouteAPI.d.ts +9 -1
- package/dist/api/diagnostics.js +107 -169
- package/dist/api/diagnostics.js.map +1 -1
- package/dist/auth/CachedKeyCollector.js +26 -25
- package/dist/auth/CachedKeyCollector.js.map +1 -1
- package/dist/auth/CompoundKeyCollector.js +1 -0
- package/dist/auth/CompoundKeyCollector.js.map +1 -1
- package/dist/auth/KeySpec.js +3 -0
- package/dist/auth/KeySpec.js.map +1 -1
- package/dist/auth/KeyStore.js +4 -0
- package/dist/auth/KeyStore.js.map +1 -1
- package/dist/auth/LeakyBucket.js +5 -0
- package/dist/auth/LeakyBucket.js.map +1 -1
- package/dist/auth/RemoteJWKSCollector.js +4 -1
- package/dist/auth/RemoteJWKSCollector.js.map +1 -1
- package/dist/auth/StaticKeyCollector.js +1 -0
- package/dist/auth/StaticKeyCollector.js.map +1 -1
- package/dist/auth/StaticSupabaseKeyCollector.js +1 -0
- package/dist/auth/StaticSupabaseKeyCollector.js.map +1 -1
- package/dist/entry/commands/compact-action.js +10 -73
- package/dist/entry/commands/compact-action.js.map +1 -1
- package/dist/metrics/Metrics.js +35 -1
- package/dist/metrics/Metrics.js.map +1 -1
- package/dist/modules/AbstractModule.d.ts +1 -1
- package/dist/modules/AbstractModule.js +2 -0
- package/dist/modules/AbstractModule.js.map +1 -1
- package/dist/modules/ModuleManager.js +1 -3
- package/dist/modules/ModuleManager.js.map +1 -1
- package/dist/replication/AbstractReplicationJob.js +4 -2
- package/dist/replication/AbstractReplicationJob.js.map +1 -1
- package/dist/replication/AbstractReplicator.js +26 -88
- package/dist/replication/AbstractReplicator.js.map +1 -1
- package/dist/replication/ReplicationEngine.js +1 -3
- package/dist/replication/ReplicationEngine.js.map +1 -1
- package/dist/replication/ReplicationModule.js +3 -0
- package/dist/replication/ReplicationModule.js.map +1 -1
- package/dist/routes/RouterEngine.js +8 -0
- package/dist/routes/RouterEngine.js.map +1 -1
- package/dist/routes/configure-fastify.d.ts +3 -3
- package/dist/routes/endpoints/admin.d.ts +6 -6
- package/dist/routes/endpoints/admin.js +4 -1
- package/dist/routes/endpoints/admin.js.map +1 -1
- package/dist/routes/endpoints/checkpointing.js +17 -86
- package/dist/routes/endpoints/checkpointing.js.map +1 -1
- package/dist/routes/endpoints/socket-route.js +7 -6
- package/dist/routes/endpoints/socket-route.js.map +1 -1
- package/dist/routes/endpoints/sync-rules.js +7 -2
- package/dist/routes/endpoints/sync-rules.js.map +1 -1
- package/dist/routes/endpoints/sync-stream.js +7 -6
- package/dist/routes/endpoints/sync-stream.js.map +1 -1
- package/dist/runner/teardown.js +5 -67
- package/dist/runner/teardown.js.map +1 -1
- package/dist/storage/BucketStorage.d.ts +8 -414
- package/dist/storage/BucketStorage.js +9 -7
- package/dist/storage/BucketStorage.js.map +1 -1
- package/dist/storage/BucketStorageBatch.d.ts +130 -0
- package/dist/storage/BucketStorageBatch.js +10 -0
- package/dist/storage/BucketStorageBatch.js.map +1 -0
- package/dist/storage/BucketStorageFactory.d.ts +145 -0
- package/dist/storage/BucketStorageFactory.js +2 -0
- package/dist/storage/BucketStorageFactory.js.map +1 -0
- package/dist/storage/ChecksumCache.js +12 -7
- package/dist/storage/ChecksumCache.js.map +1 -1
- package/dist/storage/PersistedSyncRulesContent.d.ts +20 -0
- package/dist/storage/PersistedSyncRulesContent.js +2 -0
- package/dist/storage/PersistedSyncRulesContent.js.map +1 -0
- package/dist/storage/ReplicationEventPayload.d.ts +1 -1
- package/dist/storage/ReplicationLock.d.ts +4 -0
- package/dist/storage/ReplicationLock.js +2 -0
- package/dist/storage/ReplicationLock.js.map +1 -0
- package/dist/storage/SourceEntity.d.ts +6 -2
- package/dist/storage/SourceTable.d.ts +2 -2
- package/dist/storage/SourceTable.js +32 -25
- package/dist/storage/SourceTable.js.map +1 -1
- package/dist/storage/StorageEngine.d.ts +4 -4
- package/dist/storage/StorageEngine.js +6 -5
- package/dist/storage/StorageEngine.js.map +1 -1
- package/dist/storage/StorageProvider.d.ts +4 -1
- package/dist/storage/SyncRulesBucketStorage.d.ts +207 -0
- package/dist/storage/SyncRulesBucketStorage.js +7 -0
- package/dist/storage/SyncRulesBucketStorage.js.map +1 -0
- package/dist/storage/bson.d.ts +19 -6
- package/dist/storage/bson.js +18 -2
- package/dist/storage/bson.js.map +1 -1
- package/dist/storage/storage-index.d.ts +5 -0
- package/dist/storage/storage-index.js +5 -0
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/sync/BroadcastIterable.js +4 -3
- package/dist/sync/BroadcastIterable.js.map +1 -1
- package/dist/sync/BucketChecksumState.d.ts +95 -0
- package/dist/sync/BucketChecksumState.js +321 -0
- package/dist/sync/BucketChecksumState.js.map +1 -0
- package/dist/sync/LastValueSink.js +2 -0
- package/dist/sync/LastValueSink.js.map +1 -1
- package/dist/sync/RequestTracker.js +2 -4
- package/dist/sync/RequestTracker.js.map +1 -1
- package/dist/sync/SyncContext.d.ts +17 -0
- package/dist/sync/SyncContext.js +23 -0
- package/dist/sync/SyncContext.js.map +1 -0
- package/dist/sync/merge.js +4 -0
- package/dist/sync/merge.js.map +1 -1
- package/dist/sync/sync-index.d.ts +2 -0
- package/dist/sync/sync-index.js +2 -0
- package/dist/sync/sync-index.js.map +1 -1
- package/dist/sync/sync.d.ts +10 -4
- package/dist/sync/sync.js +143 -149
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/util.d.ts +9 -0
- package/dist/sync/util.js +46 -2
- package/dist/sync/util.js.map +1 -1
- package/dist/system/ServiceContext.d.ts +3 -0
- package/dist/system/ServiceContext.js +10 -0
- package/dist/system/ServiceContext.js.map +1 -1
- package/dist/util/Mutex.js +5 -0
- package/dist/util/Mutex.js.map +1 -1
- package/dist/util/checkpointing.d.ts +13 -0
- package/dist/util/checkpointing.js +29 -0
- package/dist/util/checkpointing.js.map +1 -0
- package/dist/util/config/compound-config-collector.js +16 -2
- package/dist/util/config/compound-config-collector.js.map +1 -1
- package/dist/util/config/defaults.d.ts +5 -0
- package/dist/util/config/defaults.js +6 -0
- package/dist/util/config/defaults.js.map +1 -0
- package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js +1 -0
- package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js.map +1 -1
- package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js +1 -0
- package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js.map +1 -1
- package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.js +1 -0
- package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.js.map +1 -1
- package/dist/util/config/sync-rules/sync-rules-provider.d.ts +2 -0
- package/dist/util/config/sync-rules/sync-rules-provider.js +4 -0
- package/dist/util/config/sync-rules/sync-rules-provider.js.map +1 -1
- package/dist/util/config/types.d.ts +8 -2
- package/dist/util/config/types.js.map +1 -1
- package/dist/util/memory-tracking.js +1 -1
- package/dist/util/memory-tracking.js.map +1 -1
- package/dist/util/protocol-types.d.ts +13 -4
- package/dist/util/util-index.d.ts +1 -0
- package/dist/util/util-index.js +1 -0
- package/dist/util/util-index.js.map +1 -1
- package/dist/util/utils.d.ts +0 -1
- package/dist/util/utils.js +0 -9
- package/dist/util/utils.js.map +1 -1
- package/package.json +6 -6
- package/src/api/RouteAPI.ts +11 -1
- package/src/api/diagnostics.ts +1 -1
- package/src/entry/commands/compact-action.ts +2 -3
- package/src/modules/AbstractModule.ts +1 -1
- package/src/replication/AbstractReplicator.ts +16 -15
- package/src/routes/RouterEngine.ts +1 -0
- package/src/routes/endpoints/admin.ts +4 -1
- package/src/routes/endpoints/checkpointing.ts +11 -22
- package/src/routes/endpoints/socket-route.ts +9 -6
- package/src/routes/endpoints/sync-rules.ts +7 -2
- package/src/routes/endpoints/sync-stream.ts +10 -6
- package/src/runner/teardown.ts +1 -1
- package/src/storage/BucketStorage.ts +8 -515
- package/src/storage/BucketStorageBatch.ts +158 -0
- package/src/storage/BucketStorageFactory.ts +166 -0
- package/src/storage/ChecksumCache.ts +1 -0
- package/src/storage/PersistedSyncRulesContent.ts +26 -0
- package/src/storage/ReplicationEventPayload.ts +1 -1
- package/src/storage/ReplicationLock.ts +5 -0
- package/src/storage/SourceEntity.ts +6 -2
- package/src/storage/SourceTable.ts +1 -1
- package/src/storage/StorageEngine.ts +4 -4
- package/src/storage/StorageProvider.ts +4 -1
- package/src/storage/SyncRulesBucketStorage.ts +265 -0
- package/src/storage/bson.ts +31 -11
- package/src/storage/storage-index.ts +5 -0
- package/src/sync/BucketChecksumState.ts +418 -0
- package/src/sync/SyncContext.ts +36 -0
- package/src/sync/sync-index.ts +2 -0
- package/src/sync/sync.ts +199 -177
- package/src/sync/util.ts +54 -0
- package/src/system/ServiceContext.ts +9 -0
- package/src/util/checkpointing.ts +41 -0
- package/src/util/config/compound-config-collector.ts +26 -2
- package/src/util/config/defaults.ts +5 -0
- package/src/util/config/sync-rules/impl/base64-sync-rules-collector.ts +1 -0
- package/src/util/config/sync-rules/impl/filesystem-sync-rules-collector.ts +1 -0
- package/src/util/config/sync-rules/impl/inline-sync-rules-collector.ts +1 -0
- package/src/util/config/sync-rules/sync-rules-provider.ts +6 -0
- package/src/util/config/types.ts +9 -2
- package/src/util/memory-tracking.ts +2 -2
- package/src/util/protocol-types.ts +16 -4
- package/src/util/util-index.ts +1 -0
- package/src/util/utils.ts +0 -10
- package/test/src/auth.test.ts +5 -5
- package/test/src/sync/BucketChecksumState.test.ts +580 -0
- package/test/src/sync/util.test.ts +34 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { logger, router, schema } from '@powersync/lib-services-framework';
|
|
2
2
|
import * as t from 'ts-codec';
|
|
3
3
|
|
|
4
|
-
import * as framework from '@powersync/lib-services-framework';
|
|
5
4
|
import * as util from '../../util/util-index.js';
|
|
6
5
|
import { authUser } from '../auth.js';
|
|
7
6
|
import { routeDefinition } from '../router.js';
|
|
@@ -25,14 +24,15 @@ export const writeCheckpoint = routeDefinition({
|
|
|
25
24
|
// Since we don't use LSNs anymore, the only way to get that is to wait.
|
|
26
25
|
const start = Date.now();
|
|
27
26
|
|
|
28
|
-
const head = await apiHandler.
|
|
27
|
+
const head = await apiHandler.createReplicationHead(async (head) => head);
|
|
29
28
|
|
|
30
29
|
const timeout = 50_000;
|
|
31
30
|
|
|
32
31
|
logger.info(`Waiting for LSN checkpoint: ${head}`);
|
|
33
32
|
while (Date.now() - start < timeout) {
|
|
34
|
-
const
|
|
35
|
-
|
|
33
|
+
const bucketStorage = await service_context.storageEngine.activeBucketStorage.getActiveStorage();
|
|
34
|
+
const cp = await bucketStorage?.getCheckpoint();
|
|
35
|
+
if (cp == null) {
|
|
36
36
|
throw new Error('No sync rules available');
|
|
37
37
|
}
|
|
38
38
|
if (cp.lsn && cp.lsn >= head) {
|
|
@@ -56,25 +56,14 @@ export const writeCheckpoint2 = routeDefinition({
|
|
|
56
56
|
|
|
57
57
|
const apiHandler = service_context.routerEngine!.getAPI();
|
|
58
58
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
storageEngine: { activeBucketStorage }
|
|
65
|
-
} = service_context;
|
|
66
|
-
|
|
67
|
-
const activeSyncRules = await activeBucketStorage.getActiveSyncRulesContent();
|
|
68
|
-
if (!activeSyncRules) {
|
|
69
|
-
throw new framework.errors.ValidationError(`Cannot create Write Checkpoint since no sync rules are active.`);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
using syncBucketStorage = activeBucketStorage.getInstance(activeSyncRules);
|
|
73
|
-
const writeCheckpoint = await syncBucketStorage.createManagedWriteCheckpoint({
|
|
74
|
-
user_id: full_user_id,
|
|
75
|
-
heads: { '1': currentCheckpoint }
|
|
59
|
+
const { replicationHead, writeCheckpoint } = await util.createWriteCheckpoint({
|
|
60
|
+
userId: user_id,
|
|
61
|
+
clientId: payload.params.client_id,
|
|
62
|
+
api: apiHandler,
|
|
63
|
+
storage: service_context.storageEngine.activeBucketStorage
|
|
76
64
|
});
|
|
77
|
-
|
|
65
|
+
|
|
66
|
+
logger.info(`Write checkpoint for ${user_id}/${payload.params.client_id}: ${writeCheckpoint} | ${replicationHead}`);
|
|
78
67
|
|
|
79
68
|
return {
|
|
80
69
|
write_checkpoint: String(writeCheckpoint)
|
|
@@ -13,7 +13,7 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
13
13
|
validator: schema.createTsCodecValidator(util.StreamingSyncRequest, { allowAdditional: true }),
|
|
14
14
|
handler: async ({ context, params, responder, observer, initialN, signal: upstreamSignal }) => {
|
|
15
15
|
const { service_context } = context;
|
|
16
|
-
const { routerEngine } = service_context;
|
|
16
|
+
const { routerEngine, syncContext } = service_context;
|
|
17
17
|
|
|
18
18
|
// Create our own controller that we can abort directly
|
|
19
19
|
const controller = new AbortController();
|
|
@@ -49,9 +49,9 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
49
49
|
const {
|
|
50
50
|
storageEngine: { activeBucketStorage }
|
|
51
51
|
} = service_context;
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
if (
|
|
52
|
+
|
|
53
|
+
const bucketStorage = await activeBucketStorage.getActiveStorage();
|
|
54
|
+
if (bucketStorage == null) {
|
|
55
55
|
responder.onError(
|
|
56
56
|
new errors.ServiceError({
|
|
57
57
|
status: 500,
|
|
@@ -63,6 +63,8 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
const syncRules = bucketStorage.getParsedSyncRules(routerEngine!.getAPI().getParseSyncRulesOptions());
|
|
67
|
+
|
|
66
68
|
const removeStopHandler = routerEngine!.addStopHandler(() => {
|
|
67
69
|
controller.abort();
|
|
68
70
|
});
|
|
@@ -71,8 +73,9 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
71
73
|
const tracker = new sync.RequestTracker();
|
|
72
74
|
try {
|
|
73
75
|
for await (const data of sync.streamResponse({
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
syncContext: syncContext,
|
|
77
|
+
bucketStorage: bucketStorage,
|
|
78
|
+
syncRules: syncRules,
|
|
76
79
|
params: {
|
|
77
80
|
...params,
|
|
78
81
|
binary_data: true // always true for web sockets
|
|
@@ -69,7 +69,9 @@ export const deploySyncRules = routeDefinition({
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
const sync_rules = await storageEngine.activeBucketStorage.updateSyncRules({
|
|
72
|
-
content: content
|
|
72
|
+
content: content,
|
|
73
|
+
// Aready validated above
|
|
74
|
+
validate: false
|
|
73
75
|
});
|
|
74
76
|
|
|
75
77
|
return {
|
|
@@ -167,7 +169,10 @@ export const reprocessSyncRules = routeDefinition({
|
|
|
167
169
|
}
|
|
168
170
|
|
|
169
171
|
const new_rules = await activeBucketStorage.updateSyncRules({
|
|
170
|
-
content: sync_rules.sync_rules.content
|
|
172
|
+
content: sync_rules.sync_rules.content,
|
|
173
|
+
// These sync rules already passed validation. But if the rules are not valid anymore due
|
|
174
|
+
// to a service change, we do want to report the error here.
|
|
175
|
+
validate: true
|
|
171
176
|
});
|
|
172
177
|
return {
|
|
173
178
|
slot_name: new_rules.slot_name
|
|
@@ -20,7 +20,7 @@ export const syncStreamed = routeDefinition({
|
|
|
20
20
|
validator: schema.createTsCodecValidator(util.StreamingSyncRequest, { allowAdditional: true }),
|
|
21
21
|
handler: async (payload) => {
|
|
22
22
|
const { service_context } = payload.context;
|
|
23
|
-
const { routerEngine, storageEngine } = service_context;
|
|
23
|
+
const { routerEngine, storageEngine, syncContext } = service_context;
|
|
24
24
|
const headers = payload.request.headers;
|
|
25
25
|
const userAgent = headers['x-user-agent'] ?? headers['user-agent'];
|
|
26
26
|
const clientId = payload.params.client_id;
|
|
@@ -36,15 +36,18 @@ export const syncStreamed = routeDefinition({
|
|
|
36
36
|
const params: util.StreamingSyncRequest = payload.params;
|
|
37
37
|
const syncParams = new RequestParameters(payload.context.token_payload!, payload.params.parameters ?? {});
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (
|
|
39
|
+
const bucketStorage = await storageEngine.activeBucketStorage.getActiveStorage();
|
|
40
|
+
|
|
41
|
+
if (bucketStorage == null) {
|
|
42
42
|
throw new errors.ServiceError({
|
|
43
43
|
status: 500,
|
|
44
44
|
code: ErrorCode.PSYNC_S2302,
|
|
45
45
|
description: 'No sync rules available'
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
+
|
|
49
|
+
const syncRules = bucketStorage.getParsedSyncRules(routerEngine!.getAPI().getParseSyncRulesOptions());
|
|
50
|
+
|
|
48
51
|
const controller = new AbortController();
|
|
49
52
|
const tracker = new sync.RequestTracker();
|
|
50
53
|
try {
|
|
@@ -53,8 +56,9 @@ export const syncStreamed = routeDefinition({
|
|
|
53
56
|
sync.transformToBytesTracked(
|
|
54
57
|
sync.ndjson(
|
|
55
58
|
sync.streamResponse({
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
syncContext: syncContext,
|
|
60
|
+
bucketStorage,
|
|
61
|
+
syncRules: syncRules,
|
|
58
62
|
params,
|
|
59
63
|
syncParams,
|
|
60
64
|
token: payload.context.token_payload!,
|
package/src/runner/teardown.ts
CHANGED
|
@@ -51,7 +51,7 @@ async function terminateSyncRules(storageFactory: storage.BucketStorageFactory,
|
|
|
51
51
|
|
|
52
52
|
// Mark the sync rules as terminated
|
|
53
53
|
for (let syncRules of combinedSyncRules) {
|
|
54
|
-
|
|
54
|
+
const syncRulesStorage = storageFactory.getInstance(syncRules);
|
|
55
55
|
// The storage will be dropped at the end of the teardown, so we don't need to clear it here
|
|
56
56
|
await syncRulesStorage.terminate({ clearStorage: false });
|
|
57
57
|
}
|