@powersync/service-module-mongodb-storage 0.12.8 → 0.12.9

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.
Files changed (62) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +1 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/migrations/db/migrations/1752661449910-connection-reporting.d.ts +3 -0
  6. package/dist/migrations/db/migrations/1752661449910-connection-reporting.js +36 -0
  7. package/dist/migrations/db/migrations/1752661449910-connection-reporting.js.map +1 -0
  8. package/dist/storage/MongoBucketStorage.js +1 -1
  9. package/dist/storage/MongoBucketStorage.js.map +1 -1
  10. package/dist/storage/MongoReportStorage.d.ts +17 -0
  11. package/dist/storage/MongoReportStorage.js +152 -0
  12. package/dist/storage/MongoReportStorage.js.map +1 -0
  13. package/dist/storage/implementation/MongoBucketBatch.js +1 -1
  14. package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
  15. package/dist/storage/implementation/MongoStorageProvider.d.ts +1 -1
  16. package/dist/storage/implementation/MongoStorageProvider.js +7 -3
  17. package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
  18. package/dist/storage/implementation/MongoSyncBucketStorage.js +1 -1
  19. package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
  20. package/dist/storage/implementation/PersistedBatch.js +1 -1
  21. package/dist/storage/implementation/PersistedBatch.js.map +1 -1
  22. package/dist/storage/implementation/db.d.ts +6 -1
  23. package/dist/storage/implementation/db.js +15 -0
  24. package/dist/storage/implementation/db.js.map +1 -1
  25. package/dist/storage/implementation/models.d.ts +3 -0
  26. package/dist/storage/storage-index.d.ts +3 -2
  27. package/dist/storage/storage-index.js +3 -2
  28. package/dist/storage/storage-index.js.map +1 -1
  29. package/dist/utils/test-utils.d.ts +13 -0
  30. package/dist/utils/test-utils.js +40 -0
  31. package/dist/utils/test-utils.js.map +1 -0
  32. package/dist/{storage/implementation → utils}/util.d.ts +1 -6
  33. package/dist/{storage/implementation → utils}/util.js +0 -15
  34. package/dist/utils/util.js.map +1 -0
  35. package/dist/utils/utils-index.d.ts +2 -0
  36. package/dist/utils/utils-index.js +3 -0
  37. package/dist/utils/utils-index.js.map +1 -0
  38. package/package.json +8 -8
  39. package/src/index.ts +1 -0
  40. package/src/migrations/db/migrations/1752661449910-connection-reporting.ts +58 -0
  41. package/src/storage/MongoBucketStorage.ts +1 -1
  42. package/src/storage/MongoReportStorage.ts +174 -0
  43. package/src/storage/implementation/MongoBucketBatch.ts +1 -1
  44. package/src/storage/implementation/MongoStorageProvider.ts +9 -4
  45. package/src/storage/implementation/MongoSyncBucketStorage.ts +2 -1
  46. package/src/storage/implementation/PersistedBatch.ts +1 -1
  47. package/src/storage/implementation/db.ts +17 -0
  48. package/src/storage/implementation/models.ts +3 -0
  49. package/src/storage/storage-index.ts +3 -2
  50. package/src/utils/test-utils.ts +57 -0
  51. package/src/{storage/implementation → utils}/util.ts +2 -18
  52. package/src/utils/utils-index.ts +2 -0
  53. package/test/src/__snapshots__/connection-report-storage.test.ts.snap +215 -0
  54. package/test/src/connection-report-storage.test.ts +133 -0
  55. package/test/src/storage.test.ts +3 -51
  56. package/test/src/util.ts +6 -2
  57. package/tsconfig.tsbuildinfo +1 -1
  58. package/dist/storage/implementation/MongoTestStorageFactoryGenerator.d.ts +0 -9
  59. package/dist/storage/implementation/MongoTestStorageFactoryGenerator.js +0 -20
  60. package/dist/storage/implementation/MongoTestStorageFactoryGenerator.js.map +0 -1
  61. package/dist/storage/implementation/util.js.map +0 -1
  62. package/src/storage/implementation/MongoTestStorageFactoryGenerator.ts +0 -32
@@ -0,0 +1,133 @@
1
+ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
2
+ import { INITIALIZED_MONGO_REPORT_STORAGE_FACTORY } from './util.js';
3
+ import { register, ReportUserData } from '@powersync/service-core-tests';
4
+ import { event_types } from '@powersync/service-types';
5
+ import { MongoReportStorage } from '@module/storage/MongoReportStorage.js';
6
+
7
+ const userData = register.REPORT_TEST_USERS;
8
+ const dates = register.REPORT_TEST_DATES;
9
+ const factory = await INITIALIZED_MONGO_REPORT_STORAGE_FACTORY();
10
+
11
+ function removeVolatileFields(
12
+ connections: event_types.ClientConnection[]
13
+ ): Partial<event_types.ClientConnection & { _id: string }>[] {
14
+ return connections.map((sdk: Partial<event_types.ClientConnection & { _id: string }>) => {
15
+ const { _id, disconnected_at, connected_at, jwt_exp, ...rest } = sdk;
16
+ return {
17
+ ...rest
18
+ };
19
+ });
20
+ }
21
+
22
+ async function loadData(data: ReportUserData, factory: MongoReportStorage) {
23
+ await factory.db.connection_report_events.insertMany(Object.values(data));
24
+ }
25
+
26
+ async function deleteData(factory: MongoReportStorage) {
27
+ await factory.db.connection_report_events.deleteMany();
28
+ }
29
+
30
+ beforeAll(async () => {
31
+ await loadData(userData, factory);
32
+ });
33
+ afterAll(async () => {
34
+ await deleteData(factory);
35
+ });
36
+
37
+ describe('Report storage tests', async () => {
38
+ await register.registerReportTests(factory);
39
+ });
40
+
41
+ describe('Connection reporting storage', async () => {
42
+ it('Should create a connection report if its after a day', async () => {
43
+ const newConnectAt = new Date(
44
+ dates.now.getFullYear(),
45
+ dates.now.getMonth(),
46
+ dates.now.getDate() + 1,
47
+ dates.now.getHours()
48
+ );
49
+ const jwtExp = new Date(newConnectAt.getFullYear(), newConnectAt.getMonth(), newConnectAt.getDate() + 1);
50
+
51
+ await factory.reportClientConnection({
52
+ sdk: userData.user_week.sdk,
53
+ connected_at: newConnectAt,
54
+ jwt_exp: jwtExp,
55
+ client_id: userData.user_week.client_id,
56
+ user_id: userData.user_week.user_id,
57
+ user_agent: userData.user_week.user_agent
58
+ });
59
+
60
+ const connection = await factory.db.connection_report_events.find({ user_id: userData.user_week.user_id }).toArray();
61
+ expect(connection).toHaveLength(2);
62
+ const cleaned = removeVolatileFields(connection);
63
+ expect(cleaned).toMatchSnapshot();
64
+ });
65
+
66
+ it('Should update a connection report if its within a day', async () => {
67
+ const newConnectAt = new Date(
68
+ dates.now.getFullYear(),
69
+ dates.now.getMonth(),
70
+ dates.now.getDate(),
71
+ dates.now.getHours(),
72
+ dates.now.getMinutes() + 20
73
+ );
74
+ const jwtExp = new Date(newConnectAt.getFullYear(), newConnectAt.getMonth(), newConnectAt.getDate() + 1);
75
+ await factory.reportClientConnection({
76
+ sdk: userData.user_one.sdk,
77
+ connected_at: newConnectAt,
78
+ jwt_exp: jwtExp,
79
+ client_id: userData.user_one.client_id,
80
+ user_id: userData.user_one.user_id,
81
+ user_agent: userData.user_one.user_agent
82
+ });
83
+
84
+ const connection = await factory.db.connection_report_events
85
+ .find({ user_id: userData.user_one.user_id, client_id: userData.user_one.client_id })
86
+ .toArray();
87
+ expect(connection).toHaveLength(1);
88
+ expect(new Date(connection[0].connected_at)).toEqual(newConnectAt);
89
+ expect(new Date(connection[0].jwt_exp!)).toEqual(jwtExp);
90
+ expect(connection[0].disconnected_at).toBeUndefined();
91
+ const cleaned = removeVolatileFields(connection);
92
+ expect(cleaned).toMatchSnapshot();
93
+ });
94
+
95
+ it('Should update a connected connection report and make it disconnected', async () => {
96
+ const disconnectAt = new Date(
97
+ dates.now.getFullYear(),
98
+ dates.now.getMonth(),
99
+ dates.now.getDate(),
100
+ dates.now.getHours(),
101
+ dates.now.getMinutes() + 20
102
+ );
103
+ const jwtExp = new Date(disconnectAt.getFullYear(), disconnectAt.getMonth(), disconnectAt.getDate() + 1);
104
+
105
+ await factory.reportClientDisconnection({
106
+ disconnected_at: disconnectAt,
107
+ jwt_exp: jwtExp,
108
+ client_id: userData.user_three.client_id,
109
+ user_id: userData.user_three.user_id,
110
+ user_agent: userData.user_three.user_agent,
111
+ connected_at: userData.user_three.connected_at
112
+ });
113
+
114
+ const connection = await factory.db.connection_report_events.find({ user_id: userData.user_three.user_id }).toArray();
115
+ expect(connection).toHaveLength(1);
116
+ expect(new Date(connection[0].disconnected_at!)).toEqual(disconnectAt);
117
+ const cleaned = removeVolatileFields(connection);
118
+ expect(cleaned).toMatchSnapshot();
119
+ });
120
+
121
+ it('Should delete rows older than specified range', async () => {
122
+ await deleteData(factory);
123
+ await loadData(userData, factory);
124
+ await factory.deleteOldConnectionData({
125
+ date: dates.weekAgo
126
+ });
127
+ const connection = await factory.getClientConnectionReports({
128
+ start: dates.monthAgo,
129
+ end: dates.now
130
+ });
131
+ expect(connection).toMatchSnapshot();
132
+ });
133
+ });
@@ -2,8 +2,7 @@ import { register } from '@powersync/service-core-tests';
2
2
  import { describe } from 'vitest';
3
3
  import { INITIALIZED_MONGO_STORAGE_FACTORY } from './util.js';
4
4
  import { env } from './env.js';
5
- import { MongoTestStorageFactoryGenerator } from '@module/storage/implementation/MongoTestStorageFactoryGenerator.js';
6
- import { MongoChecksumOptions } from '@module/storage/implementation/MongoChecksums.js';
5
+ import { mongoTestStorageFactoryGenerator } from '@module/utils/test-utils.js';
7
6
 
8
7
  describe('Mongo Sync Bucket Storage - Parameters', () =>
9
8
  register.registerDataStorageParameterTests(INITIALIZED_MONGO_STORAGE_FACTORY));
@@ -18,7 +17,7 @@ describe('Sync Bucket Validation', register.registerBucketValidationTests);
18
17
 
19
18
  describe('Mongo Sync Bucket Storage - split operations', () =>
20
19
  register.registerDataStorageDataTests(
21
- MongoTestStorageFactoryGenerator({
20
+ mongoTestStorageFactoryGenerator({
22
21
  url: env.MONGO_TEST_URL,
23
22
  isCI: env.CI,
24
23
  internalOptions: {
@@ -32,7 +31,7 @@ describe('Mongo Sync Bucket Storage - split operations', () =>
32
31
 
33
32
  describe('Mongo Sync Bucket Storage - split buckets', () =>
34
33
  register.registerDataStorageDataTests(
35
- MongoTestStorageFactoryGenerator({
34
+ mongoTestStorageFactoryGenerator({
36
35
  url: env.MONGO_TEST_URL,
37
36
  isCI: env.CI,
38
37
  internalOptions: {
@@ -43,50 +42,3 @@ describe('Mongo Sync Bucket Storage - split buckets', () =>
43
42
  }
44
43
  })
45
44
  ));
46
-
47
- describe('Mongo Sync Bucket Storage - checksum calculations', () => {
48
- // This test tests 4 buckets x 4 operations in each.
49
- // We specifically use operationBatchLimit that does not have factors in common with 4,
50
- // as well some that do.
51
- const params: MongoChecksumOptions[] = [
52
- {
53
- bucketBatchLimit: 100,
54
- operationBatchLimit: 3
55
- },
56
-
57
- {
58
- bucketBatchLimit: 10,
59
- operationBatchLimit: 7
60
- },
61
-
62
- {
63
- bucketBatchLimit: 3,
64
- operationBatchLimit: 1
65
- },
66
- {
67
- bucketBatchLimit: 1,
68
- operationBatchLimit: 3
69
- },
70
- {
71
- bucketBatchLimit: 2,
72
- operationBatchLimit: 4
73
- },
74
- {
75
- bucketBatchLimit: 4,
76
- operationBatchLimit: 12
77
- }
78
- ];
79
- for (let options of params) {
80
- describe(`${options.bucketBatchLimit}|${options.operationBatchLimit}`, () => {
81
- register.testChecksumBatching(
82
- MongoTestStorageFactoryGenerator({
83
- url: env.MONGO_TEST_URL,
84
- isCI: env.CI,
85
- internalOptions: {
86
- checksumOptions: options
87
- }
88
- })
89
- );
90
- });
91
- }
92
- });
package/test/src/util.ts CHANGED
@@ -1,8 +1,12 @@
1
1
  import { env } from './env.js';
2
+ import { mongoTestReportStorageFactoryGenerator, mongoTestStorageFactoryGenerator } from '@module/utils/test-utils.js';
2
3
 
3
- import { MongoTestStorageFactoryGenerator } from '@module/storage/implementation/MongoTestStorageFactoryGenerator.js';
4
+ export const INITIALIZED_MONGO_STORAGE_FACTORY = mongoTestStorageFactoryGenerator({
5
+ url: env.MONGO_TEST_URL,
6
+ isCI: env.CI
7
+ });
4
8
 
5
- export const INITIALIZED_MONGO_STORAGE_FACTORY = MongoTestStorageFactoryGenerator({
9
+ export const INITIALIZED_MONGO_REPORT_STORAGE_FACTORY = mongoTestReportStorageFactoryGenerator({
6
10
  url: env.MONGO_TEST_URL,
7
11
  isCI: env.CI
8
12
  });