@powersync/service-module-mongodb-storage 0.0.0-dev-20250820110726 → 0.0.0-dev-20250827072023
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 +11 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/migrations/db/migrations/1752661449910-connection-reporting.js +0 -12
- package/dist/migrations/db/migrations/1752661449910-connection-reporting.js.map +1 -1
- package/dist/storage/MongoBucketStorage.js +1 -1
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/MongoReportStorage.d.ts +2 -3
- package/dist/storage/MongoReportStorage.js +8 -25
- package/dist/storage/MongoReportStorage.js.map +1 -1
- package/dist/storage/implementation/MongoBucketBatch.js +1 -1
- package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.js +1 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/PersistedBatch.js +1 -1
- package/dist/storage/implementation/PersistedBatch.js.map +1 -1
- package/dist/storage/storage-index.d.ts +2 -2
- package/dist/storage/storage-index.js +2 -2
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/utils/test-utils.d.ts +11 -0
- package/dist/utils/test-utils.js +40 -0
- package/dist/utils/test-utils.js.map +1 -0
- package/dist/{storage/implementation → utils}/util.d.ts +1 -6
- package/dist/{storage/implementation → utils}/util.js +0 -15
- package/dist/utils/util.js.map +1 -0
- package/dist/utils/utils-index.d.ts +2 -0
- package/dist/utils/utils-index.js +3 -0
- package/dist/utils/utils-index.js.map +1 -0
- package/package.json +8 -8
- package/src/index.ts +1 -0
- package/src/migrations/db/migrations/1752661449910-connection-reporting.ts +0 -12
- package/src/storage/MongoBucketStorage.ts +1 -1
- package/src/storage/MongoReportStorage.ts +11 -29
- package/src/storage/implementation/MongoBucketBatch.ts +1 -1
- package/src/storage/implementation/MongoSyncBucketStorage.ts +1 -1
- package/src/storage/implementation/PersistedBatch.ts +1 -1
- package/src/storage/storage-index.ts +2 -2
- package/src/utils/test-utils.ts +55 -0
- package/src/{storage/implementation → utils}/util.ts +1 -17
- package/src/utils/utils-index.ts +2 -0
- package/test/src/__snapshots__/connection-report-storage.test.ts.snap +63 -46
- package/test/src/__snapshots__/storage_sync.test.ts.snap +12 -11
- package/test/src/connection-report-storage.test.ts +69 -192
- package/test/src/util.ts +3 -5
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/storage/implementation/MongoTestReportStorageFactoryGenerator.d.ts +0 -7
- package/dist/storage/implementation/MongoTestReportStorageFactoryGenerator.js +0 -13
- package/dist/storage/implementation/MongoTestReportStorageFactoryGenerator.js.map +0 -1
- package/dist/storage/implementation/MongoTestStorageFactoryGenerator.d.ts +0 -7
- package/dist/storage/implementation/MongoTestStorageFactoryGenerator.js +0 -18
- package/dist/storage/implementation/MongoTestStorageFactoryGenerator.js.map +0 -1
- package/dist/storage/implementation/util.js.map +0 -1
- package/src/storage/implementation/MongoTestReportStorageFactoryGenerator.ts +0 -22
- package/src/storage/implementation/MongoTestStorageFactoryGenerator.ts +0 -28
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PowerSyncMongo } from '../storage/implementation/db.js';
|
|
2
|
+
import { TestStorageOptions } from '@powersync/service-core';
|
|
3
|
+
import { MongoReportStorage } from '../storage/MongoReportStorage.js';
|
|
4
|
+
import { MongoBucketStorage } from '../storage/MongoBucketStorage.js';
|
|
5
|
+
export type MongoTestStorageOptions = {
|
|
6
|
+
url: string;
|
|
7
|
+
isCI: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare function mongoTestStorageFactoryGenerator(factoryOptions: MongoTestStorageOptions): (options?: TestStorageOptions) => Promise<MongoBucketStorage>;
|
|
10
|
+
export declare function mongoTestReportStorageFactoryGenerator(factoryOptions: MongoTestStorageOptions): (options?: TestStorageOptions) => Promise<MongoReportStorage>;
|
|
11
|
+
export declare const connectMongoForTests: (url: string, isCI: boolean) => PowerSyncMongo;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { mongo } from '@powersync/lib-service-mongodb';
|
|
2
|
+
import { PowerSyncMongo } from '../storage/implementation/db.js';
|
|
3
|
+
import { MongoReportStorage } from '../storage/MongoReportStorage.js';
|
|
4
|
+
import { MongoBucketStorage } from '../storage/MongoBucketStorage.js';
|
|
5
|
+
export function mongoTestStorageFactoryGenerator(factoryOptions) {
|
|
6
|
+
return async (options) => {
|
|
7
|
+
const db = connectMongoForTests(factoryOptions.url, factoryOptions.isCI);
|
|
8
|
+
// None of the tests insert data into this collection, so it was never created
|
|
9
|
+
if (!(await db.db.listCollections({ name: db.bucket_parameters.collectionName }).hasNext())) {
|
|
10
|
+
await db.db.createCollection('bucket_parameters');
|
|
11
|
+
}
|
|
12
|
+
// Full migrations are not currently run for tests, so we manually create this
|
|
13
|
+
await db.createCheckpointEventsCollection();
|
|
14
|
+
if (!options?.doNotClear) {
|
|
15
|
+
await db.clear();
|
|
16
|
+
}
|
|
17
|
+
return new MongoBucketStorage(db, { slot_name_prefix: 'test_' });
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function mongoTestReportStorageFactoryGenerator(factoryOptions) {
|
|
21
|
+
return async (options) => {
|
|
22
|
+
const db = connectMongoForTests(factoryOptions.url, factoryOptions.isCI);
|
|
23
|
+
await db.createConnectionReportingCollection();
|
|
24
|
+
if (!options?.doNotClear) {
|
|
25
|
+
await db.clear();
|
|
26
|
+
}
|
|
27
|
+
return new MongoReportStorage(db);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export const connectMongoForTests = (url, isCI) => {
|
|
31
|
+
// Short timeout for tests, to fail fast when the server is not available.
|
|
32
|
+
// Slightly longer timeouts for CI, to avoid arbitrary test failures
|
|
33
|
+
const client = new mongo.MongoClient(url, {
|
|
34
|
+
connectTimeoutMS: isCI ? 15_000 : 5_000,
|
|
35
|
+
socketTimeoutMS: isCI ? 15_000 : 5_000,
|
|
36
|
+
serverSelectionTimeoutMS: isCI ? 15_000 : 2_500
|
|
37
|
+
});
|
|
38
|
+
return new PowerSyncMongo(client);
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=test-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../../src/utils/test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAOtE,MAAM,UAAU,gCAAgC,CAAC,cAAuC;IACtF,OAAO,KAAK,EAAE,OAA4B,EAAE,EAAE;QAC5C,MAAM,EAAE,GAAG,oBAAoB,CAAC,cAAc,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;QAEzE,8EAA8E;QAC9E,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YAC5F,MAAM,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;QACpD,CAAC;QAED,8EAA8E;QAC9E,MAAM,EAAE,CAAC,gCAAgC,EAAE,CAAC;QAE5C,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC;YACzB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;QAED,OAAO,IAAI,kBAAkB,CAAC,EAAE,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sCAAsC,CAAC,cAAuC;IAC5F,OAAO,KAAK,EAAE,OAA4B,EAAE,EAAE;QAC5C,MAAM,EAAE,GAAG,oBAAoB,CAAC,cAAc,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;QAEzE,MAAM,EAAE,CAAC,mCAAmC,EAAE,CAAC;QAE/C,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC;YACzB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;QAED,OAAO,IAAI,kBAAkB,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAW,EAAE,IAAa,EAAE,EAAE;IACjE,0EAA0E;IAC1E,oEAAoE;IACpE,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QACxC,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;QACvC,eAAe,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;QACtC,wBAAwB,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;KAChD,CAAC,CAAC;IACH,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC,CAAC"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import * as bson from 'bson';
|
|
2
2
|
import { mongo } from '@powersync/lib-service-mongodb';
|
|
3
3
|
import { storage, utils } from '@powersync/service-core';
|
|
4
|
-
import {
|
|
5
|
-
import { BucketDataDocument } from './models.js';
|
|
4
|
+
import { BucketDataDocument } from '../storage/implementation/models.js';
|
|
6
5
|
export declare function idPrefixFilter<T>(prefix: Partial<T>, rest: (keyof T)[]): mongo.Condition<T>;
|
|
7
6
|
export declare function generateSlotName(prefix: string, sync_rules_id: number): string;
|
|
8
7
|
/**
|
|
@@ -22,8 +21,4 @@ export declare function readSingleBatch<T>(cursor: mongo.FindCursor<T>): Promise
|
|
|
22
21
|
}>;
|
|
23
22
|
export declare function mapOpEntry(row: BucketDataDocument): utils.OplogEntry;
|
|
24
23
|
export declare function replicaIdToSubkey(table: bson.ObjectId, id: storage.ReplicaId): string;
|
|
25
|
-
/**
|
|
26
|
-
* Helper for unit tests
|
|
27
|
-
*/
|
|
28
|
-
export declare const connectMongoForTests: (url: string, isCI: boolean) => PowerSyncMongo;
|
|
29
24
|
export declare function setSessionSnapshotTime(session: mongo.ClientSession, time: bson.Timestamp): void;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import * as bson from 'bson';
|
|
2
2
|
import * as crypto from 'crypto';
|
|
3
3
|
import * as uuid from 'uuid';
|
|
4
|
-
import { mongo } from '@powersync/lib-service-mongodb';
|
|
5
4
|
import { storage, utils } from '@powersync/service-core';
|
|
6
|
-
import { PowerSyncMongo } from './db.js';
|
|
7
5
|
import { ServiceAssertionError } from '@powersync/lib-services-framework';
|
|
8
6
|
export function idPrefixFilter(prefix, rest) {
|
|
9
7
|
let filter = {
|
|
@@ -96,19 +94,6 @@ export function replicaIdToSubkey(table, id) {
|
|
|
96
94
|
return uuid.v5(repr, utils.ID_NAMESPACE);
|
|
97
95
|
}
|
|
98
96
|
}
|
|
99
|
-
/**
|
|
100
|
-
* Helper for unit tests
|
|
101
|
-
*/
|
|
102
|
-
export const connectMongoForTests = (url, isCI) => {
|
|
103
|
-
// Short timeout for tests, to fail fast when the server is not available.
|
|
104
|
-
// Slightly longer timeouts for CI, to avoid arbitrary test failures
|
|
105
|
-
const client = new mongo.MongoClient(url, {
|
|
106
|
-
connectTimeoutMS: isCI ? 15_000 : 5_000,
|
|
107
|
-
socketTimeoutMS: isCI ? 15_000 : 5_000,
|
|
108
|
-
serverSelectionTimeoutMS: isCI ? 15_000 : 2_500
|
|
109
|
-
});
|
|
110
|
-
return new PowerSyncMongo(client);
|
|
111
|
-
};
|
|
112
97
|
export function setSessionSnapshotTime(session, time) {
|
|
113
98
|
// This is a workaround for the lack of direct support for snapshot reads in the MongoDB driver.
|
|
114
99
|
if (!session.snapshotEnabled) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/utils/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,MAAM,UAAU,cAAc,CAAI,MAAkB,EAAE,IAAiB;IACrE,IAAI,MAAM,GAAG;QACX,IAAI,EAAE;YACJ,GAAG,MAAM;SACH;QACR,GAAG,EAAE;YACH,GAAG,MAAM;SACH;KACT,CAAC;IAEF,KAAK,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;IACtC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,aAAqB;IACpE,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,OAAO,GAAG,MAAM,GAAG,aAAa,IAAI,WAAW,EAAE,CAAC;AACpD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAI,MAA2B;IAClE,IAAI,CAAC;QACH,IAAI,IAAS,CAAC;QACd,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,2CAA2C;QAC3C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACtC,yCAAyC;QACzC,IAAI,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAC;QACtC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC;YACnC,0CAA0C;YAC1C,wEAAwE;YACxE,uEAAuE;YACvE,oCAAoC;YACpC,EAAE;YACF,4EAA4E;YAC5E,2DAA2D;YAC3D,gCAAgC;YAChC,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC3B,CAAC;YAAS,CAAC;QACT,iDAAiD;QACjD,uIAAuI;QACvI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAuB;IAChD,IAAI,GAAG,CAAC,EAAE,IAAI,KAAK,IAAI,GAAG,CAAC,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC1C,OAAO;YACL,KAAK,EAAE,KAAK,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9C,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,WAAW,EAAE,GAAG,CAAC,KAAK;YACtB,SAAS,EAAE,GAAG,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC9B,MAAM,EAAE,iBAAiB,CAAC,GAAG,CAAC,YAAa,EAAE,GAAG,CAAC,UAAW,CAAC;YAC7D,IAAI,EAAE,GAAG,CAAC,IAAI;SACf,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,cAAc;QAEd,OAAO;YACL,KAAK,EAAE,KAAK,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9C,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;SAC/B,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAoB,EAAE,EAAqB;IAC3E,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QACvB,mDAAmD;QACnD,OAAO,GAAG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IACtD,CAAC;SAAM,CAAC;QACN,oCAAoC;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAA4B,EAAE,IAAoB;IACvF,gGAAgG;IAChG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;QAC7B,MAAM,IAAI,qBAAqB,CAAC,oCAAoC,CAAC,CAAC;IACxE,CAAC;IACD,IAAK,OAAe,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;QACzC,OAAe,CAAC,YAAY,GAAG,IAAI,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,qBAAqB,CAAC,qCAAqC,CAAC,CAAC;IACzE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-index.js","sourceRoot":"","sources":["../../src/utils/utils-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAC;AAC9C,cAAc,WAAW,CAAC"}
|
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-20250827072023",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"license": "FSL-1.1-ALv2",
|
|
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.0.0-dev-
|
|
32
|
-
"@powersync/service-core": "0.0.0-dev-
|
|
33
|
-
"@powersync/service-types": "0.0.0-dev-
|
|
34
|
-
"@powersync/service-jsonbig": "0.0.0-dev-
|
|
35
|
-
"@powersync/service-sync-rules": "0.0.0-dev-
|
|
30
|
+
"@powersync/lib-service-mongodb": "0.0.0-dev-20250827072023",
|
|
31
|
+
"@powersync/lib-services-framework": "0.0.0-dev-20250827072023",
|
|
32
|
+
"@powersync/service-core": "0.0.0-dev-20250827072023",
|
|
33
|
+
"@powersync/service-types": "0.0.0-dev-20250827072023",
|
|
34
|
+
"@powersync/service-jsonbig": "0.0.0-dev-20250827072023",
|
|
35
|
+
"@powersync/service-sync-rules": "0.0.0-dev-20250827072023"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@powersync/service-core-tests": "0.0.0-dev-
|
|
38
|
+
"@powersync/service-core-tests": "0.0.0-dev-20250827072023"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsc -b",
|
package/src/index.ts
CHANGED
|
@@ -51,18 +51,6 @@ export const down: migrations.PowerSyncMigrationFunction = async (context) => {
|
|
|
51
51
|
const db = storage.createPowerSyncMongo(configuration.storage as MongoStorageConfig);
|
|
52
52
|
|
|
53
53
|
try {
|
|
54
|
-
if (await db.connection_report_events.indexExists('connection_list_index')) {
|
|
55
|
-
await db.connection_report_events.dropIndex('connection_list_index');
|
|
56
|
-
}
|
|
57
|
-
if (await db.connection_report_events.indexExists('connection_user_id_index')) {
|
|
58
|
-
await db.connection_report_events.dropIndex('connection_user_id_index');
|
|
59
|
-
}
|
|
60
|
-
if (await db.connection_report_events.indexExists('connection_client_id_index')) {
|
|
61
|
-
await db.connection_report_events.dropIndex('connection_client_id_index');
|
|
62
|
-
}
|
|
63
|
-
if (await db.connection_report_events.indexExists('connection_index')) {
|
|
64
|
-
await db.connection_report_events.dropIndex('connection_index');
|
|
65
|
-
}
|
|
66
54
|
await db.db.dropCollection('connection_report_events');
|
|
67
55
|
} finally {
|
|
68
56
|
await db.client.close();
|
|
@@ -12,7 +12,7 @@ import { PowerSyncMongo } from './implementation/db.js';
|
|
|
12
12
|
import { SyncRuleDocument } from './implementation/models.js';
|
|
13
13
|
import { MongoPersistedSyncRulesContent } from './implementation/MongoPersistedSyncRulesContent.js';
|
|
14
14
|
import { MongoSyncBucketStorage } from './implementation/MongoSyncBucketStorage.js';
|
|
15
|
-
import { generateSlotName } from '
|
|
15
|
+
import { generateSlotName } from '../utils/util.js';
|
|
16
16
|
|
|
17
17
|
export class MongoBucketStorage
|
|
18
18
|
extends BaseObserver<storage.BucketStorageFactoryListener>
|
|
@@ -30,10 +30,10 @@ export class MongoReportStorage implements storage.ReportStorage {
|
|
|
30
30
|
|
|
31
31
|
async getClientConnectionReports(
|
|
32
32
|
data: event_types.ClientConnectionReportRequest
|
|
33
|
-
): Promise<event_types.
|
|
33
|
+
): Promise<event_types.ClientConnectionReportResponse> {
|
|
34
34
|
const { start, end } = data;
|
|
35
35
|
const result = await this.db.connection_report_events
|
|
36
|
-
.aggregate<event_types.
|
|
36
|
+
.aggregate<event_types.ClientConnectionReportResponse>([
|
|
37
37
|
{
|
|
38
38
|
$match: {
|
|
39
39
|
connected_at: { $lte: end, $gte: start }
|
|
@@ -79,15 +79,13 @@ export class MongoReportStorage implements storage.ReportStorage {
|
|
|
79
79
|
}
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
|
-
async getConnectedClients(
|
|
83
|
-
const timeframeFilter = this.listConnectionsDateRange(data);
|
|
82
|
+
async getConnectedClients(): Promise<event_types.ClientConnectionReportResponse> {
|
|
84
83
|
const result = await this.db.connection_report_events
|
|
85
|
-
.aggregate<event_types.
|
|
84
|
+
.aggregate<event_types.ClientConnectionReportResponse>([
|
|
86
85
|
{
|
|
87
86
|
$match: {
|
|
88
87
|
disconnected_at: { $exists: false },
|
|
89
|
-
jwt_exp: { $gt: new Date() }
|
|
90
|
-
...timeframeFilter
|
|
88
|
+
jwt_exp: { $gt: new Date() }
|
|
91
89
|
}
|
|
92
90
|
},
|
|
93
91
|
this.connectionsFacetPipeline(),
|
|
@@ -102,10 +100,10 @@ export class MongoReportStorage implements storage.ReportStorage {
|
|
|
102
100
|
}
|
|
103
101
|
|
|
104
102
|
private parseJsDate(date: Date) {
|
|
105
|
-
const year = date.
|
|
106
|
-
const month = date.
|
|
107
|
-
const today = date.
|
|
108
|
-
const day = date.
|
|
103
|
+
const year = date.getUTCFullYear();
|
|
104
|
+
const month = date.getUTCMonth();
|
|
105
|
+
const today = date.getUTCDate();
|
|
106
|
+
const day = date.getUTCDay();
|
|
109
107
|
return {
|
|
110
108
|
year,
|
|
111
109
|
month,
|
|
@@ -171,24 +169,8 @@ export class MongoReportStorage implements storage.ReportStorage {
|
|
|
171
169
|
user_id: userId,
|
|
172
170
|
client_id: clientId,
|
|
173
171
|
connected_at: {
|
|
174
|
-
|
|
175
|
-
$
|
|
176
|
-
$lt: new Date(year, month, nextDay)
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
private listConnectionsDateRange(data: event_types.ClientConnectionsRequest) {
|
|
182
|
-
const { range } = data;
|
|
183
|
-
if (!range) {
|
|
184
|
-
return undefined;
|
|
185
|
-
}
|
|
186
|
-
const endDate = data.range?.end ? new Date(data.range.end) : new Date();
|
|
187
|
-
const startDate = new Date(range.start);
|
|
188
|
-
return {
|
|
189
|
-
connected_at: {
|
|
190
|
-
$lte: endDate,
|
|
191
|
-
$gte: startDate
|
|
172
|
+
$gte: new Date(Date.UTC(year, month, today)),
|
|
173
|
+
$lt: new Date(Date.UTC(year, month, nextDay))
|
|
192
174
|
}
|
|
193
175
|
};
|
|
194
176
|
}
|
|
@@ -28,7 +28,7 @@ import { MongoIdSequence } from './MongoIdSequence.js';
|
|
|
28
28
|
import { batchCreateCustomWriteCheckpoints } from './MongoWriteCheckpointAPI.js';
|
|
29
29
|
import { cacheKey, OperationBatch, RecordOperation } from './OperationBatch.js';
|
|
30
30
|
import { PersistedBatch } from './PersistedBatch.js';
|
|
31
|
-
import { idPrefixFilter } from '
|
|
31
|
+
import { idPrefixFilter } from '../../utils/util.js';
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* 15MB
|
|
@@ -32,7 +32,7 @@ import { BucketDataDocument, BucketDataKey, BucketStateDocument, SourceKey, Sour
|
|
|
32
32
|
import { MongoBucketBatch } from './MongoBucketBatch.js';
|
|
33
33
|
import { MongoCompactor } from './MongoCompactor.js';
|
|
34
34
|
import { MongoWriteCheckpointAPI } from './MongoWriteCheckpointAPI.js';
|
|
35
|
-
import { idPrefixFilter, mapOpEntry, readSingleBatch, setSessionSnapshotTime } from '
|
|
35
|
+
import { idPrefixFilter, mapOpEntry, readSingleBatch, setSessionSnapshotTime } from '../../utils/util.js';
|
|
36
36
|
import { MongoParameterCompactor } from './MongoParameterCompactor.js';
|
|
37
37
|
|
|
38
38
|
export class MongoSyncBucketStorage
|
|
@@ -7,9 +7,9 @@ export * from './implementation/MongoPersistedSyncRulesContent.js';
|
|
|
7
7
|
export * from './implementation/MongoStorageProvider.js';
|
|
8
8
|
export * from './implementation/MongoSyncBucketStorage.js';
|
|
9
9
|
export * from './implementation/MongoSyncRulesLock.js';
|
|
10
|
-
export * from './implementation/MongoTestStorageFactoryGenerator.js';
|
|
11
10
|
export * from './implementation/OperationBatch.js';
|
|
12
11
|
export * from './implementation/PersistedBatch.js';
|
|
13
|
-
export * from '
|
|
12
|
+
export * from '../utils/util.js';
|
|
14
13
|
export * from './MongoBucketStorage.js';
|
|
15
14
|
export * from './MongoReportStorage.js';
|
|
15
|
+
export * as test_utils from '../utils/test-utils.js';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { mongo } from '@powersync/lib-service-mongodb';
|
|
2
|
+
import { PowerSyncMongo } from '../storage/implementation/db.js';
|
|
3
|
+
import { TestStorageOptions } from '@powersync/service-core';
|
|
4
|
+
import { MongoReportStorage } from '../storage/MongoReportStorage.js';
|
|
5
|
+
import { MongoBucketStorage } from '../storage/MongoBucketStorage.js';
|
|
6
|
+
|
|
7
|
+
export type MongoTestStorageOptions = {
|
|
8
|
+
url: string;
|
|
9
|
+
isCI: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function mongoTestStorageFactoryGenerator(factoryOptions: MongoTestStorageOptions) {
|
|
13
|
+
return async (options?: TestStorageOptions) => {
|
|
14
|
+
const db = connectMongoForTests(factoryOptions.url, factoryOptions.isCI);
|
|
15
|
+
|
|
16
|
+
// None of the tests insert data into this collection, so it was never created
|
|
17
|
+
if (!(await db.db.listCollections({ name: db.bucket_parameters.collectionName }).hasNext())) {
|
|
18
|
+
await db.db.createCollection('bucket_parameters');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Full migrations are not currently run for tests, so we manually create this
|
|
22
|
+
await db.createCheckpointEventsCollection();
|
|
23
|
+
|
|
24
|
+
if (!options?.doNotClear) {
|
|
25
|
+
await db.clear();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return new MongoBucketStorage(db, { slot_name_prefix: 'test_' });
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function mongoTestReportStorageFactoryGenerator(factoryOptions: MongoTestStorageOptions) {
|
|
33
|
+
return async (options?: TestStorageOptions) => {
|
|
34
|
+
const db = connectMongoForTests(factoryOptions.url, factoryOptions.isCI);
|
|
35
|
+
|
|
36
|
+
await db.createConnectionReportingCollection();
|
|
37
|
+
|
|
38
|
+
if (!options?.doNotClear) {
|
|
39
|
+
await db.clear();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return new MongoReportStorage(db);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const connectMongoForTests = (url: string, isCI: boolean) => {
|
|
47
|
+
// Short timeout for tests, to fail fast when the server is not available.
|
|
48
|
+
// Slightly longer timeouts for CI, to avoid arbitrary test failures
|
|
49
|
+
const client = new mongo.MongoClient(url, {
|
|
50
|
+
connectTimeoutMS: isCI ? 15_000 : 5_000,
|
|
51
|
+
socketTimeoutMS: isCI ? 15_000 : 5_000,
|
|
52
|
+
serverSelectionTimeoutMS: isCI ? 15_000 : 2_500
|
|
53
|
+
});
|
|
54
|
+
return new PowerSyncMongo(client);
|
|
55
|
+
};
|
|
@@ -3,9 +3,7 @@ import * as crypto from 'crypto';
|
|
|
3
3
|
import * as uuid from 'uuid';
|
|
4
4
|
import { mongo } from '@powersync/lib-service-mongodb';
|
|
5
5
|
import { storage, utils } from '@powersync/service-core';
|
|
6
|
-
|
|
7
|
-
import { PowerSyncMongo } from './db.js';
|
|
8
|
-
import { BucketDataDocument } from './models.js';
|
|
6
|
+
import { BucketDataDocument } from '../storage/implementation/models.js';
|
|
9
7
|
import { ServiceAssertionError } from '@powersync/lib-services-framework';
|
|
10
8
|
|
|
11
9
|
export function idPrefixFilter<T>(prefix: Partial<T>, rest: (keyof T)[]): mongo.Condition<T> {
|
|
@@ -104,20 +102,6 @@ export function replicaIdToSubkey(table: bson.ObjectId, id: storage.ReplicaId):
|
|
|
104
102
|
}
|
|
105
103
|
}
|
|
106
104
|
|
|
107
|
-
/**
|
|
108
|
-
* Helper for unit tests
|
|
109
|
-
*/
|
|
110
|
-
export const connectMongoForTests = (url: string, isCI: boolean) => {
|
|
111
|
-
// Short timeout for tests, to fail fast when the server is not available.
|
|
112
|
-
// Slightly longer timeouts for CI, to avoid arbitrary test failures
|
|
113
|
-
const client = new mongo.MongoClient(url, {
|
|
114
|
-
connectTimeoutMS: isCI ? 15_000 : 5_000,
|
|
115
|
-
socketTimeoutMS: isCI ? 15_000 : 5_000,
|
|
116
|
-
serverSelectionTimeoutMS: isCI ? 15_000 : 2_500
|
|
117
|
-
});
|
|
118
|
-
return new PowerSyncMongo(client);
|
|
119
|
-
};
|
|
120
|
-
|
|
121
105
|
export function setSessionSnapshotTime(session: mongo.ClientSession, time: bson.Timestamp) {
|
|
122
106
|
// This is a workaround for the lack of direct support for snapshot reads in the MongoDB driver.
|
|
123
107
|
if (!session.snapshotEnabled) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
-
exports[`
|
|
3
|
+
exports[`Connection reporting storage > Should create a connection report if its after a day 1`] = `
|
|
4
4
|
[
|
|
5
5
|
{
|
|
6
6
|
"client_id": "client_week",
|
|
@@ -17,7 +17,7 @@ exports[`SDK reporting storage > Should create a connection report if its after
|
|
|
17
17
|
]
|
|
18
18
|
`;
|
|
19
19
|
|
|
20
|
-
exports[`
|
|
20
|
+
exports[`Connection reporting storage > Should delete rows older than specified range 1`] = `
|
|
21
21
|
{
|
|
22
22
|
"sdks": [
|
|
23
23
|
{
|
|
@@ -45,38 +45,39 @@ exports[`SDK reporting storage > Should delete rows older than specified range 1
|
|
|
45
45
|
"sdk": "powersync-js/1.24.5",
|
|
46
46
|
"users": 1,
|
|
47
47
|
},
|
|
48
|
-
],
|
|
49
|
-
"users": 5,
|
|
50
|
-
}
|
|
51
|
-
`;
|
|
52
|
-
|
|
53
|
-
exports[`SDK reporting storage > Should show connected users with start range 1`] = `
|
|
54
|
-
{
|
|
55
|
-
"sdks": [
|
|
56
48
|
{
|
|
57
49
|
"clients": 1,
|
|
58
|
-
"sdk": "
|
|
50
|
+
"sdk": "unknown",
|
|
59
51
|
"users": 1,
|
|
60
52
|
},
|
|
61
53
|
],
|
|
62
|
-
"users":
|
|
54
|
+
"users": 5,
|
|
63
55
|
}
|
|
64
56
|
`;
|
|
65
57
|
|
|
66
|
-
exports[`
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
"users": 1,
|
|
76
|
-
}
|
|
58
|
+
exports[`Connection reporting storage > Should update a connected connection report and make it disconnected 1`] = `
|
|
59
|
+
[
|
|
60
|
+
{
|
|
61
|
+
"client_id": "client_three",
|
|
62
|
+
"sdk": "powersync-js/1.21.2",
|
|
63
|
+
"user_agent": "powersync-js/1.21.0 powersync-web Firefox/141 linux",
|
|
64
|
+
"user_id": "user_three",
|
|
65
|
+
},
|
|
66
|
+
]
|
|
77
67
|
`;
|
|
78
68
|
|
|
79
|
-
exports[`
|
|
69
|
+
exports[`Connection reporting storage > Should update a connection report if its within a day 1`] = `
|
|
70
|
+
[
|
|
71
|
+
{
|
|
72
|
+
"client_id": "client_one",
|
|
73
|
+
"sdk": "powersync-dart/1.6.4",
|
|
74
|
+
"user_agent": "powersync-dart/1.6.4 Dart (flutter-web) Chrome/128 android",
|
|
75
|
+
"user_id": "user_one",
|
|
76
|
+
},
|
|
77
|
+
]
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
exports[`Report storage tests > Should show connection report data for user over the past day 1`] = `
|
|
80
81
|
{
|
|
81
82
|
"sdks": [
|
|
82
83
|
{
|
|
@@ -94,12 +95,17 @@ exports[`SDK reporting storage > Should show connection report data for user ove
|
|
|
94
95
|
"sdk": "powersync-js/1.21.4",
|
|
95
96
|
"users": 1,
|
|
96
97
|
},
|
|
98
|
+
{
|
|
99
|
+
"clients": 1,
|
|
100
|
+
"sdk": "unknown",
|
|
101
|
+
"users": 1,
|
|
102
|
+
},
|
|
97
103
|
],
|
|
98
104
|
"users": 3,
|
|
99
105
|
}
|
|
100
106
|
`;
|
|
101
107
|
|
|
102
|
-
exports[`
|
|
108
|
+
exports[`Report storage tests > Should show connection report data for user over the past month 1`] = `
|
|
103
109
|
{
|
|
104
110
|
"sdks": [
|
|
105
111
|
{
|
|
@@ -137,12 +143,17 @@ exports[`SDK reporting storage > Should show connection report data for user ove
|
|
|
137
143
|
"sdk": "powersync-js/1.24.5",
|
|
138
144
|
"users": 1,
|
|
139
145
|
},
|
|
146
|
+
{
|
|
147
|
+
"clients": 1,
|
|
148
|
+
"sdk": "unknown",
|
|
149
|
+
"users": 1,
|
|
150
|
+
},
|
|
140
151
|
],
|
|
141
152
|
"users": 7,
|
|
142
153
|
}
|
|
143
154
|
`;
|
|
144
155
|
|
|
145
|
-
exports[`
|
|
156
|
+
exports[`Report storage tests > Should show connection report data for user over the past week 1`] = `
|
|
146
157
|
{
|
|
147
158
|
"sdks": [
|
|
148
159
|
{
|
|
@@ -170,29 +181,35 @@ exports[`SDK reporting storage > Should show connection report data for user ove
|
|
|
170
181
|
"sdk": "powersync-js/1.24.5",
|
|
171
182
|
"users": 1,
|
|
172
183
|
},
|
|
184
|
+
{
|
|
185
|
+
"clients": 1,
|
|
186
|
+
"sdk": "unknown",
|
|
187
|
+
"users": 1,
|
|
188
|
+
},
|
|
173
189
|
],
|
|
174
190
|
"users": 5,
|
|
175
191
|
}
|
|
176
192
|
`;
|
|
177
193
|
|
|
178
|
-
exports[`
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
194
|
+
exports[`Report storage tests > Should show currently connected users 1`] = `
|
|
195
|
+
{
|
|
196
|
+
"sdks": [
|
|
197
|
+
{
|
|
198
|
+
"clients": 1,
|
|
199
|
+
"sdk": "powersync-dart/1.6.4",
|
|
200
|
+
"users": 1,
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"clients": 1,
|
|
204
|
+
"sdk": "powersync-js/1.21.1",
|
|
205
|
+
"users": 1,
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"clients": 1,
|
|
209
|
+
"sdk": "unknown",
|
|
210
|
+
"users": 1,
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
"users": 2,
|
|
214
|
+
}
|
|
198
215
|
`;
|