@powersync/service-module-mongodb-storage 0.0.0-dev-20250722145732 → 0.0.0-dev-20250723080543

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-20250722145732
3
+ ## 0.0.0-dev-20250723080543
4
4
 
5
5
  ### Patch Changes
6
6
 
@@ -10,10 +10,10 @@
10
10
  - Updated dependencies [4ebc3bf]
11
11
  - Updated dependencies [1aafdaf]
12
12
  - Updated dependencies [a700ec9]
13
- - @powersync/service-core@0.0.0-dev-20250722145732
14
- - @powersync/service-types@0.0.0-dev-20250722145732
15
- - @powersync/lib-services-framework@0.0.0-dev-20250722145732
16
- - @powersync/lib-service-mongodb@0.0.0-dev-20250722145732
13
+ - @powersync/service-core@0.0.0-dev-20250723080543
14
+ - @powersync/service-types@0.0.0-dev-20250723080543
15
+ - @powersync/lib-services-framework@0.0.0-dev-20250723080543
16
+ - @powersync/lib-service-mongodb@0.0.0-dev-20250723080543
17
17
 
18
18
  ## 0.10.4
19
19
 
@@ -9,6 +9,6 @@ export declare class MongoReportStorage implements storage.ReportStorageFactory
9
9
  scrapeSdkData(data: event_types.ScrapeSdkDataRequest): Promise<event_types.ListCurrentConnectionsResponse>;
10
10
  reportSdkConnect(data: event_types.SdkConnectBucketData): Promise<void>;
11
11
  reportSdkDisconnect(data: event_types.SdkDisconnectEventData): Promise<void>;
12
- listCurrentConnections(data: event_types.InstanceRequest): Promise<event_types.ListCurrentConnectionsResponse>;
12
+ listCurrentConnections(data: event_types.ListCurrentConnectionsRequest): Promise<event_types.ListCurrentConnectionsResponse>;
13
13
  [Symbol.asyncDispose](): Promise<void>;
14
14
  }
@@ -22,15 +22,22 @@ function updateDocFilter(userId, clientId) {
22
22
  }
23
23
  };
24
24
  }
25
- function timeSpan(timeframe) {
25
+ function parseMonthInterval(currentMonth, interval) {
26
+ const readableMonth = currentMonth + 1;
27
+ const difference = readableMonth - interval;
28
+ if (difference < 0) {
29
+ return 12 + difference - 1;
30
+ }
31
+ return difference - 1;
32
+ }
33
+ function timeSpan(period, timeframe = 1) {
26
34
  const date = new Date();
27
35
  const { year, month, day, today } = parseDate(date);
28
- switch (timeframe) {
36
+ switch (period) {
29
37
  case 'month': {
30
- // Cron should run the first day of the new month, this then retrieves from the 1st to the last day of the month
31
38
  const thisMonth = month;
32
- const nextMonth = month == 11 ? 0 : month + 1;
33
- return { $gte: new Date(year, thisMonth), $lte: new Date(year, nextMonth) };
39
+ const previousMonth = parseMonthInterval(thisMonth, timeframe);
40
+ return { $gte: new Date(year, thisMonth), $lt: new Date(year, previousMonth) };
34
41
  }
35
42
  case 'week': {
36
43
  // Back tracks the date to the previous week Monday to Sunday
@@ -38,7 +45,7 @@ function timeSpan(timeframe) {
38
45
  const weekEndDate = new Date(date);
39
46
  weekEndDate.setDate(weekEndDate.getDate() + daysToSunday);
40
47
  const weekStartDate = new Date(weekEndDate);
41
- weekStartDate.setDate(weekStartDate.getDate() - 6);
48
+ weekStartDate.setDate(weekStartDate.getDate() - 6 * timeframe);
42
49
  const weekStart = parseDate(weekStartDate);
43
50
  const weekEnd = parseDate(weekEndDate);
44
51
  return {
@@ -46,12 +53,19 @@ function timeSpan(timeframe) {
46
53
  $lte: new Date(weekEnd.year, weekEnd.month, weekEnd.today)
47
54
  };
48
55
  }
56
+ case 'hour': {
57
+ // Get the last hour from the current time
58
+ const previousHour = date.getHours() - timeframe;
59
+ return {
60
+ $gte: new Date(year, month, today, previousHour),
61
+ $lt: new Date(year, month, today, date.getHours())
62
+ };
63
+ }
49
64
  default: {
50
65
  // Start from today to just before tomorrow
51
- const nextDay = today + 1;
52
66
  return {
53
67
  $gte: new Date(year, month, today),
54
- $lt: new Date(year, month, nextDay)
68
+ $lte: new Date(year, month, today - timeframe)
55
69
  };
56
70
  }
57
71
  }
@@ -64,11 +78,14 @@ export class MongoReportStorage {
64
78
  this.db = db;
65
79
  }
66
80
  async deleteOldSdkData(data) {
67
- console.log(data);
81
+ const { period, timeframe } = data;
82
+ await this.db.sdk_report_events.deleteMany({
83
+ connect_at: timeSpan(period, timeframe),
84
+ $or: [{ disconnect_at: { $exists: true } }, { jwt_exp: { $lt: new Date() }, disconnect_at: { $exists: false } }]
85
+ });
68
86
  }
69
87
  async scrapeSdkData(data) {
70
- const timespanFilter = timeSpan(data.scrape_time);
71
- console.log(timespanFilter);
88
+ const timespanFilter = timeSpan(data.period);
72
89
  const result = await this.db.sdk_report_events
73
90
  .aggregate([
74
91
  {
@@ -123,6 +140,7 @@ export class MongoReportStorage {
123
140
  },
124
141
  {
125
142
  $project: {
143
+ _id: 0,
126
144
  k: '$_id',
127
145
  v: '$count'
128
146
  }
@@ -132,10 +150,10 @@ export class MongoReportStorage {
132
150
  },
133
151
  {
134
152
  $project: {
135
- unique_users_count: { $ifNull: [{ $arrayElemAt: ['$unique_users.count', 0] }, 0] },
136
- unique_user_sdk_count: { $ifNull: [{ $arrayElemAt: ['$unique_user_sdk.count', 0] }, 0] },
137
- unique_user_client_count: { $ifNull: [{ $arrayElemAt: ['$unique_user_client.count', 0] }, 0] },
138
- sdk_versions: '$sdk_versions_array'
153
+ users: { $ifNull: [{ $arrayElemAt: ['$unique_users.count', 0] }, 0] },
154
+ user_sdk: { $ifNull: [{ $arrayElemAt: ['$unique_user_sdk.count', 0] }, 0] },
155
+ client_user: { $ifNull: [{ $arrayElemAt: ['$unique_user_client.count', 0] }, 0] },
156
+ sdk_versions: { $arrayToObject: '$sdk_versions_array' }
139
157
  }
140
158
  }
141
159
  ])
@@ -163,29 +181,83 @@ export class MongoReportStorage {
163
181
  });
164
182
  }
165
183
  async listCurrentConnections(data) {
184
+ const timespanFilter = data.period ? { connect_at: timeSpan(data.period) } : undefined;
185
+ console.log({ timespanFilter });
166
186
  const result = await this.db.sdk_report_events
167
187
  .aggregate([
168
188
  {
169
- $group: {
170
- _id: null,
171
- user_ids: { $addToSet: '$user_id' },
172
- client_ids: { $addToSet: '$client_id' },
173
- sdks: { $addToSet: '$sdk' }
189
+ $match: {
190
+ disconnect_at: { $exists: false },
191
+ jwt_exp: { $gt: new Date() },
192
+ ...timespanFilter
193
+ }
194
+ },
195
+ {
196
+ $facet: {
197
+ unique_users: [
198
+ {
199
+ $group: {
200
+ _id: '$user_id'
201
+ }
202
+ },
203
+ {
204
+ $count: 'count'
205
+ }
206
+ ],
207
+ unique_user_sdk: [
208
+ {
209
+ $group: {
210
+ _id: {
211
+ user_id: '$user_id',
212
+ sdk: '$sdk'
213
+ }
214
+ }
215
+ },
216
+ {
217
+ $count: 'count'
218
+ }
219
+ ],
220
+ unique_user_client: [
221
+ {
222
+ $group: {
223
+ _id: {
224
+ user_id: '$user_id',
225
+ client_id: '$client_id'
226
+ }
227
+ }
228
+ },
229
+ {
230
+ $count: 'count'
231
+ }
232
+ ],
233
+ sdk_versions_array: [
234
+ {
235
+ $group: {
236
+ _id: '$sdk',
237
+ count: { $sum: 1 }
238
+ }
239
+ },
240
+ {
241
+ $project: {
242
+ _id: 0,
243
+ k: '$_id',
244
+ v: '$count'
245
+ }
246
+ }
247
+ ]
174
248
  }
175
249
  },
176
250
  {
177
251
  $project: {
178
- _id: 0,
179
- users: '$user_ids',
180
- clients: '$client_ids',
181
- sdks: '$sdks'
252
+ users: { $ifNull: [{ $arrayElemAt: ['$unique_users.count', 0] }, 0] },
253
+ user_sdk: { $ifNull: [{ $arrayElemAt: ['$unique_user_sdk.count', 0] }, 0] },
254
+ client_user: { $ifNull: [{ $arrayElemAt: ['$unique_user_client.count', 0] }, 0] },
255
+ sdk_versions: { $arrayToObject: '$sdk_versions_array' }
182
256
  }
183
257
  }
184
258
  ])
185
259
  .toArray();
186
- return {
187
- ...result[0]
188
- };
260
+ return result[0];
189
261
  }
190
262
  async [Symbol.asyncDispose]() {
191
263
  // No-op
@@ -1 +1 @@
1
- {"version":3,"file":"MongoReportStorage.js","sourceRoot":"","sources":["../../src/storage/MongoReportStorage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MongoReportStorage.js","sourceRoot":"","sources":["../../src/storage/MongoReportStorage.ts"],"names":[],"mappings":"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"}
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-20250722145732",
5
+ "version": "0.0.0-dev-20250723080543",
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-20250722145732",
31
- "@powersync/lib-services-framework": "0.0.0-dev-20250722145732",
32
- "@powersync/service-core": "0.0.0-dev-20250722145732",
33
- "@powersync/service-types": "0.0.0-dev-20250722145732",
30
+ "@powersync/lib-service-mongodb": "0.0.0-dev-20250723080543",
31
+ "@powersync/lib-services-framework": "0.0.0-dev-20250723080543",
32
+ "@powersync/service-core": "0.0.0-dev-20250723080543",
33
+ "@powersync/service-types": "0.0.0-dev-20250723080543",
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-20250722145732"
38
+ "@powersync/service-core-tests": "0.0.0-dev-20250723080543"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsc -b",
@@ -28,15 +28,23 @@ function updateDocFilter(userId: string, clientId: string) {
28
28
  };
29
29
  }
30
30
 
31
- function timeSpan(timeframe: event_types.TimeFrames) {
31
+ function parseMonthInterval(currentMonth: number, interval: number) {
32
+ const readableMonth = currentMonth + 1;
33
+ const difference = readableMonth - interval;
34
+ if (difference < 0) {
35
+ return 12 + difference - 1;
36
+ }
37
+ return difference - 1;
38
+ }
39
+
40
+ function timeSpan(period: event_types.TimeFrames, timeframe: number = 1): mongo.Filter<mongo.Document> {
32
41
  const date = new Date();
33
42
  const { year, month, day, today } = parseDate(date);
34
- switch (timeframe) {
43
+ switch (period) {
35
44
  case 'month': {
36
- // Cron should run the first day of the new month, this then retrieves from the 1st to the last day of the month
37
45
  const thisMonth = month;
38
- const nextMonth = month == 11 ? 0 : month + 1;
39
- return { $gte: new Date(year, thisMonth), $lte: new Date(year, nextMonth) };
46
+ const previousMonth = parseMonthInterval(thisMonth, timeframe);
47
+ return { $gte: new Date(year, thisMonth), $lt: new Date(year, previousMonth) };
40
48
  }
41
49
  case 'week': {
42
50
  // Back tracks the date to the previous week Monday to Sunday
@@ -44,7 +52,7 @@ function timeSpan(timeframe: event_types.TimeFrames) {
44
52
  const weekEndDate = new Date(date);
45
53
  weekEndDate.setDate(weekEndDate.getDate() + daysToSunday);
46
54
  const weekStartDate = new Date(weekEndDate);
47
- weekStartDate.setDate(weekStartDate.getDate() - 6);
55
+ weekStartDate.setDate(weekStartDate.getDate() - 6 * timeframe);
48
56
  const weekStart = parseDate(weekStartDate);
49
57
  const weekEnd = parseDate(weekEndDate);
50
58
  return {
@@ -52,12 +60,19 @@ function timeSpan(timeframe: event_types.TimeFrames) {
52
60
  $lte: new Date(weekEnd.year, weekEnd.month, weekEnd.today)
53
61
  };
54
62
  }
63
+ case 'hour': {
64
+ // Get the last hour from the current time
65
+ const previousHour = date.getHours() - timeframe;
66
+ return {
67
+ $gte: new Date(year, month, today, previousHour),
68
+ $lt: new Date(year, month, today, date.getHours())
69
+ };
70
+ }
55
71
  default: {
56
72
  // Start from today to just before tomorrow
57
- const nextDay = today + 1;
58
73
  return {
59
74
  $gte: new Date(year, month, today),
60
- $lt: new Date(year, month, nextDay)
75
+ $lte: new Date(year, month, today - timeframe)
61
76
  };
62
77
  }
63
78
  }
@@ -73,12 +88,15 @@ export class MongoReportStorage implements storage.ReportStorageFactory {
73
88
  }
74
89
 
75
90
  async deleteOldSdkData(data: event_types.DeleteOldSdkData): Promise<void> {
76
- console.log(data);
91
+ const { period, timeframe } = data;
92
+ await this.db.sdk_report_events.deleteMany({
93
+ connect_at: timeSpan(period, timeframe),
94
+ $or: [{ disconnect_at: { $exists: true } }, { jwt_exp: { $lt: new Date() }, disconnect_at: { $exists: false } }]
95
+ });
77
96
  }
78
97
 
79
98
  async scrapeSdkData(data: event_types.ScrapeSdkDataRequest): Promise<event_types.ListCurrentConnectionsResponse> {
80
- const timespanFilter = timeSpan(data.scrape_time);
81
- console.log(timespanFilter);
99
+ const timespanFilter = timeSpan(data.period);
82
100
  const result = await this.db.sdk_report_events
83
101
  .aggregate([
84
102
  {
@@ -133,6 +151,7 @@ export class MongoReportStorage implements storage.ReportStorageFactory {
133
151
  },
134
152
  {
135
153
  $project: {
154
+ _id: 0,
136
155
  k: '$_id',
137
156
  v: '$count'
138
157
  }
@@ -142,10 +161,10 @@ export class MongoReportStorage implements storage.ReportStorageFactory {
142
161
  },
143
162
  {
144
163
  $project: {
145
- unique_users_count: { $ifNull: [{ $arrayElemAt: ['$unique_users.count', 0] }, 0] },
146
- unique_user_sdk_count: { $ifNull: [{ $arrayElemAt: ['$unique_user_sdk.count', 0] }, 0] },
147
- unique_user_client_count: { $ifNull: [{ $arrayElemAt: ['$unique_user_client.count', 0] }, 0] },
148
- sdk_versions: '$sdk_versions_array'
164
+ users: { $ifNull: [{ $arrayElemAt: ['$unique_users.count', 0] }, 0] },
165
+ user_sdk: { $ifNull: [{ $arrayElemAt: ['$unique_user_sdk.count', 0] }, 0] },
166
+ client_user: { $ifNull: [{ $arrayElemAt: ['$unique_user_client.count', 0] }, 0] },
167
+ sdk_versions: { $arrayToObject: '$sdk_versions_array' }
149
168
  }
150
169
  }
151
170
  ])
@@ -177,30 +196,86 @@ export class MongoReportStorage implements storage.ReportStorageFactory {
177
196
  }
178
197
  });
179
198
  }
180
- async listCurrentConnections(data: event_types.InstanceRequest): Promise<event_types.ListCurrentConnectionsResponse> {
199
+ async listCurrentConnections(
200
+ data: event_types.ListCurrentConnectionsRequest
201
+ ): Promise<event_types.ListCurrentConnectionsResponse> {
202
+ const timespanFilter = data.period ? { connect_at: timeSpan(data.period) } : undefined;
203
+ console.log({ timespanFilter });
181
204
  const result = await this.db.sdk_report_events
182
- .aggregate<event_types.ListCurrentConnections>([
205
+ .aggregate([
183
206
  {
184
- $group: {
185
- _id: null,
186
- user_ids: { $addToSet: '$user_id' },
187
- client_ids: { $addToSet: '$client_id' },
188
- sdks: { $addToSet: '$sdk' }
207
+ $match: {
208
+ disconnect_at: { $exists: false },
209
+ jwt_exp: { $gt: new Date() },
210
+ ...timespanFilter
211
+ }
212
+ },
213
+ {
214
+ $facet: {
215
+ unique_users: [
216
+ {
217
+ $group: {
218
+ _id: '$user_id'
219
+ }
220
+ },
221
+ {
222
+ $count: 'count'
223
+ }
224
+ ],
225
+ unique_user_sdk: [
226
+ {
227
+ $group: {
228
+ _id: {
229
+ user_id: '$user_id',
230
+ sdk: '$sdk'
231
+ }
232
+ }
233
+ },
234
+ {
235
+ $count: 'count'
236
+ }
237
+ ],
238
+ unique_user_client: [
239
+ {
240
+ $group: {
241
+ _id: {
242
+ user_id: '$user_id',
243
+ client_id: '$client_id'
244
+ }
245
+ }
246
+ },
247
+ {
248
+ $count: 'count'
249
+ }
250
+ ],
251
+ sdk_versions_array: [
252
+ {
253
+ $group: {
254
+ _id: '$sdk',
255
+ count: { $sum: 1 }
256
+ }
257
+ },
258
+ {
259
+ $project: {
260
+ _id: 0,
261
+ k: '$_id',
262
+ v: '$count'
263
+ }
264
+ }
265
+ ]
189
266
  }
190
267
  },
191
268
  {
192
269
  $project: {
193
- _id: 0,
194
- users: '$user_ids',
195
- clients: '$client_ids',
196
- sdks: '$sdks'
270
+ users: { $ifNull: [{ $arrayElemAt: ['$unique_users.count', 0] }, 0] },
271
+ user_sdk: { $ifNull: [{ $arrayElemAt: ['$unique_user_sdk.count', 0] }, 0] },
272
+ client_user: { $ifNull: [{ $arrayElemAt: ['$unique_user_client.count', 0] }, 0] },
273
+ sdk_versions: { $arrayToObject: '$sdk_versions_array' }
197
274
  }
198
275
  }
199
276
  ])
200
277
  .toArray();
201
- return {
202
- ...result[0]
203
- };
278
+ return result[0] as event_types.ListCurrentConnectionsResponse;
204
279
  }
205
280
 
206
281
  async [Symbol.asyncDispose]() {