@powersync/service-module-mongodb 0.0.0-dev-20241128134723 → 0.0.0-dev-20241219110735

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 (137) hide show
  1. package/CHANGELOG.md +69 -4
  2. package/dist/db/db-index.d.ts +1 -0
  3. package/dist/db/db-index.js +2 -0
  4. package/dist/db/db-index.js.map +1 -0
  5. package/dist/db/mongo.d.ts +35 -0
  6. package/dist/db/mongo.js +73 -0
  7. package/dist/db/mongo.js.map +1 -0
  8. package/dist/index.d.ts +2 -0
  9. package/dist/index.js +2 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/locks/MonogLocks.d.ts +36 -0
  12. package/dist/locks/MonogLocks.js +83 -0
  13. package/dist/locks/MonogLocks.js.map +1 -0
  14. package/dist/migrations/MonogMigrationAgent.d.ts +12 -0
  15. package/dist/migrations/MonogMigrationAgent.js +25 -0
  16. package/dist/migrations/MonogMigrationAgent.js.map +1 -0
  17. package/dist/migrations/db/migrations/1684951997326-init.d.ts +3 -0
  18. package/dist/migrations/db/migrations/1684951997326-init.js +30 -0
  19. package/dist/migrations/db/migrations/1684951997326-init.js.map +1 -0
  20. package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.d.ts +2 -0
  21. package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.js +5 -0
  22. package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.js.map +1 -0
  23. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.d.ts +3 -0
  24. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js +54 -0
  25. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js.map +1 -0
  26. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.d.ts +3 -0
  27. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js +26 -0
  28. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js.map +1 -0
  29. package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.d.ts +3 -0
  30. package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.js +28 -0
  31. package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.js.map +1 -0
  32. package/dist/migrations/mongo-migration-store.d.ts +7 -0
  33. package/dist/migrations/mongo-migration-store.js +49 -0
  34. package/dist/migrations/mongo-migration-store.js.map +1 -0
  35. package/dist/module/MongoModule.js +15 -4
  36. package/dist/module/MongoModule.js.map +1 -1
  37. package/dist/replication/MongoManager.d.ts +1 -1
  38. package/dist/replication/MongoManager.js +3 -2
  39. package/dist/replication/MongoManager.js.map +1 -1
  40. package/dist/storage/MongoBucketStorage.d.ts +48 -0
  41. package/dist/storage/MongoBucketStorage.js +425 -0
  42. package/dist/storage/MongoBucketStorage.js.map +1 -0
  43. package/dist/storage/implementation/MongoBucketBatch.d.ts +72 -0
  44. package/dist/storage/implementation/MongoBucketBatch.js +681 -0
  45. package/dist/storage/implementation/MongoBucketBatch.js.map +1 -0
  46. package/dist/storage/implementation/MongoCompactor.d.ts +40 -0
  47. package/dist/storage/implementation/MongoCompactor.js +310 -0
  48. package/dist/storage/implementation/MongoCompactor.js.map +1 -0
  49. package/dist/storage/implementation/MongoIdSequence.d.ts +12 -0
  50. package/dist/storage/implementation/MongoIdSequence.js +21 -0
  51. package/dist/storage/implementation/MongoIdSequence.js.map +1 -0
  52. package/dist/storage/implementation/MongoPersistedSyncRules.d.ts +9 -0
  53. package/dist/storage/implementation/MongoPersistedSyncRules.js +9 -0
  54. package/dist/storage/implementation/MongoPersistedSyncRules.js.map +1 -0
  55. package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +20 -0
  56. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +26 -0
  57. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +1 -0
  58. package/dist/storage/implementation/MongoStorageProvider.d.ts +6 -0
  59. package/dist/storage/implementation/MongoStorageProvider.js +34 -0
  60. package/dist/storage/implementation/MongoStorageProvider.js.map +1 -0
  61. package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +36 -0
  62. package/dist/storage/implementation/MongoSyncBucketStorage.js +529 -0
  63. package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -0
  64. package/dist/storage/implementation/MongoSyncRulesLock.d.ts +16 -0
  65. package/dist/storage/implementation/MongoSyncRulesLock.js +65 -0
  66. package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -0
  67. package/dist/storage/implementation/MongoWriteCheckpointAPI.d.ts +20 -0
  68. package/dist/storage/implementation/MongoWriteCheckpointAPI.js +104 -0
  69. package/dist/storage/implementation/MongoWriteCheckpointAPI.js.map +1 -0
  70. package/dist/storage/implementation/OperationBatch.d.ts +34 -0
  71. package/dist/storage/implementation/OperationBatch.js +119 -0
  72. package/dist/storage/implementation/OperationBatch.js.map +1 -0
  73. package/dist/storage/implementation/PersistedBatch.d.ts +46 -0
  74. package/dist/storage/implementation/PersistedBatch.js +223 -0
  75. package/dist/storage/implementation/PersistedBatch.js.map +1 -0
  76. package/dist/storage/implementation/config.d.ts +19 -0
  77. package/dist/storage/implementation/config.js +26 -0
  78. package/dist/storage/implementation/config.js.map +1 -0
  79. package/dist/storage/implementation/db.d.ts +36 -0
  80. package/dist/storage/implementation/db.js +47 -0
  81. package/dist/storage/implementation/db.js.map +1 -0
  82. package/dist/storage/implementation/models.d.ts +139 -0
  83. package/dist/storage/implementation/models.js +2 -0
  84. package/dist/storage/implementation/models.js.map +1 -0
  85. package/dist/storage/implementation/util.d.ts +58 -0
  86. package/dist/storage/implementation/util.js +196 -0
  87. package/dist/storage/implementation/util.js.map +1 -0
  88. package/dist/storage/storage-index.d.ts +14 -0
  89. package/dist/storage/storage-index.js +15 -0
  90. package/dist/storage/storage-index.js.map +1 -0
  91. package/dist/types/types.d.ts +3 -0
  92. package/dist/types/types.js +4 -1
  93. package/dist/types/types.js.map +1 -1
  94. package/package.json +11 -8
  95. package/src/db/db-index.ts +1 -0
  96. package/src/db/mongo.ts +81 -0
  97. package/src/index.ts +4 -0
  98. package/src/locks/MonogLocks.ts +147 -0
  99. package/src/migrations/MonogMigrationAgent.ts +39 -0
  100. package/src/migrations/db/migrations/1684951997326-init.ts +39 -0
  101. package/src/migrations/db/migrations/1688556755264-initial-sync-rules.ts +5 -0
  102. package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +105 -0
  103. package/src/migrations/db/migrations/1711543888062-write-checkpoint-index.ts +38 -0
  104. package/src/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.ts +40 -0
  105. package/src/migrations/mongo-migration-store.ts +62 -0
  106. package/src/module/MongoModule.ts +18 -4
  107. package/src/replication/MongoManager.ts +6 -2
  108. package/src/storage/MongoBucketStorage.ts +530 -0
  109. package/src/storage/implementation/MongoBucketBatch.ts +893 -0
  110. package/src/storage/implementation/MongoCompactor.ts +392 -0
  111. package/src/storage/implementation/MongoIdSequence.ts +24 -0
  112. package/src/storage/implementation/MongoPersistedSyncRules.ts +16 -0
  113. package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +49 -0
  114. package/src/storage/implementation/MongoStorageProvider.ts +42 -0
  115. package/src/storage/implementation/MongoSyncBucketStorage.ts +612 -0
  116. package/src/storage/implementation/MongoSyncRulesLock.ts +88 -0
  117. package/src/storage/implementation/MongoWriteCheckpointAPI.ts +146 -0
  118. package/src/storage/implementation/OperationBatch.ts +130 -0
  119. package/src/storage/implementation/PersistedBatch.ts +283 -0
  120. package/src/storage/implementation/config.ts +40 -0
  121. package/src/storage/implementation/db.ts +88 -0
  122. package/src/storage/implementation/models.ts +160 -0
  123. package/src/storage/implementation/util.ts +209 -0
  124. package/src/storage/storage-index.ts +14 -0
  125. package/src/types/types.ts +8 -1
  126. package/test/src/__snapshots__/storage_sync.test.ts.snap +332 -0
  127. package/test/src/change_stream.test.ts +34 -33
  128. package/test/src/change_stream_utils.ts +6 -6
  129. package/test/src/env.ts +1 -0
  130. package/test/src/slow_tests.test.ts +4 -4
  131. package/test/src/storage.test.ts +7 -0
  132. package/test/src/storage_compacting.test.ts +6 -0
  133. package/test/src/storage_sync.test.ts +113 -0
  134. package/test/src/util.ts +20 -7
  135. package/test/tsconfig.json +4 -0
  136. package/tsconfig.tsbuildinfo +1 -1
  137. package/vitest.config.ts +1 -1
@@ -0,0 +1,332 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`sync - mongodb > compacting data - invalidate checkpoint 1`] = `
4
+ [
5
+ {
6
+ "checkpoint": {
7
+ "buckets": [
8
+ {
9
+ "bucket": "mybucket[]",
10
+ "checksum": -93886621,
11
+ "count": 2,
12
+ },
13
+ ],
14
+ "last_op_id": "2",
15
+ "write_checkpoint": undefined,
16
+ },
17
+ },
18
+ ]
19
+ `;
20
+
21
+ exports[`sync - mongodb > compacting data - invalidate checkpoint 2`] = `
22
+ [
23
+ {
24
+ "data": {
25
+ "after": "0",
26
+ "bucket": "mybucket[]",
27
+ "data": [
28
+ {
29
+ "checksum": -93886621n,
30
+ "op": "CLEAR",
31
+ "op_id": "2",
32
+ },
33
+ ],
34
+ "has_more": false,
35
+ "next_after": "2",
36
+ },
37
+ },
38
+ {
39
+ "checkpoint_diff": {
40
+ "last_op_id": "4",
41
+ "removed_buckets": [],
42
+ "updated_buckets": [
43
+ {
44
+ "bucket": "mybucket[]",
45
+ "checksum": 499012468,
46
+ "count": 4,
47
+ },
48
+ ],
49
+ "write_checkpoint": undefined,
50
+ },
51
+ },
52
+ {
53
+ "data": {
54
+ "after": "2",
55
+ "bucket": "mybucket[]",
56
+ "data": [
57
+ {
58
+ "checksum": 1859363232n,
59
+ "data": "{"id":"t1","description":"Test 1b"}",
60
+ "object_id": "t1",
61
+ "object_type": "test",
62
+ "op": "PUT",
63
+ "op_id": "3",
64
+ "subkey": "e5aa2ddc-1328-58fa-a000-0b5ed31eaf1a",
65
+ },
66
+ {
67
+ "checksum": 3028503153n,
68
+ "data": "{"id":"t2","description":"Test 2b"}",
69
+ "object_id": "t2",
70
+ "object_type": "test",
71
+ "op": "PUT",
72
+ "op_id": "4",
73
+ "subkey": "13423353-9f27-59b4-baf0-64a5e09f1769",
74
+ },
75
+ ],
76
+ "has_more": false,
77
+ "next_after": "4",
78
+ },
79
+ },
80
+ {
81
+ "checkpoint_complete": {
82
+ "last_op_id": "4",
83
+ },
84
+ },
85
+ ]
86
+ `;
87
+
88
+ exports[`sync - mongodb > expired token 1`] = `
89
+ [
90
+ {
91
+ "token_expires_in": 0,
92
+ },
93
+ ]
94
+ `;
95
+
96
+ exports[`sync - mongodb > expiring token 1`] = `
97
+ [
98
+ {
99
+ "checkpoint": {
100
+ "buckets": [
101
+ {
102
+ "bucket": "mybucket[]",
103
+ "checksum": 0,
104
+ "count": 0,
105
+ },
106
+ ],
107
+ "last_op_id": "0",
108
+ "write_checkpoint": undefined,
109
+ },
110
+ },
111
+ {
112
+ "checkpoint_complete": {
113
+ "last_op_id": "0",
114
+ },
115
+ },
116
+ ]
117
+ `;
118
+
119
+ exports[`sync - mongodb > expiring token 2`] = `
120
+ [
121
+ {
122
+ "token_expires_in": 0,
123
+ },
124
+ ]
125
+ `;
126
+
127
+ exports[`sync - mongodb > sync global data 1`] = `
128
+ [
129
+ {
130
+ "checkpoint": {
131
+ "buckets": [
132
+ {
133
+ "bucket": "mybucket[]",
134
+ "checksum": -93886621,
135
+ "count": 2,
136
+ },
137
+ ],
138
+ "last_op_id": "2",
139
+ "write_checkpoint": undefined,
140
+ },
141
+ },
142
+ {
143
+ "data": {
144
+ "after": "0",
145
+ "bucket": "mybucket[]",
146
+ "data": [
147
+ {
148
+ "checksum": 920318466n,
149
+ "data": "{"id":"t1","description":"Test 1"}",
150
+ "object_id": "t1",
151
+ "object_type": "test",
152
+ "op": "PUT",
153
+ "op_id": "1",
154
+ "subkey": "e5aa2ddc-1328-58fa-a000-0b5ed31eaf1a",
155
+ },
156
+ {
157
+ "checksum": 3280762209n,
158
+ "data": "{"id":"t2","description":"Test 2"}",
159
+ "object_id": "t2",
160
+ "object_type": "test",
161
+ "op": "PUT",
162
+ "op_id": "2",
163
+ "subkey": "13423353-9f27-59b4-baf0-64a5e09f1769",
164
+ },
165
+ ],
166
+ "has_more": false,
167
+ "next_after": "2",
168
+ },
169
+ },
170
+ {
171
+ "checkpoint_complete": {
172
+ "last_op_id": "2",
173
+ },
174
+ },
175
+ ]
176
+ `;
177
+
178
+ exports[`sync - mongodb > sync legacy non-raw data 1`] = `
179
+ [
180
+ {
181
+ "checkpoint": {
182
+ "buckets": [
183
+ {
184
+ "bucket": "mybucket[]",
185
+ "checksum": -852817836,
186
+ "count": 1,
187
+ },
188
+ ],
189
+ "last_op_id": "1",
190
+ "write_checkpoint": undefined,
191
+ },
192
+ },
193
+ {
194
+ "data": {
195
+ "after": "0",
196
+ "bucket": "mybucket[]",
197
+ "data": [
198
+ {
199
+ "checksum": 3442149460n,
200
+ "data": {
201
+ "description": "Test
202
+ "string"",
203
+ "id": "t1",
204
+ "large_num": 12345678901234567890n,
205
+ },
206
+ "object_id": "t1",
207
+ "object_type": "test",
208
+ "op": "PUT",
209
+ "op_id": "1",
210
+ "subkey": "e5aa2ddc-1328-58fa-a000-0b5ed31eaf1a",
211
+ },
212
+ ],
213
+ "has_more": false,
214
+ "next_after": "1",
215
+ },
216
+ },
217
+ {
218
+ "checkpoint_complete": {
219
+ "last_op_id": "1",
220
+ },
221
+ },
222
+ ]
223
+ `;
224
+
225
+ exports[`sync - mongodb > sync updates to global data 1`] = `
226
+ [
227
+ {
228
+ "checkpoint": {
229
+ "buckets": [
230
+ {
231
+ "bucket": "mybucket[]",
232
+ "checksum": 0,
233
+ "count": 0,
234
+ },
235
+ ],
236
+ "last_op_id": "0",
237
+ "write_checkpoint": undefined,
238
+ },
239
+ },
240
+ {
241
+ "checkpoint_complete": {
242
+ "last_op_id": "0",
243
+ },
244
+ },
245
+ ]
246
+ `;
247
+
248
+ exports[`sync - mongodb > sync updates to global data 2`] = `
249
+ [
250
+ {
251
+ "checkpoint_diff": {
252
+ "last_op_id": "1",
253
+ "removed_buckets": [],
254
+ "updated_buckets": [
255
+ {
256
+ "bucket": "mybucket[]",
257
+ "checksum": 920318466,
258
+ "count": 1,
259
+ },
260
+ ],
261
+ "write_checkpoint": undefined,
262
+ },
263
+ },
264
+ {
265
+ "data": {
266
+ "after": "0",
267
+ "bucket": "mybucket[]",
268
+ "data": [
269
+ {
270
+ "checksum": 920318466n,
271
+ "data": "{"id":"t1","description":"Test 1"}",
272
+ "object_id": "t1",
273
+ "object_type": "test",
274
+ "op": "PUT",
275
+ "op_id": "1",
276
+ "subkey": "e5aa2ddc-1328-58fa-a000-0b5ed31eaf1a",
277
+ },
278
+ ],
279
+ "has_more": false,
280
+ "next_after": "1",
281
+ },
282
+ },
283
+ {
284
+ "checkpoint_complete": {
285
+ "last_op_id": "1",
286
+ },
287
+ },
288
+ ]
289
+ `;
290
+
291
+ exports[`sync - mongodb > sync updates to global data 3`] = `
292
+ [
293
+ {
294
+ "checkpoint_diff": {
295
+ "last_op_id": "2",
296
+ "removed_buckets": [],
297
+ "updated_buckets": [
298
+ {
299
+ "bucket": "mybucket[]",
300
+ "checksum": -93886621,
301
+ "count": 2,
302
+ },
303
+ ],
304
+ "write_checkpoint": undefined,
305
+ },
306
+ },
307
+ {
308
+ "data": {
309
+ "after": "1",
310
+ "bucket": "mybucket[]",
311
+ "data": [
312
+ {
313
+ "checksum": 3280762209n,
314
+ "data": "{"id":"t2","description":"Test 2"}",
315
+ "object_id": "t2",
316
+ "object_type": "test",
317
+ "op": "PUT",
318
+ "op_id": "2",
319
+ "subkey": "13423353-9f27-59b4-baf0-64a5e09f1769",
320
+ },
321
+ ],
322
+ "has_more": false,
323
+ "next_after": "2",
324
+ },
325
+ },
326
+ {
327
+ "checkpoint_complete": {
328
+ "last_op_id": "2",
329
+ },
330
+ },
331
+ ]
332
+ `;
@@ -1,12 +1,13 @@
1
- import { putOp, removeOp } from '@core-tests/stream_utils.js';
2
- import { MONGO_STORAGE_FACTORY } from '@core-tests/util.js';
1
+ import { test_utils } from '@powersync/service-core-tests';
2
+
3
+ import { PostImagesOption } from '@module/types/types.js';
3
4
  import { BucketStorageFactory } from '@powersync/service-core';
4
5
  import * as crypto from 'crypto';
5
6
  import * as mongo from 'mongodb';
6
7
  import { setTimeout } from 'node:timers/promises';
7
8
  import { describe, expect, test, vi } from 'vitest';
8
9
  import { ChangeStreamTestContext } from './change_stream_utils.js';
9
- import { PostImagesOption } from '@module/types/types.js';
10
+ import { INITIALIZED_MONGO_STORAGE_FACTORY } from './util.js';
10
11
 
11
12
  type StorageFactory = () => Promise<BucketStorageFactory>;
12
13
 
@@ -18,7 +19,7 @@ bucket_definitions:
18
19
  `;
19
20
 
20
21
  describe('change stream - mongodb', { timeout: 20_000 }, function () {
21
- defineChangeStreamTests(MONGO_STORAGE_FACTORY);
22
+ defineChangeStreamTests(INITIALIZED_MONGO_STORAGE_FACTORY);
22
23
  });
23
24
 
24
25
  function defineChangeStreamTests(factory: StorageFactory) {
@@ -52,10 +53,10 @@ bucket_definitions:
52
53
  const data = await context.getBucketData('global[]');
53
54
 
54
55
  expect(data).toMatchObject([
55
- putOp('test_data', { id: test_id.toHexString(), description: 'test1', num: 1152921504606846976n }),
56
- putOp('test_data', { id: test_id.toHexString(), description: 'test2', num: 1152921504606846976n }),
57
- putOp('test_data', { id: test_id.toHexString(), description: 'test3' }),
58
- removeOp('test_data', test_id.toHexString())
56
+ test_utils.putOp('test_data', { id: test_id.toHexString(), description: 'test1', num: 1152921504606846976n }),
57
+ test_utils.putOp('test_data', { id: test_id.toHexString(), description: 'test2', num: 1152921504606846976n }),
58
+ test_utils.putOp('test_data', { id: test_id.toHexString(), description: 'test3' }),
59
+ test_utils.removeOp('test_data', test_id.toHexString())
59
60
  ]);
60
61
  });
61
62
 
@@ -86,8 +87,8 @@ bucket_definitions:
86
87
  const data = await context.getBucketData('global[]');
87
88
 
88
89
  expect(data).toMatchObject([
89
- putOp('test_data', { id: test_id.toHexString(), description: 'test1', num: 1152921504606846976n }),
90
- putOp('test_data', { id: test_id.toHexString(), description: 'test2', num: 1152921504606846976n })
90
+ test_utils.putOp('test_data', { id: test_id.toHexString(), description: 'test1', num: 1152921504606846976n }),
91
+ test_utils.putOp('test_data', { id: test_id.toHexString(), description: 'test2', num: 1152921504606846976n })
91
92
  ]);
92
93
  });
93
94
 
@@ -125,11 +126,11 @@ bucket_definitions:
125
126
  const data = await context.getBucketData('global[]');
126
127
 
127
128
  expect(data).toMatchObject([
128
- putOp('test_data', { id: test_id!.toHexString(), description: 'test1', num: 1152921504606846976n }),
129
+ test_utils.putOp('test_data', { id: test_id!.toHexString(), description: 'test1', num: 1152921504606846976n }),
129
130
  // fullDocument is not available at the point this is replicated, resulting in it treated as a remove
130
- removeOp('test_data', test_id!.toHexString()),
131
- putOp('test_data', { id: test_id!.toHexString(), description: 'test3' }),
132
- removeOp('test_data', test_id!.toHexString())
131
+ test_utils.removeOp('test_data', test_id!.toHexString()),
132
+ test_utils.putOp('test_data', { id: test_id!.toHexString(), description: 'test3' }),
133
+ test_utils.removeOp('test_data', test_id!.toHexString())
133
134
  ]);
134
135
  });
135
136
 
@@ -171,11 +172,11 @@ bucket_definitions:
171
172
  const data = await context.getBucketData('global[]');
172
173
 
173
174
  expect(data).toMatchObject([
174
- putOp('test_data', { id: test_id!.toHexString(), description: 'test1', num: 1152921504606846976n }),
175
+ test_utils.putOp('test_data', { id: test_id!.toHexString(), description: 'test1', num: 1152921504606846976n }),
175
176
  // The postImage helps us get this data
176
- putOp('test_data', { id: test_id!.toHexString(), description: 'test2', num: 1152921504606846976n }),
177
- putOp('test_data', { id: test_id!.toHexString(), description: 'test3' }),
178
- removeOp('test_data', test_id!.toHexString())
177
+ test_utils.putOp('test_data', { id: test_id!.toHexString(), description: 'test2', num: 1152921504606846976n }),
178
+ test_utils.putOp('test_data', { id: test_id!.toHexString(), description: 'test3' }),
179
+ test_utils.removeOp('test_data', test_id!.toHexString())
179
180
  ]);
180
181
  });
181
182
 
@@ -216,11 +217,11 @@ bucket_definitions:
216
217
  const data = await context.getBucketData('global[]');
217
218
 
218
219
  expect(data).toMatchObject([
219
- putOp('test_data', { id: test_id!.toHexString(), description: 'test1', num: 1152921504606846976n }),
220
+ test_utils.putOp('test_data', { id: test_id!.toHexString(), description: 'test1', num: 1152921504606846976n }),
220
221
  // The postImage helps us get this data
221
- putOp('test_data', { id: test_id!.toHexString(), description: 'test2', num: 1152921504606846976n }),
222
- putOp('test_data', { id: test_id!.toHexString(), description: 'test3' }),
223
- removeOp('test_data', test_id!.toHexString())
222
+ test_utils.putOp('test_data', { id: test_id!.toHexString(), description: 'test2', num: 1152921504606846976n }),
223
+ test_utils.putOp('test_data', { id: test_id!.toHexString(), description: 'test3' }),
224
+ test_utils.removeOp('test_data', test_id!.toHexString())
224
225
  ]);
225
226
  });
226
227
 
@@ -244,7 +245,7 @@ bucket_definitions:
244
245
 
245
246
  const data = await context.getBucketData('global[]');
246
247
 
247
- expect(data).toMatchObject([putOp('test_DATA', { id: test_id, description: 'test1' })]);
248
+ expect(data).toMatchObject([test_utils.putOp('test_DATA', { id: test_id, description: 'test1' })]);
248
249
  });
249
250
 
250
251
  test('replicating large values', async () => {
@@ -270,10 +271,10 @@ bucket_definitions:
270
271
 
271
272
  const data = await context.getBucketData('global[]');
272
273
  expect(data.slice(0, 1)).toMatchObject([
273
- putOp('test_data', { id: test_id.toHexString(), name: 'test1', description: largeDescription })
274
+ test_utils.putOp('test_data', { id: test_id.toHexString(), name: 'test1', description: largeDescription })
274
275
  ]);
275
276
  expect(data.slice(1)).toMatchObject([
276
- putOp('test_data', { id: test_id.toHexString(), name: 'test2', description: largeDescription })
277
+ test_utils.putOp('test_data', { id: test_id.toHexString(), name: 'test2', description: largeDescription })
277
278
  ]);
278
279
  });
279
280
 
@@ -302,8 +303,8 @@ bucket_definitions:
302
303
  const data = await context.getBucketData('global[]');
303
304
 
304
305
  expect(data).toMatchObject([
305
- putOp('test_data', { id: test_id, description: 'test1' }),
306
- removeOp('test_data', test_id)
306
+ test_utils.putOp('test_data', { id: test_id, description: 'test1' }),
307
+ test_utils.removeOp('test_data', test_id)
307
308
  ]);
308
309
  });
309
310
 
@@ -330,9 +331,9 @@ bucket_definitions:
330
331
  const data = await context.getBucketData('global[]');
331
332
 
332
333
  expect(data).toMatchObject([
333
- putOp('test_data1', { id: test_id, description: 'test1' }),
334
- removeOp('test_data1', test_id),
335
- putOp('test_data2', { id: test_id, description: 'test1' })
334
+ test_utils.putOp('test_data1', { id: test_id, description: 'test1' }),
335
+ test_utils.removeOp('test_data1', test_id),
336
+ test_utils.putOp('test_data2', { id: test_id, description: 'test1' })
336
337
  ]);
337
338
  });
338
339
 
@@ -349,7 +350,7 @@ bucket_definitions:
349
350
  context.startStreaming();
350
351
 
351
352
  const data = await context.getBucketData('global[]');
352
- expect(data).toMatchObject([putOp('test_data', { id: test_id, description: 'test1' })]);
353
+ expect(data).toMatchObject([test_utils.putOp('test_data', { id: test_id, description: 'test1' })]);
353
354
  });
354
355
 
355
356
  test('large record', async () => {
@@ -446,8 +447,8 @@ bucket_definitions:
446
447
 
447
448
  const data = await context.getBucketData('global[]');
448
449
  expect(data).toMatchObject([
449
- putOp('test_data', { id: test_id!.toHexString(), description: 'test1' }),
450
- putOp('test_data', { id: test_id!.toHexString(), description: 'test2' })
450
+ test_utils.putOp('test_data', { id: test_id!.toHexString(), description: 'test1' }),
451
+ test_utils.putOp('test_data', { id: test_id!.toHexString(), description: 'test2' })
451
452
  ]);
452
453
  });
453
454
 
@@ -1,12 +1,12 @@
1
1
  import { ActiveCheckpoint, BucketStorageFactory, OpId, SyncRulesBucketStorage } from '@powersync/service-core';
2
2
 
3
- import { TEST_CONNECTION_OPTIONS, clearTestDb } from './util.js';
4
- import { fromAsync } from '@core-tests/stream_utils.js';
5
- import { MongoManager } from '@module/replication/MongoManager.js';
6
3
  import { ChangeStream, ChangeStreamOptions } from '@module/replication/ChangeStream.js';
7
- import * as mongo from 'mongodb';
4
+ import { MongoManager } from '@module/replication/MongoManager.js';
8
5
  import { createCheckpoint } from '@module/replication/MongoRelation.js';
9
6
  import { NormalizedMongoConnectionConfig } from '@module/types/types.js';
7
+ import { test_utils } from '@powersync/service-core-tests';
8
+ import * as mongo from 'mongodb';
9
+ import { TEST_CONNECTION_OPTIONS, clearTestDb } from './util.js';
10
10
 
11
11
  export class ChangeStreamTestContext {
12
12
  private _walStream?: ChangeStream;
@@ -102,7 +102,7 @@ export class ChangeStreamTestContext {
102
102
  async getBucketsDataBatch(buckets: Record<string, string>, options?: { timeout?: number }) {
103
103
  let checkpoint = await this.getCheckpoint(options);
104
104
  const map = new Map<string, string>(Object.entries(buckets));
105
- return fromAsync(this.storage!.getBucketDataBatch(checkpoint, map));
105
+ return test_utils.fromAsync(this.storage!.getBucketDataBatch(checkpoint, map));
106
106
  }
107
107
 
108
108
  async getBucketData(
@@ -117,7 +117,7 @@ export class ChangeStreamTestContext {
117
117
  limit: options?.limit,
118
118
  chunkLimitBytes: options?.chunkLimitBytes
119
119
  });
120
- const batches = await fromAsync(batch);
120
+ const batches = await test_utils.fromAsync(batch);
121
121
  return batches[0]?.batch.data ?? [];
122
122
  }
123
123
 
package/test/src/env.ts CHANGED
@@ -2,6 +2,7 @@ import { utils } from '@powersync/lib-services-framework';
2
2
 
3
3
  export const env = utils.collectEnvironmentVariables({
4
4
  MONGO_TEST_DATA_URL: utils.type.string.default('mongodb://localhost:27017/powersync_test_data'),
5
+ MONGO_TEST_URL: utils.type.string.default('mongodb://localhost:27017/powersync_test'),
5
6
  CI: utils.type.boolean.default('false'),
6
7
  SLOW_TESTS: utils.type.boolean.default('false')
7
8
  });
@@ -1,10 +1,10 @@
1
- import { MONGO_STORAGE_FACTORY } from '@core-tests/util.js';
2
1
  import { BucketStorageFactory } from '@powersync/service-core';
3
2
  import * as mongo from 'mongodb';
4
3
  import { setTimeout } from 'node:timers/promises';
5
4
  import { describe, expect, test } from 'vitest';
6
5
  import { ChangeStreamTestContext, setSnapshotHistorySeconds } from './change_stream_utils.js';
7
6
  import { env } from './env.js';
7
+ import { INITIALIZED_MONGO_STORAGE_FACTORY } from './util.js';
8
8
 
9
9
  type StorageFactory = () => Promise<BucketStorageFactory>;
10
10
 
@@ -17,7 +17,7 @@ bucket_definitions:
17
17
 
18
18
  describe('change stream slow tests - mongodb', { timeout: 60_000 }, function () {
19
19
  if (env.CI || env.SLOW_TESTS) {
20
- defineSlowTests(MONGO_STORAGE_FACTORY);
20
+ defineSlowTests(INITIALIZED_MONGO_STORAGE_FACTORY);
21
21
  } else {
22
22
  // Need something in this file.
23
23
  test('no-op', () => {});
@@ -96,8 +96,8 @@ bucket_definitions:
96
96
 
97
97
  const data = await context.getBucketData('global[]', undefined, { limit: 50_000, chunkLimitBytes: 60_000_000 });
98
98
 
99
- const preDocuments = data.filter((d) => JSON.parse(d.data! as string).description.startsWith('pre')).length;
100
- const updatedDocuments = data.filter((d) => JSON.parse(d.data! as string).description.startsWith('updated')).length;
99
+ const preDocuments = data.filter((d: any) => JSON.parse(d.data! as string).description.startsWith('pre')).length;
100
+ const updatedDocuments = data.filter((d: any) => JSON.parse(d.data! as string).description.startsWith('updated')).length;
101
101
 
102
102
  // If the test works properly, preDocuments should be around 2000-3000.
103
103
  // The total should be around 9000-9900.
@@ -0,0 +1,7 @@
1
+ import { register } from '@powersync/service-core-tests';
2
+ import { describe } from 'vitest';
3
+ import { INITIALIZED_MONGO_STORAGE_FACTORY } from './util.js';
4
+
5
+ describe('Mongo Sync Bucket Storage', () => register.registerDataStorageTests(INITIALIZED_MONGO_STORAGE_FACTORY));
6
+
7
+ describe('Sync Bucket Validation', register.registerBucketValidationTests);
@@ -0,0 +1,6 @@
1
+ import { MongoCompactOptions } from '@module/storage/implementation/MongoCompactor.js';
2
+ import { register } from '@powersync/service-core-tests';
3
+ import { describe } from 'vitest';
4
+ import { INITIALIZED_MONGO_STORAGE_FACTORY } from './util.js';
5
+
6
+ describe('Mongo Sync Bucket Storage Compact', () => register.registerCompactTests<MongoCompactOptions>(INITIALIZED_MONGO_STORAGE_FACTORY, { clearBatchLimit: 2, moveBatchLimit: 1, moveBatchQueryLimit: 1 }));