@powersync/service-core 0.0.0-dev-20241001150040 → 0.0.0-dev-20241002111637
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 +10 -5
- package/dist/api/diagnostics.js.map +1 -1
- package/dist/api/schema.js.map +1 -1
- package/dist/auth/CachedKeyCollector.js.map +1 -1
- package/dist/auth/KeySpec.js.map +1 -1
- package/dist/auth/KeyStore.js.map +1 -1
- package/dist/auth/LeakyBucket.js.map +1 -1
- package/dist/auth/RemoteJWKSCollector.d.ts +0 -2
- package/dist/auth/RemoteJWKSCollector.js.map +1 -1
- package/dist/db/mongo.js +3 -5
- package/dist/db/mongo.js.map +1 -1
- package/dist/entry/cli-entry.js.map +1 -1
- package/dist/entry/commands/compact-action.js.map +1 -1
- package/dist/entry/commands/migrate-action.js.map +1 -1
- package/dist/entry/commands/teardown-action.js.map +1 -1
- package/dist/locks/MongoLocks.js.map +1 -1
- package/dist/metrics/Metrics.js.map +1 -1
- package/dist/migrations/db/migrations/1684951997326-init.js.map +1 -1
- package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js.map +1 -1
- package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js.map +1 -1
- package/dist/migrations/executor.js.map +1 -1
- package/dist/migrations/migrations.js.map +1 -1
- package/dist/migrations/store/migration-store.js.map +1 -1
- package/dist/modules/ModuleManager.js.map +1 -1
- package/dist/replication/AbstractReplicationJob.d.ts +0 -1
- package/dist/replication/AbstractReplicator.js.map +1 -1
- package/dist/replication/ErrorRateLimiter.d.ts +0 -1
- package/dist/replication/ReplicationEngine.js.map +1 -1
- package/dist/replication/ReplicationModule.js.map +1 -1
- package/dist/routes/RouterEngine.js.map +1 -1
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/configure-fastify.d.ts +15 -7
- package/dist/routes/configure-rsocket.d.ts +0 -1
- package/dist/routes/configure-rsocket.js.map +1 -1
- package/dist/routes/endpoints/admin.d.ts +30 -12
- package/dist/routes/endpoints/admin.js.map +1 -1
- package/dist/routes/endpoints/checkpointing.js.map +1 -1
- package/dist/routes/endpoints/socket-route.js.map +1 -1
- package/dist/routes/endpoints/sync-rules.js.map +1 -1
- package/dist/routes/endpoints/sync-stream.d.ts +0 -1
- package/dist/routes/endpoints/sync-stream.js.map +1 -1
- package/dist/routes/hooks.js.map +1 -1
- package/dist/routes/route-register.js.map +1 -1
- package/dist/runner/teardown.js.map +1 -1
- package/dist/storage/BucketStorage.d.ts +0 -5
- package/dist/storage/BucketStorage.js.map +1 -1
- package/dist/storage/ChecksumCache.d.ts +19 -1
- package/dist/storage/ChecksumCache.js +8 -1
- package/dist/storage/ChecksumCache.js.map +1 -1
- package/dist/storage/MongoBucketStorage.d.ts +0 -1
- package/dist/storage/MongoBucketStorage.js +1 -1
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/StorageEngine.js.map +1 -1
- package/dist/storage/mongo/MongoBucketBatch.d.ts +0 -1
- package/dist/storage/mongo/MongoBucketBatch.js +1 -4
- package/dist/storage/mongo/MongoBucketBatch.js.map +1 -1
- package/dist/storage/mongo/MongoCompactor.js.map +1 -1
- package/dist/storage/mongo/MongoIdSequence.js.map +1 -1
- package/dist/storage/mongo/MongoPersistedSyncRulesContent.js.map +1 -1
- package/dist/storage/mongo/MongoSyncBucketStorage.js +14 -4
- package/dist/storage/mongo/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/mongo/MongoSyncRulesLock.js.map +1 -1
- package/dist/storage/mongo/OperationBatch.js.map +1 -1
- package/dist/storage/mongo/PersistedBatch.js.map +1 -1
- package/dist/storage/mongo/util.js.map +1 -1
- package/dist/storage/storage-index.d.ts +0 -1
- package/dist/storage/storage-index.js +0 -1
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/sync/BroadcastIterable.d.ts +0 -1
- package/dist/sync/BroadcastIterable.js.map +1 -1
- package/dist/sync/LastValueSink.d.ts +0 -1
- package/dist/sync/LastValueSink.js.map +1 -1
- package/dist/sync/merge.d.ts +0 -1
- package/dist/sync/merge.js.map +1 -1
- package/dist/sync/safeRace.js.map +1 -1
- package/dist/sync/sync.d.ts +0 -1
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/util.d.ts +0 -2
- package/dist/sync/util.js.map +1 -1
- package/dist/util/Mutex.js.map +1 -1
- package/dist/util/config/collectors/config-collector.js.map +1 -1
- package/dist/util/config/collectors/impl/base64-config-collector.js.map +1 -1
- package/dist/util/config/collectors/impl/filesystem-config-collector.js.map +1 -1
- package/dist/util/config/compound-config-collector.js +1 -1
- package/dist/util/config/compound-config-collector.js.map +1 -1
- package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js.map +1 -1
- package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js.map +1 -1
- package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.js.map +1 -1
- package/dist/util/config/sync-rules/sync-rules-provider.js.map +1 -1
- package/dist/util/config.js.map +1 -1
- package/dist/util/memory-tracking.js.map +1 -1
- package/dist/util/protocol-types.d.ts +0 -65
- package/dist/util/protocol-types.js +0 -7
- package/dist/util/protocol-types.js.map +1 -1
- package/dist/util/secs.js.map +1 -1
- package/dist/util/utils.d.ts +2 -1
- package/dist/util/utils.js +9 -2
- package/dist/util/utils.js.map +1 -1
- package/package.json +8 -9
- package/src/auth/RemoteJWKSCollector.ts +4 -1
- package/src/db/mongo.ts +3 -5
- package/src/storage/BucketStorage.ts +0 -5
- package/src/storage/ChecksumCache.ts +32 -2
- package/src/storage/mongo/MongoBucketBatch.ts +2 -6
- package/src/storage/mongo/MongoCompactor.ts +5 -1
- package/src/storage/mongo/MongoPersistedSyncRulesContent.ts +4 -1
- package/src/storage/mongo/MongoSyncBucketStorage.ts +18 -8
- package/src/storage/mongo/MongoSyncRulesLock.ts +6 -2
- package/src/storage/mongo/PersistedBatch.ts +4 -1
- package/src/storage/storage-index.ts +0 -1
- package/src/util/protocol-types.ts +0 -89
- package/src/util/utils.ts +11 -3
- package/test/src/__snapshots__/sync.test.ts.snap +7 -7
- package/test/src/checksum_cache.test.ts +26 -19
- package/test/src/compacting.test.ts +81 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +7 -1
- package/dist/storage/mongo/config.d.ts +0 -19
- package/dist/storage/mongo/config.js +0 -26
- package/dist/storage/mongo/config.js.map +0 -1
- package/src/storage/mongo/config.ts +0 -40
|
@@ -56,7 +56,7 @@ exports[`sync - mongodb > compacting data - invalidate checkpoint 2`] = `
|
|
|
56
56
|
"data": [
|
|
57
57
|
{
|
|
58
58
|
"checksum": 1859363232n,
|
|
59
|
-
"data": "{
|
|
59
|
+
"data": "{"id":"t1","description":"Test 1b"}",
|
|
60
60
|
"object_id": "t1",
|
|
61
61
|
"object_type": "test",
|
|
62
62
|
"op": "PUT",
|
|
@@ -65,7 +65,7 @@ exports[`sync - mongodb > compacting data - invalidate checkpoint 2`] = `
|
|
|
65
65
|
},
|
|
66
66
|
{
|
|
67
67
|
"checksum": 3028503153n,
|
|
68
|
-
"data": "{
|
|
68
|
+
"data": "{"id":"t2","description":"Test 2b"}",
|
|
69
69
|
"object_id": "t2",
|
|
70
70
|
"object_type": "test",
|
|
71
71
|
"op": "PUT",
|
|
@@ -146,7 +146,7 @@ exports[`sync - mongodb > sync global data 1`] = `
|
|
|
146
146
|
"data": [
|
|
147
147
|
{
|
|
148
148
|
"checksum": 920318466n,
|
|
149
|
-
"data": "{
|
|
149
|
+
"data": "{"id":"t1","description":"Test 1"}",
|
|
150
150
|
"object_id": "t1",
|
|
151
151
|
"object_type": "test",
|
|
152
152
|
"op": "PUT",
|
|
@@ -155,7 +155,7 @@ exports[`sync - mongodb > sync global data 1`] = `
|
|
|
155
155
|
},
|
|
156
156
|
{
|
|
157
157
|
"checksum": 3280762209n,
|
|
158
|
-
"data": "{
|
|
158
|
+
"data": "{"id":"t2","description":"Test 2"}",
|
|
159
159
|
"object_id": "t2",
|
|
160
160
|
"object_type": "test",
|
|
161
161
|
"op": "PUT",
|
|
@@ -199,7 +199,7 @@ exports[`sync - mongodb > sync legacy non-raw data 1`] = `
|
|
|
199
199
|
"checksum": 3442149460n,
|
|
200
200
|
"data": {
|
|
201
201
|
"description": "Test
|
|
202
|
-
|
|
202
|
+
"string"",
|
|
203
203
|
"id": "t1",
|
|
204
204
|
"large_num": 12345678901234567890n,
|
|
205
205
|
},
|
|
@@ -268,7 +268,7 @@ exports[`sync - mongodb > sync updates to global data 2`] = `
|
|
|
268
268
|
"data": [
|
|
269
269
|
{
|
|
270
270
|
"checksum": 920318466n,
|
|
271
|
-
"data": "{
|
|
271
|
+
"data": "{"id":"t1","description":"Test 1"}",
|
|
272
272
|
"object_id": "t1",
|
|
273
273
|
"object_type": "test",
|
|
274
274
|
"op": "PUT",
|
|
@@ -311,7 +311,7 @@ exports[`sync - mongodb > sync updates to global data 3`] = `
|
|
|
311
311
|
"data": [
|
|
312
312
|
{
|
|
313
313
|
"checksum": 3280762209n,
|
|
314
|
-
"data": "{
|
|
314
|
+
"data": "{"id":"t2","description":"Test 2"}",
|
|
315
315
|
"object_id": "t2",
|
|
316
316
|
"object_type": "test",
|
|
317
317
|
"op": "PUT",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ChecksumCache, FetchChecksums, FetchPartialBucketChecksum } from '@/storage/ChecksumCache.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { ChecksumCache, FetchChecksums, FetchPartialBucketChecksum, PartialChecksum } from '@/storage/ChecksumCache.js';
|
|
2
|
+
import { OpId } from '@/util/protocol-types.js';
|
|
3
|
+
import { addChecksums } from '@/util/util-index.js';
|
|
4
4
|
import * as crypto from 'node:crypto';
|
|
5
5
|
import { describe, expect, it } from 'vitest';
|
|
6
6
|
|
|
@@ -13,28 +13,22 @@ function testHash(bucket: string, checkpoint: OpId) {
|
|
|
13
13
|
return hash;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
function testPartialHash(request: FetchPartialBucketChecksum):
|
|
16
|
+
function testPartialHash(request: FetchPartialBucketChecksum): PartialChecksum {
|
|
17
17
|
if (request.start) {
|
|
18
18
|
const a = testHash(request.bucket, request.start);
|
|
19
19
|
const b = testHash(request.bucket, request.end);
|
|
20
|
-
return
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
{
|
|
27
|
-
// Subtract a
|
|
28
|
-
bucket: request.bucket,
|
|
29
|
-
checksum: -a,
|
|
30
|
-
count: -Number(request.start)
|
|
31
|
-
}
|
|
32
|
-
);
|
|
20
|
+
return {
|
|
21
|
+
bucket: request.bucket,
|
|
22
|
+
partialCount: Number(request.end) - Number(request.start),
|
|
23
|
+
partialChecksum: addChecksums(b, -a),
|
|
24
|
+
isFullChecksum: false
|
|
25
|
+
};
|
|
33
26
|
} else {
|
|
34
27
|
return {
|
|
35
28
|
bucket: request.bucket,
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
partialChecksum: testHash(request.bucket, request.end),
|
|
30
|
+
partialCount: Number(request.end),
|
|
31
|
+
isFullChecksum: true
|
|
38
32
|
};
|
|
39
33
|
}
|
|
40
34
|
}
|
|
@@ -433,4 +427,17 @@ describe('checksum cache', function () {
|
|
|
433
427
|
[{ bucket: 'test2', end: '123' }]
|
|
434
428
|
]);
|
|
435
429
|
});
|
|
430
|
+
|
|
431
|
+
it('should handle CLEAR/isFullChecksum checksums', async function () {
|
|
432
|
+
let lookups: FetchPartialBucketChecksum[][] = [];
|
|
433
|
+
const cache = factory(async (batch) => {
|
|
434
|
+
lookups.push(batch);
|
|
435
|
+
// This forces a `isFullChecksum: true` result
|
|
436
|
+
delete batch[0].start;
|
|
437
|
+
return fetchTestChecksums(batch);
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
expect(await cache.getChecksums('123', ['test'])).toEqual([TEST_123]);
|
|
441
|
+
expect(await cache.getChecksums('1234', ['test'])).toEqual([TEST_1234]);
|
|
442
|
+
});
|
|
436
443
|
});
|
|
@@ -61,6 +61,7 @@ bucket_definitions:
|
|
|
61
61
|
|
|
62
62
|
const batchBefore = await oneFromAsync(storage.getBucketDataBatch(checkpoint, new Map([['global[]', '0']])));
|
|
63
63
|
const dataBefore = batchBefore.batch.data;
|
|
64
|
+
const checksumBefore = await storage.getChecksums(checkpoint, ['global[]']);
|
|
64
65
|
|
|
65
66
|
expect(dataBefore).toMatchObject([
|
|
66
67
|
{
|
|
@@ -87,6 +88,7 @@ bucket_definitions:
|
|
|
87
88
|
|
|
88
89
|
const batchAfter = await oneFromAsync(storage.getBucketDataBatch(checkpoint, new Map([['global[]', '0']])));
|
|
89
90
|
const dataAfter = batchAfter.batch.data;
|
|
91
|
+
const checksumAfter = await storage.getChecksums(checkpoint, ['global[]']);
|
|
90
92
|
|
|
91
93
|
expect(batchAfter.targetOp).toEqual(3n);
|
|
92
94
|
expect(dataAfter).toMatchObject([
|
|
@@ -109,6 +111,8 @@ bucket_definitions:
|
|
|
109
111
|
}
|
|
110
112
|
]);
|
|
111
113
|
|
|
114
|
+
expect(checksumBefore.get('global[]')).toEqual(checksumAfter.get('global[]'));
|
|
115
|
+
|
|
112
116
|
validateCompactedBucket(dataBefore, dataAfter);
|
|
113
117
|
});
|
|
114
118
|
|
|
@@ -163,6 +167,7 @@ bucket_definitions:
|
|
|
163
167
|
|
|
164
168
|
const batchBefore = await oneFromAsync(storage.getBucketDataBatch(checkpoint, new Map([['global[]', '0']])));
|
|
165
169
|
const dataBefore = batchBefore.batch.data;
|
|
170
|
+
const checksumBefore = await storage.getChecksums(checkpoint, ['global[]']);
|
|
166
171
|
|
|
167
172
|
expect(dataBefore).toMatchObject([
|
|
168
173
|
{
|
|
@@ -195,6 +200,7 @@ bucket_definitions:
|
|
|
195
200
|
|
|
196
201
|
const batchAfter = await oneFromAsync(storage.getBucketDataBatch(checkpoint, new Map([['global[]', '0']])));
|
|
197
202
|
const dataAfter = batchAfter.batch.data;
|
|
203
|
+
const checksumAfter = await storage.getChecksums(checkpoint, ['global[]']);
|
|
198
204
|
|
|
199
205
|
expect(batchAfter.targetOp).toEqual(4n);
|
|
200
206
|
expect(dataAfter).toMatchObject([
|
|
@@ -210,7 +216,82 @@ bucket_definitions:
|
|
|
210
216
|
op_id: '4'
|
|
211
217
|
}
|
|
212
218
|
]);
|
|
219
|
+
expect(checksumBefore.get('global[]')).toEqual(checksumAfter.get('global[]'));
|
|
213
220
|
|
|
214
221
|
validateCompactedBucket(dataBefore, dataAfter);
|
|
215
222
|
});
|
|
223
|
+
|
|
224
|
+
test('compacting (3)', async () => {
|
|
225
|
+
const sync_rules = testRules(`
|
|
226
|
+
bucket_definitions:
|
|
227
|
+
global:
|
|
228
|
+
data: [select * from test]
|
|
229
|
+
`);
|
|
230
|
+
|
|
231
|
+
const storage = (await factory()).getInstance(sync_rules);
|
|
232
|
+
|
|
233
|
+
const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
|
|
234
|
+
await batch.save({
|
|
235
|
+
sourceTable: TEST_TABLE,
|
|
236
|
+
tag: 'insert',
|
|
237
|
+
after: {
|
|
238
|
+
id: 't1'
|
|
239
|
+
},
|
|
240
|
+
afterReplicaId: 't1'
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
await batch.save({
|
|
244
|
+
sourceTable: TEST_TABLE,
|
|
245
|
+
tag: 'insert',
|
|
246
|
+
after: {
|
|
247
|
+
id: 't2'
|
|
248
|
+
},
|
|
249
|
+
afterReplicaId: 't2'
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
await batch.save({
|
|
253
|
+
sourceTable: TEST_TABLE,
|
|
254
|
+
tag: 'delete',
|
|
255
|
+
before: {
|
|
256
|
+
id: 't1'
|
|
257
|
+
},
|
|
258
|
+
beforeReplicaId: 't1'
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const checkpoint1 = result!.flushed_op;
|
|
263
|
+
const checksumBefore = await storage.getChecksums(checkpoint1, ['global[]']);
|
|
264
|
+
|
|
265
|
+
const result2 = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
|
|
266
|
+
await batch.save({
|
|
267
|
+
sourceTable: TEST_TABLE,
|
|
268
|
+
tag: 'delete',
|
|
269
|
+
before: {
|
|
270
|
+
id: 't2'
|
|
271
|
+
},
|
|
272
|
+
beforeReplicaId: 't2'
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
const checkpoint2 = result2!.flushed_op;
|
|
276
|
+
|
|
277
|
+
await storage.compact(compactOptions);
|
|
278
|
+
|
|
279
|
+
const batchAfter = await oneFromAsync(storage.getBucketDataBatch(checkpoint2, new Map([['global[]', '0']])));
|
|
280
|
+
const dataAfter = batchAfter.batch.data;
|
|
281
|
+
const checksumAfter = await storage.getChecksums(checkpoint2, ['global[]']);
|
|
282
|
+
|
|
283
|
+
expect(batchAfter.targetOp).toEqual(4n);
|
|
284
|
+
expect(dataAfter).toMatchObject([
|
|
285
|
+
{
|
|
286
|
+
checksum: 1874612650,
|
|
287
|
+
op: 'CLEAR',
|
|
288
|
+
op_id: '4'
|
|
289
|
+
}
|
|
290
|
+
]);
|
|
291
|
+
expect(checksumAfter.get('global[]')).toEqual({
|
|
292
|
+
bucket: 'global[]',
|
|
293
|
+
count: 1,
|
|
294
|
+
checksum: 1874612650
|
|
295
|
+
});
|
|
296
|
+
});
|
|
216
297
|
}
|