@powersync/service-module-mongodb-storage 0.12.1 → 0.12.3
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 +21 -0
- package/dist/migrations/db/migrations/1741697235857-bucket-state-index.js +1 -4
- package/dist/migrations/db/migrations/1741697235857-bucket-state-index.js.map +1 -1
- package/dist/storage/MongoBucketStorage.d.ts +3 -2
- package/dist/storage/MongoBucketStorage.js +4 -2
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoChecksums.d.ts +45 -13
- package/dist/storage/implementation/MongoChecksums.js +151 -136
- package/dist/storage/implementation/MongoChecksums.js.map +1 -1
- package/dist/storage/implementation/MongoCompactor.js +23 -21
- package/dist/storage/implementation/MongoCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +5 -2
- package/dist/storage/implementation/MongoSyncBucketStorage.js +3 -3
- package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoTestStorageFactoryGenerator.d.ts +2 -0
- package/dist/storage/implementation/MongoTestStorageFactoryGenerator.js +4 -3
- package/dist/storage/implementation/MongoTestStorageFactoryGenerator.js.map +1 -1
- package/dist/storage/implementation/db.d.ts +4 -0
- package/dist/storage/implementation/db.js +10 -0
- package/dist/storage/implementation/db.js.map +1 -1
- package/dist/storage/implementation/models.d.ts +4 -0
- package/package.json +6 -6
- package/src/migrations/db/migrations/1741697235857-bucket-state-index.ts +1 -7
- package/src/storage/MongoBucketStorage.ts +4 -3
- package/src/storage/implementation/MongoChecksums.ts +174 -150
- package/src/storage/implementation/MongoCompactor.ts +23 -22
- package/src/storage/implementation/MongoSyncBucketStorage.ts +9 -4
- package/src/storage/implementation/MongoTestStorageFactoryGenerator.ts +7 -4
- package/src/storage/implementation/db.ts +14 -0
- package/src/storage/implementation/models.ts +4 -0
- package/test/src/__snapshots__/storage.test.ts.snap +17 -1
- package/test/src/storage.test.ts +86 -1
- package/test/src/storage_compacting.test.ts +120 -5
- package/tsconfig.tsbuildinfo +1 -1
package/test/src/storage.test.ts
CHANGED
|
@@ -1,7 +1,92 @@
|
|
|
1
1
|
import { register } from '@powersync/service-core-tests';
|
|
2
2
|
import { describe } from 'vitest';
|
|
3
3
|
import { INITIALIZED_MONGO_STORAGE_FACTORY } from './util.js';
|
|
4
|
+
import { env } from './env.js';
|
|
5
|
+
import { MongoTestStorageFactoryGenerator } from '@module/storage/implementation/MongoTestStorageFactoryGenerator.js';
|
|
6
|
+
import { MongoChecksumOptions } from '@module/storage/implementation/MongoChecksums.js';
|
|
4
7
|
|
|
5
|
-
describe('Mongo Sync Bucket Storage', () =>
|
|
8
|
+
describe('Mongo Sync Bucket Storage - Parameters', () =>
|
|
9
|
+
register.registerDataStorageParameterTests(INITIALIZED_MONGO_STORAGE_FACTORY));
|
|
10
|
+
|
|
11
|
+
describe('Mongo Sync Bucket Storage - Data', () =>
|
|
12
|
+
register.registerDataStorageDataTests(INITIALIZED_MONGO_STORAGE_FACTORY));
|
|
13
|
+
|
|
14
|
+
describe('Mongo Sync Bucket Storage - Checkpoints', () =>
|
|
15
|
+
register.registerDataStorageCheckpointTests(INITIALIZED_MONGO_STORAGE_FACTORY));
|
|
6
16
|
|
|
7
17
|
describe('Sync Bucket Validation', register.registerBucketValidationTests);
|
|
18
|
+
|
|
19
|
+
describe('Mongo Sync Bucket Storage - split operations', () =>
|
|
20
|
+
register.registerDataStorageDataTests(
|
|
21
|
+
MongoTestStorageFactoryGenerator({
|
|
22
|
+
url: env.MONGO_TEST_URL,
|
|
23
|
+
isCI: env.CI,
|
|
24
|
+
internalOptions: {
|
|
25
|
+
checksumOptions: {
|
|
26
|
+
bucketBatchLimit: 100,
|
|
27
|
+
operationBatchLimit: 1
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
));
|
|
32
|
+
|
|
33
|
+
describe('Mongo Sync Bucket Storage - split buckets', () =>
|
|
34
|
+
register.registerDataStorageDataTests(
|
|
35
|
+
MongoTestStorageFactoryGenerator({
|
|
36
|
+
url: env.MONGO_TEST_URL,
|
|
37
|
+
isCI: env.CI,
|
|
38
|
+
internalOptions: {
|
|
39
|
+
checksumOptions: {
|
|
40
|
+
bucketBatchLimit: 1,
|
|
41
|
+
operationBatchLimit: 100
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
));
|
|
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
|
+
});
|
|
@@ -1,7 +1,122 @@
|
|
|
1
|
-
import { register } from '@powersync/service-core-tests';
|
|
2
|
-
import { describe } from 'vitest';
|
|
1
|
+
import { register, TEST_TABLE, test_utils } from '@powersync/service-core-tests';
|
|
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
5
|
|
|
5
|
-
describe('Mongo Sync Bucket Storage Compact', () =>
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
describe('Mongo Sync Bucket Storage Compact', () => {
|
|
7
|
+
register.registerCompactTests(INITIALIZED_MONGO_STORAGE_FACTORY);
|
|
8
|
+
|
|
9
|
+
describe('with blank bucket_state', () => {
|
|
10
|
+
// This can happen when migrating from older service versions, that did not populate bucket_state yet.
|
|
11
|
+
const populate = async (bucketStorage: SyncRulesBucketStorage) => {
|
|
12
|
+
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
13
|
+
await batch.save({
|
|
14
|
+
sourceTable: TEST_TABLE,
|
|
15
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
16
|
+
after: {
|
|
17
|
+
id: 't1',
|
|
18
|
+
owner_id: 'u1'
|
|
19
|
+
},
|
|
20
|
+
afterReplicaId: test_utils.rid('t1')
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
await batch.save({
|
|
24
|
+
sourceTable: TEST_TABLE,
|
|
25
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
26
|
+
after: {
|
|
27
|
+
id: 't2',
|
|
28
|
+
owner_id: 'u2'
|
|
29
|
+
},
|
|
30
|
+
afterReplicaId: test_utils.rid('t2')
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await batch.commit('1/1');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return bucketStorage.getCheckpoint();
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const setup = async () => {
|
|
40
|
+
await using factory = await INITIALIZED_MONGO_STORAGE_FACTORY();
|
|
41
|
+
const syncRules = await factory.updateSyncRules({
|
|
42
|
+
content: `
|
|
43
|
+
bucket_definitions:
|
|
44
|
+
by_user:
|
|
45
|
+
parameters: select request.user_id() as user_id
|
|
46
|
+
data: [select * from test where owner_id = bucket.user_id]
|
|
47
|
+
`
|
|
48
|
+
});
|
|
49
|
+
const bucketStorage = factory.getInstance(syncRules);
|
|
50
|
+
const { checkpoint } = await populate(bucketStorage);
|
|
51
|
+
|
|
52
|
+
return { bucketStorage, checkpoint, factory };
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
test('full compact', async () => {
|
|
56
|
+
const { bucketStorage, checkpoint, factory } = await setup();
|
|
57
|
+
|
|
58
|
+
// Simulate bucket_state from old version not being available
|
|
59
|
+
await factory.db.bucket_state.deleteMany({});
|
|
60
|
+
|
|
61
|
+
await bucketStorage.compact({
|
|
62
|
+
clearBatchLimit: 200,
|
|
63
|
+
moveBatchLimit: 10,
|
|
64
|
+
moveBatchQueryLimit: 10,
|
|
65
|
+
maxOpId: checkpoint,
|
|
66
|
+
signal: null as any
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const checksumAfter = await bucketStorage.getChecksums(checkpoint, ['by_user["u1"]', 'by_user["u2"]']);
|
|
70
|
+
expect(checksumAfter.get('by_user["u1"]')).toEqual({
|
|
71
|
+
bucket: 'by_user["u1"]',
|
|
72
|
+
checksum: -659469718,
|
|
73
|
+
count: 1
|
|
74
|
+
});
|
|
75
|
+
expect(checksumAfter.get('by_user["u2"]')).toEqual({
|
|
76
|
+
bucket: 'by_user["u2"]',
|
|
77
|
+
checksum: 430217650,
|
|
78
|
+
count: 1
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('populatePersistentChecksumCache', async () => {
|
|
83
|
+
// Populate old sync rules version
|
|
84
|
+
const { factory } = await setup();
|
|
85
|
+
|
|
86
|
+
// Not populate another version (bucket definition name changed)
|
|
87
|
+
const syncRules = await factory.updateSyncRules({
|
|
88
|
+
content: `
|
|
89
|
+
bucket_definitions:
|
|
90
|
+
by_user2:
|
|
91
|
+
parameters: select request.user_id() as user_id
|
|
92
|
+
data: [select * from test where owner_id = bucket.user_id]
|
|
93
|
+
`
|
|
94
|
+
});
|
|
95
|
+
const bucketStorage = factory.getInstance(syncRules);
|
|
96
|
+
|
|
97
|
+
await populate(bucketStorage);
|
|
98
|
+
const { checkpoint } = await bucketStorage.getCheckpoint();
|
|
99
|
+
|
|
100
|
+
await bucketStorage.populatePersistentChecksumCache({
|
|
101
|
+
maxOpId: checkpoint,
|
|
102
|
+
signal: new AbortController().signal
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const checksumAfter = await bucketStorage.getChecksums(checkpoint, ['by_user2["u1"]', 'by_user2["u2"]']);
|
|
106
|
+
expect(checksumAfter.get('by_user2["u1"]')).toEqual({
|
|
107
|
+
bucket: 'by_user2["u1"]',
|
|
108
|
+
checksum: -659469718,
|
|
109
|
+
count: 1
|
|
110
|
+
});
|
|
111
|
+
expect(checksumAfter.get('by_user2["u2"]')).toEqual({
|
|
112
|
+
bucket: 'by_user2["u2"]',
|
|
113
|
+
checksum: 430217650,
|
|
114
|
+
count: 1
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe('Mongo Sync Parameter Storage Compact', () => {
|
|
121
|
+
register.registerParameterCompactTests(INITIALIZED_MONGO_STORAGE_FACTORY);
|
|
122
|
+
});
|