@powersync/service-module-mongodb-storage 0.0.0-dev-20250716094055 → 0.0.0-dev-20250716120232

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @powersync/service-module-mongodb-storage
2
2
 
3
- ## 0.0.0-dev-20250716094055
3
+ ## 0.0.0-dev-20250716120232
4
4
 
5
5
  ### Patch Changes
6
6
 
@@ -8,9 +8,9 @@
8
8
  - Updated dependencies [71cf892]
9
9
  - Updated dependencies [ba1ceef]
10
10
  - Updated dependencies [f1431b6]
11
- - @powersync/lib-service-mongodb@0.0.0-dev-20250716094055
12
- - @powersync/service-core@0.0.0-dev-20250716094055
13
- - @powersync/service-types@0.0.0-dev-20250716094055
11
+ - @powersync/lib-service-mongodb@0.0.0-dev-20250716120232
12
+ - @powersync/service-core@0.0.0-dev-20250716120232
13
+ - @powersync/service-types@0.0.0-dev-20250716120232
14
14
 
15
15
  ## 0.10.3
16
16
 
@@ -0,0 +1,3 @@
1
+ import { migrations } from '@powersync/service-core';
2
+ export declare const up: migrations.PowerSyncMigrationFunction;
3
+ export declare const down: migrations.PowerSyncMigrationFunction;
@@ -0,0 +1,44 @@
1
+ import * as storage from '../../../storage/storage-index.js';
2
+ export const up = async (context) => {
3
+ const { service_context: { configuration } } = context;
4
+ const db = storage.createPowerSyncMongo(configuration.storage);
5
+ try {
6
+ await db.createSdkReportingCollection();
7
+ await db.sdk_report_events.createIndex({
8
+ connect_at: 1,
9
+ jwt_exp: 1,
10
+ disconnect_at: 1
11
+ }, { name: 'connect_at' });
12
+ await db.sdk_report_events.createIndex({
13
+ user_id: 1,
14
+ sdk: 1,
15
+ version: 1
16
+ }, { name: 'user_id' });
17
+ await db.sdk_report_events.createIndex({
18
+ client_id: 1
19
+ }, { name: 'client_id' });
20
+ }
21
+ finally {
22
+ await db.client.close();
23
+ }
24
+ };
25
+ export const down = async (context) => {
26
+ const { service_context: { configuration } } = context;
27
+ const db = storage.createPowerSyncMongo(configuration.storage);
28
+ try {
29
+ if (await db.write_checkpoints.indexExists('connect_at')) {
30
+ await db.write_checkpoints.dropIndex('connect_at');
31
+ }
32
+ if (await db.custom_write_checkpoints.indexExists('user_id')) {
33
+ await db.custom_write_checkpoints.dropIndex('user_id');
34
+ }
35
+ if (await db.custom_write_checkpoints.indexExists('client_id')) {
36
+ await db.custom_write_checkpoints.dropIndex('client_id');
37
+ }
38
+ await db.db.dropCollection('sdk_report_events');
39
+ }
40
+ finally {
41
+ await db.client.close();
42
+ }
43
+ };
44
+ //# sourceMappingURL=1752661449910-sdk-reporting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1752661449910-sdk-reporting.js","sourceRoot":"","sources":["../../../../src/migrations/db/migrations/1752661449910-sdk-reporting.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,mCAAmC,CAAC;AAG7D,MAAM,CAAC,MAAM,EAAE,GAA0C,KAAK,EAAE,OAAO,EAAE,EAAE;IACzE,MAAM,EACJ,eAAe,EAAE,EAAE,aAAa,EAAE,EACnC,GAAG,OAAO,CAAC;IACZ,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,aAAa,CAAC,OAA6B,CAAC,CAAC;IAErF,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,4BAA4B,EAAE,CAAC;QAExC,MAAM,EAAE,CAAC,iBAAiB,CAAC,WAAW,CACpC;YACE,UAAU,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,aAAa,EAAE,CAAC;SACjB,EACD,EAAE,IAAI,EAAE,YAAY,EAAE,CACvB,CAAC;QAEF,MAAM,EAAE,CAAC,iBAAiB,CAAC,WAAW,CACpC;YACE,OAAO,EAAE,CAAC;YACV,GAAG,EAAE,CAAC;YACN,OAAO,EAAE,CAAC;SACX,EACD,EAAE,IAAI,EAAE,SAAS,EAAE,CACpB,CAAC;QACF,MAAM,EAAE,CAAC,iBAAiB,CAAC,WAAW,CACpC;YACE,SAAS,EAAE,CAAC;SACb,EACD,EAAE,IAAI,EAAE,WAAW,EAAE,CACtB,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,IAAI,GAA0C,KAAK,EAAE,OAAO,EAAE,EAAE;IAC3E,MAAM,EACJ,eAAe,EAAE,EAAE,aAAa,EAAE,EACnC,GAAG,OAAO,CAAC;IAEZ,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,aAAa,CAAC,OAA6B,CAAC,CAAC;IAErF,IAAI,CAAC;QACH,IAAI,MAAM,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,CAAC;YACzD,MAAM,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,MAAM,EAAE,CAAC,wBAAwB,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7D,MAAM,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,MAAM,EAAE,CAAC,wBAAwB,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/D,MAAM,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC3D,CAAC;QACD,MAAM,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC;IAClD,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC,CAAC"}
@@ -1,13 +1,14 @@
1
1
  import { storage } from '@powersync/service-core';
2
2
  import { event_types } from '@powersync/service-types';
3
3
  import { PowerSyncMongo } from './implementation/db.js';
4
+ import { SdkConnectDocument } from './implementation/models.js';
4
5
  export declare class MongoReportStorage implements storage.ReportStorageFactory {
5
6
  private readonly client;
6
7
  readonly db: PowerSyncMongo;
7
8
  constructor(db: PowerSyncMongo);
8
9
  scrapeSdkData(data: event_types.PaginatedInstanceRequest): Promise<void>;
9
- reportSdkConnect(data: event_types.SdkConnectEventData): Promise<void>;
10
- reportSdkDisconnect(data: event_types.SdkDisconnectEventData): Promise<void>;
10
+ reportSdkConnect(data: SdkConnectDocument): Promise<void>;
11
+ reportSdkDisconnect(data: SdkConnectDocument): Promise<void>;
11
12
  listCurrentConnections(data: event_types.PaginatedInstanceRequest): Promise<void>;
12
13
  [Symbol.asyncDispose](): Promise<void>;
13
14
  }
@@ -9,10 +9,11 @@ export class MongoReportStorage {
9
9
  console.log('MongoReportStorage.scrapeSdkData', data);
10
10
  }
11
11
  async reportSdkConnect(data) {
12
- console.log('MongoReportStorage.reportSdkConnect', data);
12
+ await this.db.sdk_report_events.insertOne(data);
13
13
  }
14
14
  async reportSdkDisconnect(data) {
15
- console.log('MongoReportStorage.reportSdkDisconnect', data);
15
+ const { _id, ...rest } = data;
16
+ await this.db.sdk_report_events.findOneAndUpdate({ _id }, rest, { upsert: true });
16
17
  }
17
18
  async listCurrentConnections(data) {
18
19
  console.log('MongoReportStorage.listCurrentConnections', data);
@@ -1 +1 @@
1
- {"version":3,"file":"MongoReportStorage.js","sourceRoot":"","sources":["../../src/storage/MongoReportStorage.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,kBAAkB;IACZ,MAAM,CAAoB;IAC3B,EAAE,CAAiB;IAEnC,YAAY,EAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC;QACxB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAA0C;QAC5D,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAqC;QAC1D,OAAO,CAAC,GAAG,CAAC,qCAAqC,EAAE,IAAI,CAAC,CAAC;IAC3D,CAAC;IACD,KAAK,CAAC,mBAAmB,CAAC,IAAwC;QAChE,OAAO,CAAC,GAAG,CAAC,wCAAwC,EAAE,IAAI,CAAC,CAAC;IAC9D,CAAC;IACD,KAAK,CAAC,sBAAsB,CAAC,IAA0C;QACrE,OAAO,CAAC,GAAG,CAAC,2CAA2C,EAAE,IAAI,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;QACzB,QAAQ;IACV,CAAC;CACF"}
1
+ {"version":3,"file":"MongoReportStorage.js","sourceRoot":"","sources":["../../src/storage/MongoReportStorage.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,kBAAkB;IACZ,MAAM,CAAoB;IAC3B,EAAE,CAAiB;IAEnC,YAAY,EAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC;QACxB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAA0C;QAC5D,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAwB;QAC7C,MAAM,IAAI,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC;IACD,KAAK,CAAC,mBAAmB,CAAC,IAAwB;QAChD,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;QAC9B,MAAM,IAAI,CAAC,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACpF,CAAC;IACD,KAAK,CAAC,sBAAsB,CAAC,IAA0C;QACrE,OAAO,CAAC,GAAG,CAAC,2CAA2C,EAAE,IAAI,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;QACzB,QAAQ;IACV,CAAC;CACF"}
@@ -1,7 +1,7 @@
1
1
  import * as lib_mongo from '@powersync/lib-service-mongodb';
2
2
  import { mongo } from '@powersync/lib-service-mongodb';
3
3
  import { MongoStorageConfig } from '../../types/types.js';
4
- import { BucketDataDocument, BucketParameterDocument, BucketStateDocument, CheckpointEventDocument, CurrentDataDocument, CustomWriteCheckpointDocument, IdSequenceDocument, InstanceDocument, SdkConnectEventDocument, SourceTableDocument, SyncRuleDocument, WriteCheckpointDocument } from './models.js';
4
+ import { BucketDataDocument, BucketParameterDocument, BucketStateDocument, CheckpointEventDocument, CurrentDataDocument, CustomWriteCheckpointDocument, IdSequenceDocument, InstanceDocument, SdkConnectDocument, SourceTableDocument, SyncRuleDocument, WriteCheckpointDocument } from './models.js';
5
5
  export interface PowerSyncMongoOptions {
6
6
  /**
7
7
  * Optional - uses the database from the MongoClient connection URI if not specified.
@@ -21,7 +21,7 @@ export declare class PowerSyncMongo {
21
21
  readonly locks: mongo.Collection<lib_mongo.locks.Lock>;
22
22
  readonly bucket_state: mongo.Collection<BucketStateDocument>;
23
23
  readonly checkpoint_events: mongo.Collection<CheckpointEventDocument>;
24
- readonly sdk_connect_events: mongo.Collection<SdkConnectEventDocument>;
24
+ readonly sdk_report_events: mongo.Collection<SdkConnectDocument>;
25
25
  readonly client: mongo.MongoClient;
26
26
  readonly db: mongo.Db;
27
27
  constructor(client: mongo.MongoClient, options?: PowerSyncMongoOptions);
@@ -45,5 +45,9 @@ export declare class PowerSyncMongo {
45
45
  * Only use in migrations and tests.
46
46
  */
47
47
  createCheckpointEventsCollection(): Promise<void>;
48
+ /**
49
+ * Only use in migrations and tests.
50
+ */
51
+ createSdkReportingCollection(): Promise<void>;
48
52
  }
49
53
  export declare function createPowerSyncMongo(config: MongoStorageConfig, options?: lib_mongo.MongoConnectionOptions): PowerSyncMongo;
@@ -13,7 +13,7 @@ export class PowerSyncMongo {
13
13
  locks;
14
14
  bucket_state;
15
15
  checkpoint_events;
16
- sdk_connect_events;
16
+ sdk_report_events;
17
17
  client;
18
18
  db;
19
19
  constructor(client, options) {
@@ -34,7 +34,7 @@ export class PowerSyncMongo {
34
34
  this.locks = this.db.collection('locks');
35
35
  this.bucket_state = this.db.collection('bucket_state');
36
36
  this.checkpoint_events = this.db.collection('checkpoint_events');
37
- this.sdk_connect_events = this.db.collection('sdk_connect_events');
37
+ this.sdk_report_events = this.db.collection('sdk_report_events');
38
38
  }
39
39
  /**
40
40
  * Clear all collections.
@@ -97,6 +97,19 @@ export class PowerSyncMongo {
97
97
  max: 50 // max number of documents
98
98
  });
99
99
  }
100
+ /**
101
+ * Only use in migrations and tests.
102
+ */
103
+ async createSdkReportingCollection() {
104
+ const existingCollections = await this.db
105
+ .listCollections({ name: 'sdk_report_events' }, { nameOnly: false })
106
+ .toArray();
107
+ const collection = existingCollections[0];
108
+ if (collection != null) {
109
+ return;
110
+ }
111
+ await this.db.createCollection('sdk_report_events');
112
+ }
100
113
  }
101
114
  export function createPowerSyncMongo(config, options) {
102
115
  return new PowerSyncMongo(lib_mongo.createMongoClient(config, {
@@ -1 +1 @@
1
- {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/storage/implementation/db.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/storage/implementation/db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,gCAAgC,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAyBrE,MAAM,OAAO,cAAc;IAChB,YAAY,CAAwC;IACpD,WAAW,CAAuC;IAClD,iBAAiB,CAA4C;IAC7D,cAAc,CAAuC;IACrD,UAAU,CAAqC;IAC/C,aAAa,CAAwC;IACrD,wBAAwB,CAAkD;IAC1E,iBAAiB,CAA4C;IAC7D,QAAQ,CAAqC;IAC7C,KAAK,CAAyC;IAC9C,YAAY,CAAwC;IACpD,iBAAiB,CAA4C;IAC7D,iBAAiB,CAAuC;IAExD,MAAM,CAAoB;IAC1B,EAAE,CAAW;IAEtB,YAAY,MAAyB,EAAE,OAA+B;QACpE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE;YACtC,GAAG,OAAO,CAAC,iCAAiC;SAC7C,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QAEb,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC,UAAU,CAAsB,cAAc,CAAC,CAAC;QACvE,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QAChD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,CAAC,wBAAwB,GAAG,EAAE,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAAC;QAC1E,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;QACvD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;QACjE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACvC,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACzC,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACvC,MAAM,IAAI,CAAC,wBAAwB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,gBAAgB;QACpB,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,EAAS,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC;IACnF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gCAAgC;QACpC,6FAA6F;QAC7F,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,EAAE;aACtC,eAAe,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;aACnE,OAAO,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;gBAChC,oEAAoE;gBACpE,MAAM,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,iDAAiD;gBACjD,OAAO;YACT,CAAC;QACH,CAAC;QAED,MAAM,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,mBAAmB,EAAE;YAClD,MAAM,EAAE,IAAI;YACZ,sFAAsF;YACtF,mFAAmF;YACnF,iFAAiF;YACjF,4BAA4B;YAC5B,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,gBAAgB;YACjC,GAAG,EAAE,EAAE,CAAC,0BAA0B;SACnC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,4BAA4B;QAChC,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,EAAE;aACtC,eAAe,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;aACnE,OAAO,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QACD,MAAM,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;IACtD,CAAC;CACF;AAED,MAAM,UAAU,oBAAoB,CAAC,MAA0B,EAAE,OAA0C;IACzG,OAAO,IAAI,cAAc,CACvB,SAAS,CAAC,iBAAiB,CAAC,MAAM,EAAE;QAClC,gBAAgB,EAAE,iBAAiB;QACnC,GAAG,OAAO;KACX,CAAC,EACF,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAC9B,CAAC;AACJ,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { InternalOpId, storage } from '@powersync/service-core';
2
2
  import { SqliteJsonValue } from '@powersync/service-sync-rules';
3
3
  import * as bson from 'bson';
4
+ import { event_types } from '@powersync/service-types';
4
5
  /**
5
6
  * Replica id uniquely identifying a row on the source database.
6
7
  *
@@ -183,11 +184,5 @@ export interface WriteCheckpointDocument {
183
184
  export interface InstanceDocument {
184
185
  _id: string;
185
186
  }
186
- export interface SdkConnectEventDocument {
187
- version: string;
188
- sdk: string;
189
- user_agent: string;
190
- client_id: string;
191
- user_id: string;
192
- jwt_exp: number;
187
+ export interface SdkConnectDocument extends event_types.SdkConnectDocument {
193
188
  }
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-20250716094055",
5
+ "version": "0.0.0-dev-20250716120232",
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-20250716094055",
30
+ "@powersync/lib-service-mongodb": "0.0.0-dev-20250716120232",
31
31
  "@powersync/lib-services-framework": "0.7.0",
32
- "@powersync/service-core": "0.0.0-dev-20250716094055",
33
- "@powersync/service-types": "0.0.0-dev-20250716094055",
32
+ "@powersync/service-core": "0.0.0-dev-20250716120232",
33
+ "@powersync/service-types": "0.0.0-dev-20250716120232",
34
34
  "@powersync/service-jsonbig": "0.17.10",
35
35
  "@powersync/service-sync-rules": "0.27.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@powersync/service-core-tests": "0.0.0-dev-20250716094055"
38
+ "@powersync/service-core-tests": "0.0.0-dev-20250716120232"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsc -b",
@@ -0,0 +1,63 @@
1
+ import { migrations } from '@powersync/service-core';
2
+ import * as storage from '../../../storage/storage-index.js';
3
+ import { MongoStorageConfig } from '../../../types/types.js';
4
+
5
+ export const up: migrations.PowerSyncMigrationFunction = async (context) => {
6
+ const {
7
+ service_context: { configuration }
8
+ } = context;
9
+ const db = storage.createPowerSyncMongo(configuration.storage as MongoStorageConfig);
10
+
11
+ try {
12
+ await db.createSdkReportingCollection();
13
+
14
+ await db.sdk_report_events.createIndex(
15
+ {
16
+ connect_at: 1,
17
+ jwt_exp: 1,
18
+ disconnect_at: 1
19
+ },
20
+ { name: 'connect_at' }
21
+ );
22
+
23
+ await db.sdk_report_events.createIndex(
24
+ {
25
+ user_id: 1,
26
+ sdk: 1,
27
+ version: 1
28
+ },
29
+ { name: 'user_id' }
30
+ );
31
+ await db.sdk_report_events.createIndex(
32
+ {
33
+ client_id: 1
34
+ },
35
+ { name: 'client_id' }
36
+ );
37
+ } finally {
38
+ await db.client.close();
39
+ }
40
+ };
41
+
42
+ export const down: migrations.PowerSyncMigrationFunction = async (context) => {
43
+ const {
44
+ service_context: { configuration }
45
+ } = context;
46
+
47
+ const db = storage.createPowerSyncMongo(configuration.storage as MongoStorageConfig);
48
+
49
+ try {
50
+ if (await db.write_checkpoints.indexExists('connect_at')) {
51
+ await db.write_checkpoints.dropIndex('connect_at');
52
+ }
53
+ if (await db.custom_write_checkpoints.indexExists('user_id')) {
54
+ await db.custom_write_checkpoints.dropIndex('user_id');
55
+ }
56
+ if (await db.custom_write_checkpoints.indexExists('client_id')) {
57
+ await db.custom_write_checkpoints.dropIndex('client_id');
58
+ }
59
+ await db.db.dropCollection('sdk_report_events');
60
+ } finally {
61
+ await db.client.close();
62
+ }
63
+ };
@@ -2,6 +2,7 @@ import { mongo } from '@powersync/lib-service-mongodb';
2
2
  import { storage } from '@powersync/service-core';
3
3
  import { event_types } from '@powersync/service-types';
4
4
  import { PowerSyncMongo } from './implementation/db.js';
5
+ import { SdkConnectDocument } from './implementation/models.js';
5
6
 
6
7
  export class MongoReportStorage implements storage.ReportStorageFactory {
7
8
  private readonly client: mongo.MongoClient;
@@ -16,11 +17,12 @@ export class MongoReportStorage implements storage.ReportStorageFactory {
16
17
  console.log('MongoReportStorage.scrapeSdkData', data);
17
18
  }
18
19
 
19
- async reportSdkConnect(data: event_types.SdkConnectEventData): Promise<void> {
20
- console.log('MongoReportStorage.reportSdkConnect', data);
20
+ async reportSdkConnect(data: SdkConnectDocument): Promise<void> {
21
+ await this.db.sdk_report_events.insertOne(data);
21
22
  }
22
- async reportSdkDisconnect(data: event_types.SdkDisconnectEventData): Promise<void> {
23
- console.log('MongoReportStorage.reportSdkDisconnect', data);
23
+ async reportSdkDisconnect(data: SdkConnectDocument): Promise<void> {
24
+ const { _id, ...rest } = data;
25
+ await this.db.sdk_report_events.findOneAndUpdate({ _id }, rest, { upsert: true });
24
26
  }
25
27
  async listCurrentConnections(data: event_types.PaginatedInstanceRequest): Promise<void> {
26
28
  console.log('MongoReportStorage.listCurrentConnections', data);
@@ -12,7 +12,7 @@ import {
12
12
  CustomWriteCheckpointDocument,
13
13
  IdSequenceDocument,
14
14
  InstanceDocument,
15
- SdkConnectEventDocument,
15
+ SdkConnectDocument,
16
16
  SourceTableDocument,
17
17
  SyncRuleDocument,
18
18
  WriteCheckpointDocument
@@ -38,7 +38,7 @@ export class PowerSyncMongo {
38
38
  readonly locks: mongo.Collection<lib_mongo.locks.Lock>;
39
39
  readonly bucket_state: mongo.Collection<BucketStateDocument>;
40
40
  readonly checkpoint_events: mongo.Collection<CheckpointEventDocument>;
41
- readonly sdk_connect_events: mongo.Collection<SdkConnectEventDocument>;
41
+ readonly sdk_report_events: mongo.Collection<SdkConnectDocument>;
42
42
 
43
43
  readonly client: mongo.MongoClient;
44
44
  readonly db: mongo.Db;
@@ -63,7 +63,7 @@ export class PowerSyncMongo {
63
63
  this.locks = this.db.collection('locks');
64
64
  this.bucket_state = this.db.collection('bucket_state');
65
65
  this.checkpoint_events = this.db.collection('checkpoint_events');
66
- this.sdk_connect_events = this.db.collection('sdk_connect_events');
66
+ this.sdk_report_events = this.db.collection('sdk_report_events');
67
67
  }
68
68
 
69
69
  /**
@@ -130,6 +130,20 @@ export class PowerSyncMongo {
130
130
  max: 50 // max number of documents
131
131
  });
132
132
  }
133
+
134
+ /**
135
+ * Only use in migrations and tests.
136
+ */
137
+ async createSdkReportingCollection() {
138
+ const existingCollections = await this.db
139
+ .listCollections({ name: 'sdk_report_events' }, { nameOnly: false })
140
+ .toArray();
141
+ const collection = existingCollections[0];
142
+ if (collection != null) {
143
+ return;
144
+ }
145
+ await this.db.createCollection('sdk_report_events');
146
+ }
133
147
  }
134
148
 
135
149
  export function createPowerSyncMongo(config: MongoStorageConfig, options?: lib_mongo.MongoConnectionOptions) {
@@ -1,6 +1,7 @@
1
1
  import { InternalOpId, storage } from '@powersync/service-core';
2
2
  import { SqliteJsonValue } from '@powersync/service-sync-rules';
3
3
  import * as bson from 'bson';
4
+ import { event_types } from '@powersync/service-types';
4
5
 
5
6
  /**
6
7
  * Replica id uniquely identifying a row on the source database.
@@ -214,11 +215,4 @@ export interface InstanceDocument {
214
215
  _id: string;
215
216
  }
216
217
 
217
- export interface SdkConnectEventDocument {
218
- version: string;
219
- sdk: string;
220
- user_agent: string;
221
- client_id: string;
222
- user_id: string;
223
- jwt_exp: number;
224
- }
218
+ export interface SdkConnectDocument extends event_types.SdkConnectDocument {}