@powersync/service-core 0.0.0-dev-20240930091342 → 0.0.0-dev-20241001150444
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 +5 -6
- 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 +2 -0
- package/dist/auth/RemoteJWKSCollector.js.map +1 -1
- package/dist/db/mongo.js +5 -3
- package/dist/db/mongo.js.map +1 -1
- package/dist/entry/cli-entry.js.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 +1 -0
- package/dist/replication/AbstractReplicator.js.map +1 -1
- package/dist/replication/ErrorRateLimiter.d.ts +1 -0
- 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 +7 -15
- package/dist/routes/configure-rsocket.d.ts +1 -0
- package/dist/routes/configure-rsocket.js.map +1 -1
- package/dist/routes/endpoints/admin.d.ts +12 -30
- 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 +1 -0
- 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 +5 -0
- package/dist/storage/BucketStorage.js.map +1 -1
- package/dist/storage/ChecksumCache.js.map +1 -1
- package/dist/storage/MongoBucketStorage.d.ts +1 -0
- 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 +1 -0
- package/dist/storage/mongo/MongoBucketBatch.js +4 -1
- 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.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/config.d.ts +19 -0
- package/dist/storage/mongo/config.js +26 -0
- package/dist/storage/mongo/config.js.map +1 -0
- package/dist/storage/mongo/util.js.map +1 -1
- package/dist/storage/storage-index.d.ts +1 -0
- package/dist/storage/storage-index.js +1 -0
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/sync/BroadcastIterable.d.ts +1 -0
- package/dist/sync/BroadcastIterable.js.map +1 -1
- package/dist/sync/LastValueSink.d.ts +1 -0
- package/dist/sync/LastValueSink.js.map +1 -1
- package/dist/sync/merge.d.ts +1 -0
- package/dist/sync/merge.js.map +1 -1
- package/dist/sync/safeRace.js.map +1 -1
- package/dist/sync/sync.d.ts +1 -0
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/util.d.ts +2 -0
- 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/secs.js.map +1 -1
- package/dist/util/utils.js.map +1 -1
- package/package.json +9 -8
- package/src/auth/RemoteJWKSCollector.ts +1 -4
- package/src/db/mongo.ts +5 -3
- package/src/storage/BucketStorage.ts +5 -0
- package/src/storage/mongo/MongoBucketBatch.ts +6 -2
- package/src/storage/mongo/MongoCompactor.ts +1 -5
- package/src/storage/mongo/MongoPersistedSyncRulesContent.ts +1 -4
- package/src/storage/mongo/MongoSyncRulesLock.ts +2 -6
- package/src/storage/mongo/PersistedBatch.ts +1 -4
- package/src/storage/mongo/config.ts +40 -0
- package/src/storage/storage-index.ts +1 -0
- package/test/src/__snapshots__/sync.test.ts.snap +7 -7
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +1 -7
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
|
-
"version": "0.0.0-dev-
|
|
8
|
+
"version": "0.0.0-dev-20241001150444",
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"license": "FSL-1.1-Apache-2.0",
|
|
11
11
|
"type": "module",
|
|
@@ -29,14 +29,15 @@
|
|
|
29
29
|
"mongodb": "^6.7.0",
|
|
30
30
|
"node-fetch": "^3.3.2",
|
|
31
31
|
"ts-codec": "^1.2.2",
|
|
32
|
+
"uri-js": "^4.4.1",
|
|
32
33
|
"uuid": "^9.0.1",
|
|
33
34
|
"winston": "^3.13.0",
|
|
34
35
|
"yaml": "^2.3.2",
|
|
35
|
-
"@powersync/lib-services-framework": "0.0.0-dev-
|
|
36
|
+
"@powersync/lib-services-framework": "0.0.0-dev-20241001150444",
|
|
36
37
|
"@powersync/service-jsonbig": "0.17.10",
|
|
37
|
-
"@powersync/service-rsocket-router": "0.0.0-dev-
|
|
38
|
-
"@powersync/service-sync-rules": "0.0.0-dev-
|
|
39
|
-
"@powersync/service-types": "0.0.0-dev-
|
|
38
|
+
"@powersync/service-rsocket-router": "0.0.0-dev-20241001150444",
|
|
39
|
+
"@powersync/service-sync-rules": "0.0.0-dev-20241001150444",
|
|
40
|
+
"@powersync/service-types": "0.0.0-dev-20241001150444"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@types/async": "^3.2.24",
|
|
@@ -44,14 +45,14 @@
|
|
|
44
45
|
"@types/uuid": "^9.0.4",
|
|
45
46
|
"fastify": "4.23.2",
|
|
46
47
|
"fastify-plugin": "^4.5.1",
|
|
47
|
-
"typescript": "^5.
|
|
48
|
+
"typescript": "^5.2.2",
|
|
48
49
|
"vite-tsconfig-paths": "^4.3.2",
|
|
49
|
-
"vitest": "^
|
|
50
|
+
"vitest": "^0.34.6"
|
|
50
51
|
},
|
|
51
52
|
"scripts": {
|
|
52
53
|
"build": "tsc -b",
|
|
53
54
|
"build:tests": "tsc -b test/tsconfig.json",
|
|
54
|
-
"test": "vitest",
|
|
55
|
+
"test": "vitest --no-threads",
|
|
55
56
|
"clean": "rm -rf ./lib && tsc -b --clean"
|
|
56
57
|
}
|
|
57
58
|
}
|
|
@@ -22,10 +22,7 @@ export type RemoteJWKSCollectorOptions = {
|
|
|
22
22
|
export class RemoteJWKSCollector implements KeyCollector {
|
|
23
23
|
private url: URL;
|
|
24
24
|
|
|
25
|
-
constructor(
|
|
26
|
-
url: string,
|
|
27
|
-
protected options?: RemoteJWKSCollectorOptions
|
|
28
|
-
) {
|
|
25
|
+
constructor(url: string, protected options?: RemoteJWKSCollectorOptions) {
|
|
29
26
|
try {
|
|
30
27
|
this.url = new URL(url);
|
|
31
28
|
} catch (e) {
|
package/src/db/mongo.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as mongo from 'mongodb';
|
|
|
2
2
|
import * as timers from 'timers/promises';
|
|
3
3
|
|
|
4
4
|
import { configFile } from '@powersync/service-types';
|
|
5
|
+
import { normalizeMongoConfig } from '../storage/storage-index.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Time for new connection to timeout.
|
|
@@ -23,10 +24,11 @@ export const MONGO_SOCKET_TIMEOUT_MS = 60_000;
|
|
|
23
24
|
export const MONGO_OPERATION_TIMEOUT_MS = 30_000;
|
|
24
25
|
|
|
25
26
|
export function createMongoClient(config: configFile.PowerSyncConfig['storage']) {
|
|
26
|
-
|
|
27
|
+
const normalized = normalizeMongoConfig(config);
|
|
28
|
+
return new mongo.MongoClient(normalized.uri, {
|
|
27
29
|
auth: {
|
|
28
|
-
username:
|
|
29
|
-
password:
|
|
30
|
+
username: normalized.username,
|
|
31
|
+
password: normalized.password
|
|
30
32
|
},
|
|
31
33
|
// Time for connection to timeout
|
|
32
34
|
connectTimeoutMS: MONGO_CONNECT_TIMEOUT_MS,
|
|
@@ -339,6 +339,11 @@ export interface BucketStorageBatch {
|
|
|
339
339
|
*/
|
|
340
340
|
keepalive(lsn: string): Promise<boolean>;
|
|
341
341
|
|
|
342
|
+
/**
|
|
343
|
+
* Get the last checkpoint LSN, from either commit or keepalive.
|
|
344
|
+
*/
|
|
345
|
+
lastCheckpointLsn: string | null;
|
|
346
|
+
|
|
342
347
|
markSnapshotDone(tables: SourceTable[], no_checkpoint_before_lsn: string): Promise<SourceTable[]>;
|
|
343
348
|
}
|
|
344
349
|
|
|
@@ -7,7 +7,7 @@ import * as util from '../../util/util-index.js';
|
|
|
7
7
|
import { BucketStorageBatch, FlushedResult, mergeToast, SaveOptions } from '../BucketStorage.js';
|
|
8
8
|
import { SourceTable } from '../SourceTable.js';
|
|
9
9
|
import { PowerSyncMongo } from './db.js';
|
|
10
|
-
import { CurrentBucket, CurrentDataDocument, SourceKey } from './models.js';
|
|
10
|
+
import { CurrentBucket, CurrentDataDocument, SourceKey, SyncRuleDocument } from './models.js';
|
|
11
11
|
import { MongoIdSequence } from './MongoIdSequence.js';
|
|
12
12
|
import { cacheKey, OperationBatch, RecordOperation } from './OperationBatch.js';
|
|
13
13
|
import { PersistedBatch } from './PersistedBatch.js';
|
|
@@ -73,6 +73,10 @@ export class MongoBucketBatch implements BucketStorageBatch {
|
|
|
73
73
|
this.no_checkpoint_before_lsn = no_checkpoint_before_lsn;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
get lastCheckpointLsn() {
|
|
77
|
+
return this.last_checkpoint_lsn;
|
|
78
|
+
}
|
|
79
|
+
|
|
76
80
|
async flush(): Promise<FlushedResult | null> {
|
|
77
81
|
let result: FlushedResult | null = null;
|
|
78
82
|
// One flush may be split over multiple transactions.
|
|
@@ -535,7 +539,7 @@ export class MongoBucketBatch implements BucketStorageBatch {
|
|
|
535
539
|
async commit(lsn: string): Promise<boolean> {
|
|
536
540
|
await this.flush();
|
|
537
541
|
|
|
538
|
-
if (this.last_checkpoint_lsn != null && lsn
|
|
542
|
+
if (this.last_checkpoint_lsn != null && lsn < this.last_checkpoint_lsn) {
|
|
539
543
|
// When re-applying transactions, don't create a new checkpoint until
|
|
540
544
|
// we are past the last transaction.
|
|
541
545
|
logger.info(`Re-applied transaction ${lsn} - skipping checkpoint`);
|
|
@@ -58,11 +58,7 @@ export class MongoCompactor {
|
|
|
58
58
|
private maxOpId: bigint | undefined;
|
|
59
59
|
private buckets: string[] | undefined;
|
|
60
60
|
|
|
61
|
-
constructor(
|
|
62
|
-
private db: PowerSyncMongo,
|
|
63
|
-
private group_id: number,
|
|
64
|
-
options?: MongoCompactOptions
|
|
65
|
-
) {
|
|
61
|
+
constructor(private db: PowerSyncMongo, private group_id: number, options?: MongoCompactOptions) {
|
|
66
62
|
this.idLimitBytes = (options?.memoryLimitMB ?? DEFAULT_MEMORY_LIMIT_MB) * 1024 * 1024;
|
|
67
63
|
this.moveBatchLimit = options?.moveBatchLimit ?? DEFAULT_MOVE_BATCH_LIMIT;
|
|
68
64
|
this.moveBatchQueryLimit = options?.moveBatchQueryLimit ?? DEFAULT_MOVE_BATCH_QUERY_LIMIT;
|
|
@@ -19,10 +19,7 @@ export class MongoPersistedSyncRulesContent implements PersistedSyncRulesContent
|
|
|
19
19
|
|
|
20
20
|
public current_lock: MongoSyncRulesLock | null = null;
|
|
21
21
|
|
|
22
|
-
constructor(
|
|
23
|
-
private db: PowerSyncMongo,
|
|
24
|
-
doc: mongo.WithId<SyncRuleDocument>
|
|
25
|
-
) {
|
|
22
|
+
constructor(private db: PowerSyncMongo, doc: mongo.WithId<SyncRuleDocument>) {
|
|
26
23
|
this.id = doc._id;
|
|
27
24
|
this.sync_rules_content = doc.content;
|
|
28
25
|
this.last_checkpoint_lsn = doc.last_checkpoint_lsn;
|
|
@@ -9,7 +9,7 @@ import { logger } from '@powersync/lib-services-framework';
|
|
|
9
9
|
* replicates those sync rules at a time.
|
|
10
10
|
*/
|
|
11
11
|
export class MongoSyncRulesLock implements ReplicationLock {
|
|
12
|
-
private readonly refreshInterval: NodeJS.
|
|
12
|
+
private readonly refreshInterval: NodeJS.Timer;
|
|
13
13
|
|
|
14
14
|
static async createLock(db: PowerSyncMongo, sync_rules: PersistedSyncRulesContent): Promise<MongoSyncRulesLock> {
|
|
15
15
|
const lockId = crypto.randomBytes(8).toString('hex');
|
|
@@ -35,11 +35,7 @@ export class MongoSyncRulesLock implements ReplicationLock {
|
|
|
35
35
|
return new MongoSyncRulesLock(db, sync_rules.id, lockId);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
constructor(
|
|
39
|
-
private db: PowerSyncMongo,
|
|
40
|
-
public sync_rules_id: number,
|
|
41
|
-
private lock_id: string
|
|
42
|
-
) {
|
|
38
|
+
constructor(private db: PowerSyncMongo, public sync_rules_id: number, private lock_id: string) {
|
|
43
39
|
this.refreshInterval = setInterval(async () => {
|
|
44
40
|
try {
|
|
45
41
|
await this.refresh();
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as urijs from 'uri-js';
|
|
2
|
+
|
|
3
|
+
export interface MongoConnectionConfig {
|
|
4
|
+
uri: string;
|
|
5
|
+
username?: string;
|
|
6
|
+
password?: string;
|
|
7
|
+
database?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Validate and normalize connection options.
|
|
12
|
+
*
|
|
13
|
+
* Returns destructured options.
|
|
14
|
+
*
|
|
15
|
+
* For use by both storage and mongo module.
|
|
16
|
+
*/
|
|
17
|
+
export function normalizeMongoConfig(options: MongoConnectionConfig) {
|
|
18
|
+
let uri = urijs.parse(options.uri);
|
|
19
|
+
|
|
20
|
+
const database = options.database ?? uri.path?.substring(1) ?? '';
|
|
21
|
+
|
|
22
|
+
const userInfo = uri.userinfo?.split(':');
|
|
23
|
+
|
|
24
|
+
const username = options.username ?? userInfo?.[0];
|
|
25
|
+
const password = options.password ?? userInfo?.[1];
|
|
26
|
+
|
|
27
|
+
if (database == '') {
|
|
28
|
+
throw new Error(`database required`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
delete uri.userinfo;
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
uri: urijs.serialize(uri),
|
|
35
|
+
database,
|
|
36
|
+
|
|
37
|
+
username,
|
|
38
|
+
password
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -56,7 +56,7 @@ exports[`sync - mongodb > compacting data - invalidate checkpoint 2`] = `
|
|
|
56
56
|
"data": [
|
|
57
57
|
{
|
|
58
58
|
"checksum": 1859363232n,
|
|
59
|
-
"data": "{"id"
|
|
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": "{"id"
|
|
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": "{"id"
|
|
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": "{"id"
|
|
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
|
-
"string"",
|
|
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": "{"id"
|
|
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": "{"id"
|
|
314
|
+
"data": "{\\"id\\":\\"t2\\",\\"description\\":\\"Test 2\\"}",
|
|
315
315
|
"object_id": "t2",
|
|
316
316
|
"object_type": "test",
|
|
317
317
|
"op": "PUT",
|