@powersync/service-module-mongodb-storage 0.13.2 → 0.14.0

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 (47) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/migrations/db/migrations/1770213298299-storage-version.d.ts +3 -0
  3. package/dist/migrations/db/migrations/1770213298299-storage-version.js +29 -0
  4. package/dist/migrations/db/migrations/1770213298299-storage-version.js.map +1 -0
  5. package/dist/storage/MongoBucketStorage.d.ts +7 -15
  6. package/dist/storage/MongoBucketStorage.js +13 -51
  7. package/dist/storage/MongoBucketStorage.js.map +1 -1
  8. package/dist/storage/implementation/MongoChecksums.d.ts +5 -2
  9. package/dist/storage/implementation/MongoChecksums.js +7 -4
  10. package/dist/storage/implementation/MongoChecksums.js.map +1 -1
  11. package/dist/storage/implementation/MongoCompactor.js +42 -17
  12. package/dist/storage/implementation/MongoCompactor.js.map +1 -1
  13. package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +2 -12
  14. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +24 -24
  15. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +1 -1
  16. package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +4 -2
  17. package/dist/storage/implementation/MongoSyncBucketStorage.js +4 -1
  18. package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
  19. package/dist/storage/implementation/models.d.ts +13 -1
  20. package/dist/storage/implementation/models.js +9 -1
  21. package/dist/storage/implementation/models.js.map +1 -1
  22. package/dist/storage/storage-index.d.ts +0 -1
  23. package/dist/storage/storage-index.js +0 -1
  24. package/dist/storage/storage-index.js.map +1 -1
  25. package/dist/utils/test-utils.d.ts +3 -4
  26. package/dist/utils/test-utils.js +2 -2
  27. package/dist/utils/test-utils.js.map +1 -1
  28. package/package.json +7 -7
  29. package/src/migrations/db/migrations/1770213298299-storage-version.ts +44 -0
  30. package/src/storage/MongoBucketStorage.ts +21 -59
  31. package/src/storage/implementation/MongoChecksums.ts +14 -6
  32. package/src/storage/implementation/MongoCompactor.ts +49 -19
  33. package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +26 -32
  34. package/src/storage/implementation/MongoSyncBucketStorage.ts +16 -5
  35. package/src/storage/implementation/models.ts +25 -1
  36. package/src/storage/storage-index.ts +0 -1
  37. package/src/utils/test-utils.ts +3 -4
  38. package/test/src/__snapshots__/storage_sync.test.ts.snap +1116 -21
  39. package/test/src/storage_compacting.test.ts +28 -22
  40. package/test/src/storage_sync.test.ts +27 -14
  41. package/test/src/util.ts +3 -0
  42. package/tsconfig.tsbuildinfo +1 -1
  43. package/dist/storage/implementation/MongoPersistedSyncRules.d.ts +0 -10
  44. package/dist/storage/implementation/MongoPersistedSyncRules.js +0 -17
  45. package/dist/storage/implementation/MongoPersistedSyncRules.js.map +0 -1
  46. package/src/storage/implementation/MongoPersistedSyncRules.ts +0 -20
  47. package/test/src/__snapshots__/storage.test.ts.snap +0 -25
@@ -1,7 +1,7 @@
1
- import { register, TEST_TABLE, test_utils } from '@powersync/service-core-tests';
1
+ import { bucketRequest, bucketRequests, register, TEST_TABLE, test_utils } from '@powersync/service-core-tests';
2
2
  import { describe, expect, test } from 'vitest';
3
3
  import { INITIALIZED_MONGO_STORAGE_FACTORY } from './util.js';
4
- import { storage, SyncRulesBucketStorage } from '@powersync/service-core';
4
+ import { storage, SyncRulesBucketStorage, updateSyncRulesFromYaml } from '@powersync/service-core';
5
5
 
6
6
  describe('Mongo Sync Bucket Storage Compact', () => {
7
7
  register.registerCompactTests(INITIALIZED_MONGO_STORAGE_FACTORY);
@@ -38,22 +38,22 @@ describe('Mongo Sync Bucket Storage Compact', () => {
38
38
 
39
39
  const setup = async () => {
40
40
  await using factory = await INITIALIZED_MONGO_STORAGE_FACTORY();
41
- const syncRules = await factory.updateSyncRules({
42
- content: `
41
+ const syncRules = await factory.updateSyncRules(
42
+ updateSyncRulesFromYaml(`
43
43
  bucket_definitions:
44
44
  by_user:
45
45
  parameters: select request.user_id() as user_id
46
46
  data: [select * from test where owner_id = bucket.user_id]
47
- `
48
- });
47
+ `)
48
+ );
49
49
  const bucketStorage = factory.getInstance(syncRules);
50
50
  const { checkpoint } = await populate(bucketStorage);
51
51
 
52
- return { bucketStorage, checkpoint, factory };
52
+ return { bucketStorage, checkpoint, factory, syncRules };
53
53
  };
54
54
 
55
55
  test('full compact', async () => {
56
- const { bucketStorage, checkpoint, factory } = await setup();
56
+ const { bucketStorage, checkpoint, factory, syncRules } = await setup();
57
57
 
58
58
  // Simulate bucket_state from old version not being available
59
59
  await factory.db.bucket_state.deleteMany({});
@@ -68,14 +68,17 @@ bucket_definitions:
68
68
  signal: null as any
69
69
  });
70
70
 
71
- const checksumAfter = await bucketStorage.getChecksums(checkpoint, ['by_user["u1"]', 'by_user["u2"]']);
72
- expect(checksumAfter.get('by_user["u1"]')).toEqual({
73
- bucket: 'by_user["u1"]',
71
+ const checksumAfter = await bucketStorage.getChecksums(
72
+ checkpoint,
73
+ bucketRequests(syncRules, ['by_user["u1"]', 'by_user["u2"]'])
74
+ );
75
+ expect(checksumAfter.get(bucketRequest(syncRules, 'by_user["u1"]'))).toEqual({
76
+ bucket: bucketRequest(syncRules, 'by_user["u1"]'),
74
77
  checksum: -659469718,
75
78
  count: 1
76
79
  });
77
- expect(checksumAfter.get('by_user["u2"]')).toEqual({
78
- bucket: 'by_user["u2"]',
80
+ expect(checksumAfter.get(bucketRequest(syncRules, 'by_user["u2"]'))).toEqual({
81
+ bucket: bucketRequest(syncRules, 'by_user["u2"]'),
79
82
  checksum: 430217650,
80
83
  count: 1
81
84
  });
@@ -86,14 +89,14 @@ bucket_definitions:
86
89
  const { factory } = await setup();
87
90
 
88
91
  // Not populate another version (bucket definition name changed)
89
- const syncRules = await factory.updateSyncRules({
90
- content: `
92
+ const syncRules = await factory.updateSyncRules(
93
+ updateSyncRulesFromYaml(`
91
94
  bucket_definitions:
92
95
  by_user2:
93
96
  parameters: select request.user_id() as user_id
94
97
  data: [select * from test where owner_id = bucket.user_id]
95
- `
96
- });
98
+ `)
99
+ );
97
100
  const bucketStorage = factory.getInstance(syncRules);
98
101
 
99
102
  await populate(bucketStorage);
@@ -119,14 +122,17 @@ bucket_definitions:
119
122
  });
120
123
  expect(result2.buckets).toEqual(0);
121
124
 
122
- const checksumAfter = await bucketStorage.getChecksums(checkpoint, ['by_user2["u1"]', 'by_user2["u2"]']);
123
- expect(checksumAfter.get('by_user2["u1"]')).toEqual({
124
- bucket: 'by_user2["u1"]',
125
+ const checksumAfter = await bucketStorage.getChecksums(
126
+ checkpoint,
127
+ bucketRequests(syncRules, ['by_user2["u1"]', 'by_user2["u2"]'])
128
+ );
129
+ expect(checksumAfter.get(bucketRequest(syncRules, 'by_user2["u1"]'))).toEqual({
130
+ bucket: bucketRequest(syncRules, 'by_user2["u1"]'),
125
131
  checksum: -659469718,
126
132
  count: 1
127
133
  });
128
- expect(checksumAfter.get('by_user2["u2"]')).toEqual({
129
- bucket: 'by_user2["u2"]',
134
+ expect(checksumAfter.get(bucketRequest(syncRules, 'by_user2["u2"]'))).toEqual({
135
+ bucket: bucketRequest(syncRules, 'by_user2["u2"]'),
130
136
  checksum: 430217650,
131
137
  count: 1
132
138
  });
@@ -1,26 +1,30 @@
1
- import { storage } from '@powersync/service-core';
2
- import { register, TEST_TABLE, test_utils } from '@powersync/service-core-tests';
1
+ import { storage, updateSyncRulesFromYaml } from '@powersync/service-core';
2
+ import { bucketRequest, register, TEST_TABLE, test_utils } from '@powersync/service-core-tests';
3
3
  import { describe, expect, test } from 'vitest';
4
- import { INITIALIZED_MONGO_STORAGE_FACTORY } from './util.js';
4
+ import { INITIALIZED_MONGO_STORAGE_FACTORY, TEST_STORAGE_VERSIONS } from './util.js';
5
5
 
6
- describe('sync - mongodb', () => {
7
- register.registerSyncTests(INITIALIZED_MONGO_STORAGE_FACTORY);
6
+ function registerSyncStorageTests(storageFactory: storage.TestStorageFactory, storageVersion: number) {
7
+ register.registerSyncTests(storageFactory, { storageVersion });
8
8
 
9
9
  // The split of returned results can vary depending on storage drivers
10
10
  test('large batch (2)', async () => {
11
11
  // Test syncing a batch of data that is small in count,
12
12
  // but large enough in size to be split over multiple returned chunks.
13
13
  // Similar to the above test, but splits over 1MB chunks.
14
- const sync_rules = test_utils.testRules(
15
- `
14
+ await using factory = await storageFactory();
15
+ const syncRules = await factory.updateSyncRules(
16
+ updateSyncRulesFromYaml(
17
+ `
16
18
  bucket_definitions:
17
19
  global:
18
20
  data:
19
21
  - SELECT id, description FROM "%"
20
- `
22
+ `,
23
+ { storageVersion }
24
+ )
21
25
  );
22
- await using factory = await INITIALIZED_MONGO_STORAGE_FACTORY();
23
- const bucketStorage = factory.getInstance(sync_rules);
26
+ const bucketStorage = factory.getInstance(syncRules);
27
+ const globalBucket = bucketRequest(syncRules, 'global[]');
24
28
 
25
29
  const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
26
30
  const sourceTable = TEST_TABLE;
@@ -74,7 +78,7 @@ describe('sync - mongodb', () => {
74
78
  const options: storage.BucketDataBatchOptions = {};
75
79
 
76
80
  const batch1 = await test_utils.fromAsync(
77
- bucketStorage.getBucketDataBatch(checkpoint, new Map([['global[]', 0n]]), options)
81
+ bucketStorage.getBucketDataBatch(checkpoint, new Map([[globalBucket, 0n]]), options)
78
82
  );
79
83
  expect(test_utils.getBatchData(batch1)).toEqual([
80
84
  { op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 },
@@ -89,7 +93,7 @@ describe('sync - mongodb', () => {
89
93
  const batch2 = await test_utils.fromAsync(
90
94
  bucketStorage.getBucketDataBatch(
91
95
  checkpoint,
92
- new Map([['global[]', BigInt(batch1[0].chunkData.next_after)]]),
96
+ new Map([[globalBucket, BigInt(batch1[0].chunkData.next_after)]]),
93
97
  options
94
98
  )
95
99
  );
@@ -105,7 +109,7 @@ describe('sync - mongodb', () => {
105
109
  const batch3 = await test_utils.fromAsync(
106
110
  bucketStorage.getBucketDataBatch(
107
111
  checkpoint,
108
- new Map([['global[]', BigInt(batch2[0].chunkData.next_after)]]),
112
+ new Map([[globalBucket, BigInt(batch2[0].chunkData.next_after)]]),
109
113
  options
110
114
  )
111
115
  );
@@ -120,9 +124,18 @@ describe('sync - mongodb', () => {
120
124
 
121
125
  // Test that the checksum type is correct.
122
126
  // Specifically, test that it never persisted as double.
123
- const checksumTypes = await factory.db.bucket_data
127
+ const mongoFactory = factory as any;
128
+ const checksumTypes = await mongoFactory.db.bucket_data
124
129
  .aggregate([{ $group: { _id: { $type: '$checksum' }, count: { $sum: 1 } } }])
125
130
  .toArray();
126
131
  expect(checksumTypes).toEqual([{ _id: 'long', count: 4 }]);
127
132
  });
133
+ }
134
+
135
+ describe('sync - mongodb', () => {
136
+ for (const storageVersion of TEST_STORAGE_VERSIONS) {
137
+ describe(`storage v${storageVersion}`, () => {
138
+ registerSyncStorageTests(INITIALIZED_MONGO_STORAGE_FACTORY, storageVersion);
139
+ });
140
+ }
128
141
  });
package/test/src/util.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { env } from './env.js';
2
2
  import { mongoTestReportStorageFactoryGenerator, mongoTestStorageFactoryGenerator } from '@module/utils/test-utils.js';
3
+ import { CURRENT_STORAGE_VERSION, LEGACY_STORAGE_VERSION } from '@powersync/service-core';
3
4
 
4
5
  export const INITIALIZED_MONGO_STORAGE_FACTORY = mongoTestStorageFactoryGenerator({
5
6
  url: env.MONGO_TEST_URL,
@@ -10,3 +11,5 @@ export const INITIALIZED_MONGO_REPORT_STORAGE_FACTORY = mongoTestReportStorageFa
10
11
  url: env.MONGO_TEST_URL,
11
12
  isCI: env.CI
12
13
  });
14
+
15
+ export const TEST_STORAGE_VERSIONS = [LEGACY_STORAGE_VERSION, CURRENT_STORAGE_VERSION];