@powersync/service-module-mongodb-storage 0.0.0-dev-20250618131818 → 0.0.0-dev-20250714115156
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 +40 -5
- package/dist/storage/implementation/MongoBucketBatch.js +6 -6
- package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
- package/dist/storage/implementation/MongoCompactor.js +2 -2
- package/dist/storage/implementation/MongoCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoStorageProvider.js +2 -0
- package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.js +4 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/PersistedBatch.js +2 -2
- package/dist/storage/implementation/PersistedBatch.js.map +1 -1
- package/dist/storage/implementation/db.js +5 -2
- package/dist/storage/implementation/db.js.map +1 -1
- package/dist/storage/implementation/models.d.ts +1 -1
- package/dist/storage/implementation/util.d.ts +0 -4
- package/dist/storage/implementation/util.js +1 -7
- package/dist/storage/implementation/util.js.map +1 -1
- package/package.json +6 -6
- package/src/storage/implementation/MongoBucketBatch.ts +6 -7
- package/src/storage/implementation/MongoCompactor.ts +2 -2
- package/src/storage/implementation/MongoStorageProvider.ts +2 -1
- package/src/storage/implementation/MongoSyncBucketStorage.ts +4 -1
- package/src/storage/implementation/PersistedBatch.ts +2 -2
- package/src/storage/implementation/db.ts +8 -2
- package/src/storage/implementation/models.ts +1 -1
- package/src/storage/implementation/util.ts +1 -8
- package/test/src/storage_sync.test.ts +7 -0
- package/tsconfig.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@powersync/service-module-mongodb-storage",
|
|
3
3
|
"repository": "https://github.com/powersync-ja/powersync-service",
|
|
4
4
|
"types": "dist/index.d.ts",
|
|
5
|
-
"version": "0.0.0-dev-
|
|
5
|
+
"version": "0.0.0-dev-20250714115156",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"license": "FSL-1.1-Apache-2.0",
|
|
8
8
|
"type": "module",
|
|
@@ -27,15 +27,15 @@
|
|
|
27
27
|
"lru-cache": "^10.2.2",
|
|
28
28
|
"ts-codec": "^1.3.0",
|
|
29
29
|
"uuid": "^11.1.0",
|
|
30
|
-
"@powersync/lib-service-mongodb": "0.0.0-dev-
|
|
31
|
-
"@powersync/lib-services-framework": "0.
|
|
32
|
-
"@powersync/service-core": "0.0.0-dev-
|
|
30
|
+
"@powersync/lib-service-mongodb": "0.0.0-dev-20250714115156",
|
|
31
|
+
"@powersync/lib-services-framework": "0.7.0",
|
|
32
|
+
"@powersync/service-core": "0.0.0-dev-20250714115156",
|
|
33
33
|
"@powersync/service-jsonbig": "0.17.10",
|
|
34
34
|
"@powersync/service-sync-rules": "0.27.0",
|
|
35
|
-
"@powersync/service-types": "0.0.0-dev-
|
|
35
|
+
"@powersync/service-types": "0.0.0-dev-20250714115156"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@powersync/service-core-tests": "0.0.0-dev-
|
|
38
|
+
"@powersync/service-core-tests": "0.0.0-dev-20250714115156"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsc -b",
|
|
@@ -133,7 +133,7 @@ export class MongoBucketBatch
|
|
|
133
133
|
let result: storage.FlushedResult | null = null;
|
|
134
134
|
// One flush may be split over multiple transactions.
|
|
135
135
|
// Each flushInner() is one transaction.
|
|
136
|
-
while (this.batch != null) {
|
|
136
|
+
while (this.batch != null || this.write_checkpoint_batch.length > 0) {
|
|
137
137
|
let r = await this.flushInner(options);
|
|
138
138
|
if (r) {
|
|
139
139
|
result = r;
|
|
@@ -144,17 +144,16 @@ export class MongoBucketBatch
|
|
|
144
144
|
|
|
145
145
|
private async flushInner(options?: storage.BatchBucketFlushOptions): Promise<storage.FlushedResult | null> {
|
|
146
146
|
const batch = this.batch;
|
|
147
|
-
if (batch == null) {
|
|
148
|
-
return null;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
147
|
let last_op: InternalOpId | null = null;
|
|
152
148
|
let resumeBatch: OperationBatch | null = null;
|
|
153
149
|
|
|
154
|
-
await this.withReplicationTransaction(`Flushing ${batch
|
|
155
|
-
|
|
150
|
+
await this.withReplicationTransaction(`Flushing ${batch?.length ?? 0} ops`, async (session, opSeq) => {
|
|
151
|
+
if (batch != null) {
|
|
152
|
+
resumeBatch = await this.replicateBatch(session, batch, opSeq, options);
|
|
153
|
+
}
|
|
156
154
|
|
|
157
155
|
if (this.write_checkpoint_batch.length > 0) {
|
|
156
|
+
this.logger.info(`Writing ${this.write_checkpoint_batch.length} custom write checkpoints`);
|
|
158
157
|
await batchCreateCustomWriteCheckpoints(this.db, session, this.write_checkpoint_batch, opSeq.next());
|
|
159
158
|
this.write_checkpoint_batch = [];
|
|
160
159
|
}
|
|
@@ -317,7 +317,7 @@ export class MongoCompactor {
|
|
|
317
317
|
let numberOfOpsToClear = 0;
|
|
318
318
|
for await (let op of query.stream()) {
|
|
319
319
|
if (op.op == 'MOVE' || op.op == 'REMOVE' || op.op == 'CLEAR') {
|
|
320
|
-
checksum = utils.addChecksums(checksum, op.checksum);
|
|
320
|
+
checksum = utils.addChecksums(checksum, Number(op.checksum));
|
|
321
321
|
lastOpId = op._id;
|
|
322
322
|
numberOfOpsToClear += 1;
|
|
323
323
|
if (op.op != 'CLEAR') {
|
|
@@ -358,7 +358,7 @@ export class MongoCompactor {
|
|
|
358
358
|
{
|
|
359
359
|
_id: lastOpId!,
|
|
360
360
|
op: 'CLEAR',
|
|
361
|
-
checksum: checksum,
|
|
361
|
+
checksum: BigInt(checksum),
|
|
362
362
|
data: null,
|
|
363
363
|
target_op: targetOp
|
|
364
364
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as lib_mongo from '@powersync/lib-service-mongodb';
|
|
2
2
|
import { ErrorCode, logger, ServiceAssertionError, ServiceError } from '@powersync/lib-services-framework';
|
|
3
|
-
import { storage } from '@powersync/service-core';
|
|
3
|
+
import { POWERSYNC_VERSION, storage } from '@powersync/service-core';
|
|
4
4
|
import { MongoStorageConfig } from '../../types/types.js';
|
|
5
5
|
import { MongoBucketStorage } from '../MongoBucketStorage.js';
|
|
6
6
|
import { PowerSyncMongo } from './db.js';
|
|
@@ -23,6 +23,7 @@ export class MongoStorageProvider implements storage.BucketStorageProvider {
|
|
|
23
23
|
|
|
24
24
|
const decodedConfig = MongoStorageConfig.decode(storage as any);
|
|
25
25
|
const client = lib_mongo.db.createMongoClient(decodedConfig, {
|
|
26
|
+
powersyncVersion: POWERSYNC_VERSION,
|
|
26
27
|
maxPoolSize: resolvedConfig.storage.max_pool_size ?? 8
|
|
27
28
|
});
|
|
28
29
|
|
|
@@ -473,7 +473,10 @@ export class MongoSyncBucketStorage
|
|
|
473
473
|
{
|
|
474
474
|
$group: {
|
|
475
475
|
_id: '$_id.b',
|
|
476
|
-
|
|
476
|
+
// Historically, checksum may be stored as 'int' or 'double'.
|
|
477
|
+
// More recently, this should be a 'long'.
|
|
478
|
+
// $toLong ensures that we always sum it as a long, avoiding inaccuracies in the calculations.
|
|
479
|
+
checksum_total: { $sum: { $toLong: '$checksum' } },
|
|
477
480
|
count: { $sum: 1 },
|
|
478
481
|
has_clear_op: {
|
|
479
482
|
$max: {
|
|
@@ -97,7 +97,7 @@ export class PersistedBatch {
|
|
|
97
97
|
remaining_buckets.set(key, b);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
const dchecksum = utils.hashDelete(replicaIdToSubkey(options.table.id, options.sourceKey));
|
|
100
|
+
const dchecksum = BigInt(utils.hashDelete(replicaIdToSubkey(options.table.id, options.sourceKey)));
|
|
101
101
|
|
|
102
102
|
for (const k of options.evaluated) {
|
|
103
103
|
const key = currentBucketKey(k);
|
|
@@ -133,7 +133,7 @@ export class PersistedBatch {
|
|
|
133
133
|
source_key: options.sourceKey,
|
|
134
134
|
table: k.table,
|
|
135
135
|
row_id: k.id,
|
|
136
|
-
checksum: checksum,
|
|
136
|
+
checksum: BigInt(checksum),
|
|
137
137
|
data: recordData
|
|
138
138
|
}
|
|
139
139
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as lib_mongo from '@powersync/lib-service-mongodb';
|
|
2
2
|
import { mongo } from '@powersync/lib-service-mongodb';
|
|
3
|
-
import { storage } from '@powersync/service-core';
|
|
3
|
+
import { POWERSYNC_VERSION, storage } from '@powersync/service-core';
|
|
4
4
|
|
|
5
5
|
import { MongoStorageConfig } from '../../types/types.js';
|
|
6
6
|
import {
|
|
@@ -130,5 +130,11 @@ export class PowerSyncMongo {
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
export function createPowerSyncMongo(config: MongoStorageConfig, options?: lib_mongo.MongoConnectionOptions) {
|
|
133
|
-
return new PowerSyncMongo(
|
|
133
|
+
return new PowerSyncMongo(
|
|
134
|
+
lib_mongo.createMongoClient(config, {
|
|
135
|
+
powersyncVersion: POWERSYNC_VERSION,
|
|
136
|
+
...options
|
|
137
|
+
}),
|
|
138
|
+
{ database: config.database }
|
|
139
|
+
);
|
|
134
140
|
}
|
|
@@ -104,20 +104,13 @@ export function replicaIdToSubkey(table: bson.ObjectId, id: storage.ReplicaId):
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
/**
|
|
108
|
-
* Helper function for creating a MongoDB client from consumers of this package
|
|
109
|
-
*/
|
|
110
|
-
export const createMongoClient = (url: string, options?: mongo.MongoClientOptions) => {
|
|
111
|
-
return new mongo.MongoClient(url, options);
|
|
112
|
-
};
|
|
113
|
-
|
|
114
107
|
/**
|
|
115
108
|
* Helper for unit tests
|
|
116
109
|
*/
|
|
117
110
|
export const connectMongoForTests = (url: string, isCI: boolean) => {
|
|
118
111
|
// Short timeout for tests, to fail fast when the server is not available.
|
|
119
112
|
// Slightly longer timeouts for CI, to avoid arbitrary test failures
|
|
120
|
-
const client =
|
|
113
|
+
const client = new mongo.MongoClient(url, {
|
|
121
114
|
connectTimeoutMS: isCI ? 15_000 : 5_000,
|
|
122
115
|
socketTimeoutMS: isCI ? 15_000 : 5_000,
|
|
123
116
|
serverSelectionTimeoutMS: isCI ? 15_000 : 2_500
|
|
@@ -117,5 +117,12 @@ describe('sync - mongodb', () => {
|
|
|
117
117
|
has_more: false,
|
|
118
118
|
next_after: '4'
|
|
119
119
|
});
|
|
120
|
+
|
|
121
|
+
// Test that the checksum type is correct.
|
|
122
|
+
// Specifically, test that it never persisted as double.
|
|
123
|
+
const checksumTypes = await factory.db.bucket_data
|
|
124
|
+
.aggregate([{ $group: { _id: { $type: '$checksum' }, count: { $sum: 1 } } }])
|
|
125
|
+
.toArray();
|
|
126
|
+
expect(checksumTypes).toEqual([{ _id: 'long', count: 4 }]);
|
|
120
127
|
});
|
|
121
128
|
});
|