@powersync/service-core-tests 0.16.0 → 0.17.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 (30) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/test-utils/AbstractStreamTestContext.d.ts +3 -2
  3. package/dist/test-utils/AbstractStreamTestContext.js +25 -21
  4. package/dist/test-utils/AbstractStreamTestContext.js.map +1 -1
  5. package/dist/test-utils/StorageDataHelpers.d.ts +3 -3
  6. package/dist/test-utils/StorageDataHelpers.js.map +1 -1
  7. package/dist/test-utils/general-utils.d.ts +12 -2
  8. package/dist/test-utils/general-utils.js +15 -3
  9. package/dist/test-utils/general-utils.js.map +1 -1
  10. package/dist/tests/register-compacting-tests.js +15 -8
  11. package/dist/tests/register-compacting-tests.js.map +1 -1
  12. package/dist/tests/register-data-storage-data-tests.js +102 -73
  13. package/dist/tests/register-data-storage-data-tests.js.map +1 -1
  14. package/dist/tests/register-data-storage-parameter-tests.js +44 -42
  15. package/dist/tests/register-data-storage-parameter-tests.js.map +1 -1
  16. package/dist/tests/register-sync-tests.js +6 -3
  17. package/dist/tests/register-sync-tests.js.map +1 -1
  18. package/dist/tests/util.d.ts +2 -2
  19. package/dist/tests/util.js.map +1 -1
  20. package/package.json +5 -6
  21. package/src/test-utils/AbstractStreamTestContext.ts +26 -22
  22. package/src/test-utils/StorageDataHelpers.ts +4 -4
  23. package/src/test-utils/general-utils.ts +25 -7
  24. package/src/tests/register-compacting-tests.ts +15 -8
  25. package/src/tests/register-data-storage-data-tests.ts +128 -75
  26. package/src/tests/register-data-storage-parameter-tests.ts +58 -42
  27. package/src/tests/register-sync-tests.ts +6 -3
  28. package/src/tests/util.ts +2 -2
  29. package/tsconfig.json +1 -4
  30. package/tsconfig.tsbuildinfo +1 -1
@@ -17,6 +17,7 @@ bucket_definitions:
17
17
  `)
18
18
  );
19
19
  const bucketStorage = factory.getInstance(syncRules);
20
+ const syncRulesContent = syncRules.syncConfigContent[0];
20
21
 
21
22
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
22
23
  const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
@@ -53,7 +54,7 @@ bucket_definitions:
53
54
 
54
55
  const checkpoint = writer.last_flushed_op!;
55
56
 
56
- const request = bucketRequest(syncRules, 'global[]');
57
+ const request = bucketRequest(syncRulesContent, 'global[]');
57
58
 
58
59
  const batchBefore = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
59
60
  const dataBefore = batchBefore.chunkData.data;
@@ -124,6 +125,7 @@ bucket_definitions:
124
125
  `)
125
126
  );
126
127
  const bucketStorage = factory.getInstance(syncRules);
128
+ const syncRulesContent = syncRules.syncConfigContent[0];
127
129
 
128
130
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
129
131
  const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
@@ -168,7 +170,7 @@ bucket_definitions:
168
170
  await writer.flush();
169
171
 
170
172
  const checkpoint = writer.last_flushed_op!;
171
- const request = bucketRequest(syncRules, 'global[]');
173
+ const request = bucketRequest(syncRulesContent, 'global[]');
172
174
 
173
175
  const batchBefore = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
174
176
  const dataBefore = batchBefore.chunkData.data;
@@ -240,6 +242,7 @@ bucket_definitions:
240
242
  `)
241
243
  );
242
244
  const bucketStorage = factory.getInstance(syncRules);
245
+ const syncRulesContent = syncRules.syncConfigContent[0];
243
246
 
244
247
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
245
248
  const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
@@ -275,7 +278,7 @@ bucket_definitions:
275
278
  await writer.flush();
276
279
 
277
280
  const checkpoint1 = writer.last_flushed_op!;
278
- const request = bucketRequest(syncRules, 'global[]');
281
+ const request = bucketRequest(syncRulesContent, 'global[]');
279
282
  await using writer2 = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
280
283
  const testTable2 = await test_utils.resolveTestTable(writer2, 'test', ['id'], config);
281
284
  await writer2.save({
@@ -328,6 +331,7 @@ bucket_definitions:
328
331
  - select * from test where b = bucket.b`)
329
332
  );
330
333
  const bucketStorage = factory.getInstance(syncRules);
334
+ const syncRulesContent = syncRules.syncConfigContent[0];
331
335
 
332
336
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
333
337
  const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
@@ -413,7 +417,7 @@ bucket_definitions:
413
417
  const batchAfter = await test_utils.fromAsync(
414
418
  bucketStorage.getBucketDataBatch(
415
419
  checkpoint,
416
- bucketRequestMap(syncRules, [
420
+ bucketRequestMap(syncRulesContent, [
417
421
  ['grouped["b1"]', 0n],
418
422
  ['grouped["b2"]', 0n]
419
423
  ])
@@ -458,6 +462,7 @@ bucket_definitions:
458
462
  `)
459
463
  );
460
464
  const bucketStorage = factory.getInstance(syncRules);
465
+ const syncRulesContent = syncRules.syncConfigContent[0];
461
466
 
462
467
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
463
468
  const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
@@ -513,7 +518,7 @@ bucket_definitions:
513
518
  await writer2.commit('2/1');
514
519
  await writer2.flush();
515
520
  const checkpoint2 = writer2.last_flushed_op!;
516
- const request = bucketRequest(syncRules, 'global[]');
521
+ const request = bucketRequest(syncRulesContent, 'global[]');
517
522
  await bucketStorage.clearChecksumCache();
518
523
  const checksumAfter = await bucketStorage.getChecksums(checkpoint2, [request]);
519
524
  const globalChecksum = checksumAfter.get(request.bucket);
@@ -536,6 +541,7 @@ bucket_definitions:
536
541
  `)
537
542
  );
538
543
  const bucketStorage = factory.getInstance(syncRules);
544
+ const syncRulesContent = syncRules.syncConfigContent[0];
539
545
 
540
546
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
541
547
  const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
@@ -562,7 +568,7 @@ bucket_definitions:
562
568
  await writer.flush();
563
569
 
564
570
  // Get checksums here just to populate the cache
565
- await bucketStorage.getChecksums(writer.last_flushed_op!, bucketRequests(syncRules, ['global[]']));
571
+ await bucketStorage.getChecksums(writer.last_flushed_op!, bucketRequests(syncRulesContent, ['global[]']));
566
572
  await using writer2 = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
567
573
  const testTable2 = await test_utils.resolveTestTable(writer2, 'test', ['id'], config);
568
574
  await writer2.save({
@@ -585,7 +591,7 @@ bucket_definitions:
585
591
  });
586
592
 
587
593
  const checkpoint2 = writer2.last_flushed_op!;
588
- const request = bucketRequest(syncRules, 'global[]');
594
+ const request = bucketRequest(syncRulesContent, 'global[]');
589
595
  // Check that the checksum was correctly updated with the clear operation after having a cached checksum
590
596
  const checksumAfter = await bucketStorage.getChecksums(checkpoint2, [request]);
591
597
  const globalChecksum = checksumAfter.get(request.bucket);
@@ -607,6 +613,7 @@ bucket_definitions:
607
613
  `)
608
614
  );
609
615
  const bucketStorage = factory.getInstance(syncRules);
616
+ const syncRulesContent = syncRules.syncConfigContent[0];
610
617
 
611
618
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
612
619
  const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
@@ -646,7 +653,7 @@ bucket_definitions:
646
653
  });
647
654
 
648
655
  const batchAfterDefaultCompact = await test_utils.oneFromAsync(
649
- bucketStorage.getBucketDataBatch(checkpoint2, bucketRequestMap(syncRules, [['global[]', 0n]]))
656
+ bucketStorage.getBucketDataBatch(checkpoint2, bucketRequestMap(syncRulesContent, [['global[]', 0n]]))
650
657
  );
651
658
 
652
659
  // Operation 1 should remain a PUT because op_id=2 is above the default maxOpId checkpoint.
@@ -38,7 +38,8 @@ export function registerDataStorageDataTests(config: storage.TestStorageConfig)
38
38
 
39
39
  test('removing row', async () => {
40
40
  await using factory = await generateStorageFactory();
41
- const syncRules = await factory.updateSyncRules(
41
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
42
+ factory,
42
43
  updateSyncRulesFromYaml(
43
44
  `
44
45
  bucket_definitions:
@@ -49,7 +50,7 @@ bucket_definitions:
49
50
  { storageVersion }
50
51
  )
51
52
  );
52
- const bucketStorage = factory.getInstance(syncRules);
53
+ const bucketStorage = factory.getInstance(replicationStream);
53
54
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
54
55
  const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
55
56
 
@@ -103,7 +104,8 @@ bucket_definitions:
103
104
 
104
105
  test('insert after delete in new batch', async () => {
105
106
  await using factory = await generateStorageFactory();
106
- const syncRules = await factory.updateSyncRules(
107
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
108
+ factory,
107
109
  updateSyncRulesFromYaml(
108
110
  `
109
111
  bucket_definitions:
@@ -114,7 +116,7 @@ bucket_definitions:
114
116
  { storageVersion }
115
117
  )
116
118
  );
117
- const bucketStorage = factory.getInstance(syncRules);
119
+ const bucketStorage = factory.getInstance(replicationStream);
118
120
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
119
121
  const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
120
122
  await writer.markAllSnapshotDone('1/1');
@@ -167,7 +169,8 @@ bucket_definitions:
167
169
  test('update after delete in new batch', async () => {
168
170
  // Update after delete may not be common, but the storage layer should handle it in an eventually-consistent way.
169
171
  await using factory = await generateStorageFactory();
170
- const syncRules = await factory.updateSyncRules(
172
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
173
+ factory,
171
174
  updateSyncRulesFromYaml(
172
175
  `
173
176
  bucket_definitions:
@@ -178,7 +181,7 @@ bucket_definitions:
178
181
  { storageVersion }
179
182
  )
180
183
  );
181
- const bucketStorage = factory.getInstance(syncRules);
184
+ const bucketStorage = factory.getInstance(replicationStream);
182
185
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
183
186
  const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
184
187
  await writer.markAllSnapshotDone('1/1');
@@ -234,7 +237,8 @@ bucket_definitions:
234
237
 
235
238
  test('insert after delete in same batch', async () => {
236
239
  await using factory = await generateStorageFactory();
237
- const syncRules = await factory.updateSyncRules(
240
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
241
+ factory,
238
242
  updateSyncRulesFromYaml(
239
243
  `
240
244
  bucket_definitions:
@@ -247,7 +251,7 @@ bucket_definitions:
247
251
  }
248
252
  )
249
253
  );
250
- const bucketStorage = factory.getInstance(syncRules);
254
+ const bucketStorage = factory.getInstance(replicationStream);
251
255
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
252
256
  const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
253
257
  await writer.markAllSnapshotDone('1/1');
@@ -296,7 +300,8 @@ bucket_definitions:
296
300
 
297
301
  test('(insert, delete, insert), (delete)', async () => {
298
302
  await using factory = await generateStorageFactory();
299
- const syncRules = await factory.updateSyncRules(
303
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
304
+ factory,
300
305
  updateSyncRulesFromYaml(
301
306
  `
302
307
  bucket_definitions:
@@ -309,7 +314,7 @@ bucket_definitions:
309
314
  }
310
315
  )
311
316
  );
312
- const bucketStorage = factory.getInstance(syncRules);
317
+ const bucketStorage = factory.getInstance(replicationStream);
313
318
  {
314
319
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
315
320
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
@@ -374,7 +379,8 @@ bucket_definitions:
374
379
 
375
380
  test('changing client ids', async () => {
376
381
  await using factory = await generateStorageFactory();
377
- const syncRules = await factory.updateSyncRules(
382
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
383
+ factory,
378
384
  updateSyncRulesFromYaml(
379
385
  `
380
386
  bucket_definitions:
@@ -387,7 +393,7 @@ bucket_definitions:
387
393
  }
388
394
  )
389
395
  );
390
- const bucketStorage = factory.getInstance(syncRules);
396
+ const bucketStorage = factory.getInstance(replicationStream);
391
397
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
392
398
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
393
399
  await writer.markAllSnapshotDone('1/1');
@@ -445,7 +451,8 @@ bucket_definitions:
445
451
 
446
452
  test('re-apply delete', async () => {
447
453
  await using factory = await generateStorageFactory();
448
- const syncRules = await factory.updateSyncRules(
454
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
455
+ factory,
449
456
  updateSyncRulesFromYaml(
450
457
  `
451
458
  bucket_definitions:
@@ -458,7 +465,7 @@ bucket_definitions:
458
465
  }
459
466
  )
460
467
  );
461
- const bucketStorage = factory.getInstance(syncRules);
468
+ const bucketStorage = factory.getInstance(replicationStream);
462
469
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
463
470
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
464
471
  await writer.markAllSnapshotDone('1/1');
@@ -521,7 +528,8 @@ bucket_definitions:
521
528
 
522
529
  test('re-apply update + delete', async () => {
523
530
  await using factory = await generateStorageFactory();
524
- const syncRules = await factory.updateSyncRules(
531
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
532
+ factory,
525
533
  updateSyncRulesFromYaml(
526
534
  `
527
535
  bucket_definitions:
@@ -532,7 +540,7 @@ bucket_definitions:
532
540
  { storageVersion }
533
541
  )
534
542
  );
535
- const bucketStorage = factory.getInstance(syncRules);
543
+ const bucketStorage = factory.getInstance(replicationStream);
536
544
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
537
545
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
538
546
  await writer.markAllSnapshotDone('1/1');
@@ -651,7 +659,8 @@ bucket_definitions:
651
659
  // 2. Output order not being correct.
652
660
 
653
661
  await using factory = await generateStorageFactory();
654
- const syncRules = await factory.updateSyncRules(
662
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
663
+ factory,
655
664
  updateSyncRulesFromYaml(
656
665
  `
657
666
  bucket_definitions:
@@ -662,7 +671,7 @@ bucket_definitions:
662
671
  { storageVersion }
663
672
  )
664
673
  );
665
- const bucketStorage = factory.getInstance(syncRules);
674
+ const bucketStorage = factory.getInstance(replicationStream);
666
675
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
667
676
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
668
677
 
@@ -810,7 +819,8 @@ bucket_definitions:
810
819
  ]);
811
820
  }
812
821
  await using factory = await generateStorageFactory();
813
- const syncRules = await factory.updateSyncRules(
822
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
823
+ factory,
814
824
  updateSyncRulesFromYaml(
815
825
  `
816
826
  bucket_definitions:
@@ -823,7 +833,7 @@ bucket_definitions:
823
833
  }
824
834
  )
825
835
  );
826
- const bucketStorage = factory.getInstance(syncRules);
836
+ const bucketStorage = factory.getInstance(replicationStream);
827
837
 
828
838
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
829
839
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id', 'description'], config);
@@ -923,7 +933,8 @@ bucket_definitions:
923
933
  }
924
934
 
925
935
  await using factory = await generateStorageFactory();
926
- const syncRules = await factory.updateSyncRules(
936
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
937
+ factory,
927
938
  updateSyncRulesFromYaml(
928
939
  `
929
940
  bucket_definitions:
@@ -936,7 +947,7 @@ bucket_definitions:
936
947
  }
937
948
  )
938
949
  );
939
- const bucketStorage = factory.getInstance(syncRules);
950
+ const bucketStorage = factory.getInstance(replicationStream);
940
951
 
941
952
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
942
953
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id', 'description'], config);
@@ -1026,7 +1037,8 @@ bucket_definitions:
1026
1037
  // The specific batch splits is an implementation detail of the storage driver,
1027
1038
  // and the test will have to updated when other implementations are added.
1028
1039
  await using factory = await generateStorageFactory();
1029
- const syncRules = await factory.updateSyncRules(
1040
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
1041
+ factory,
1030
1042
  updateSyncRulesFromYaml(
1031
1043
  `
1032
1044
  bucket_definitions:
@@ -1039,7 +1051,7 @@ bucket_definitions:
1039
1051
  }
1040
1052
  )
1041
1053
  );
1042
- const bucketStorage = factory.getInstance(syncRules);
1054
+ const bucketStorage = factory.getInstance(replicationStream);
1043
1055
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1044
1056
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
1045
1057
  await writer.markAllSnapshotDone('1/1');
@@ -1138,7 +1150,8 @@ bucket_definitions:
1138
1150
  test('long batch', async () => {
1139
1151
  // Test syncing a batch of data that is limited by count.
1140
1152
  await using factory = await generateStorageFactory();
1141
- const syncRules = await factory.updateSyncRules(
1153
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
1154
+ factory,
1142
1155
  updateSyncRulesFromYaml(
1143
1156
  `
1144
1157
  bucket_definitions:
@@ -1151,7 +1164,7 @@ bucket_definitions:
1151
1164
  }
1152
1165
  )
1153
1166
  );
1154
- const bucketStorage = factory.getInstance(syncRules);
1167
+ const bucketStorage = factory.getInstance(replicationStream);
1155
1168
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1156
1169
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
1157
1170
  await writer.markAllSnapshotDone('1/1');
@@ -1217,7 +1230,8 @@ bucket_definitions:
1217
1230
  describe('batch has_more', () => {
1218
1231
  const setup = async (options: BucketDataBatchOptions) => {
1219
1232
  await using factory = await generateStorageFactory();
1220
- const syncRules = await factory.updateSyncRules(
1233
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
1234
+ factory,
1221
1235
  updateSyncRulesFromYaml(
1222
1236
  `
1223
1237
  bucket_definitions:
@@ -1231,7 +1245,7 @@ bucket_definitions:
1231
1245
  { storageVersion }
1232
1246
  )
1233
1247
  );
1234
- const bucketStorage = factory.getInstance(syncRules);
1248
+ const bucketStorage = factory.getInstance(replicationStream);
1235
1249
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1236
1250
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
1237
1251
  await writer.markAllSnapshotDone('1/1');
@@ -1332,39 +1346,67 @@ bucket_definitions:
1332
1346
  // 50 bytes is more than 1 row, less than 2 rows
1333
1347
  const { batch, global1Request, global2Request } = await setup({ limit: 3, chunkLimitBytes: 50 });
1334
1348
 
1335
- expect(batch.length).toEqual(3);
1336
- expect(batch[0].chunkData.bucket).toEqual(global1Request.bucket);
1337
- expect(batch[1].chunkData.bucket).toEqual(global2Request.bucket);
1338
- expect(batch[2].chunkData.bucket).toEqual(global2Request.bucket);
1339
-
1340
- expect(test_utils.getBatchData(batch[0])).toEqual([
1341
- { op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 }
1342
- ]);
1343
-
1344
- expect(test_utils.getBatchData(batch[1])).toEqual([
1345
- { op_id: '2', op: 'PUT', object_id: 'test2', checksum: 730027011 }
1346
- ]);
1347
- expect(test_utils.getBatchData(batch[2])).toEqual([
1348
- { op_id: '3', op: 'PUT', object_id: 'test3', checksum: 1359888332 }
1349
- ]);
1349
+ if (config.compressedBucketStorage) {
1350
+ // In v3+, ops in the same bucket share a document, so ops 2 and 3 (global2) are batched together
1351
+ expect(batch.length).toEqual(2);
1352
+ expect(batch[0].chunkData.bucket).toEqual(global1Request.bucket);
1353
+ expect(batch[1].chunkData.bucket).toEqual(global2Request.bucket);
1354
+
1355
+ expect(test_utils.getBatchData(batch[0])).toEqual([
1356
+ { op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 }
1357
+ ]);
1358
+
1359
+ expect(test_utils.getBatchData(batch[1])).toEqual([
1360
+ { op_id: '2', op: 'PUT', object_id: 'test2', checksum: 730027011 },
1361
+ { op_id: '3', op: 'PUT', object_id: 'test3', checksum: 1359888332 }
1362
+ ]);
1363
+
1364
+ expect(test_utils.getBatchMeta(batch[0])).toEqual({
1365
+ after: '0',
1366
+ has_more: false,
1367
+ next_after: '1'
1368
+ });
1350
1369
 
1351
- expect(test_utils.getBatchMeta(batch[0])).toEqual({
1352
- after: '0',
1353
- has_more: false,
1354
- next_after: '1'
1355
- });
1370
+ expect(test_utils.getBatchMeta(batch[1])).toEqual({
1371
+ after: '0',
1372
+ has_more: true,
1373
+ next_after: '3'
1374
+ });
1375
+ } else {
1376
+ expect(batch.length).toEqual(3);
1377
+ expect(batch[0].chunkData.bucket).toEqual(global1Request.bucket);
1378
+ expect(batch[1].chunkData.bucket).toEqual(global2Request.bucket);
1379
+ expect(batch[2].chunkData.bucket).toEqual(global2Request.bucket);
1380
+
1381
+ expect(test_utils.getBatchData(batch[0])).toEqual([
1382
+ { op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 }
1383
+ ]);
1384
+
1385
+ expect(test_utils.getBatchData(batch[1])).toEqual([
1386
+ { op_id: '2', op: 'PUT', object_id: 'test2', checksum: 730027011 }
1387
+ ]);
1388
+ expect(test_utils.getBatchData(batch[2])).toEqual([
1389
+ { op_id: '3', op: 'PUT', object_id: 'test3', checksum: 1359888332 }
1390
+ ]);
1391
+
1392
+ expect(test_utils.getBatchMeta(batch[0])).toEqual({
1393
+ after: '0',
1394
+ has_more: false,
1395
+ next_after: '1'
1396
+ });
1356
1397
 
1357
- expect(test_utils.getBatchMeta(batch[1])).toEqual({
1358
- after: '0',
1359
- has_more: true,
1360
- next_after: '2'
1361
- });
1398
+ expect(test_utils.getBatchMeta(batch[1])).toEqual({
1399
+ after: '0',
1400
+ has_more: true,
1401
+ next_after: '2'
1402
+ });
1362
1403
 
1363
- expect(test_utils.getBatchMeta(batch[2])).toEqual({
1364
- after: '2',
1365
- has_more: true,
1366
- next_after: '3'
1367
- });
1404
+ expect(test_utils.getBatchMeta(batch[2])).toEqual({
1405
+ after: '2',
1406
+ has_more: true,
1407
+ next_after: '3'
1408
+ });
1409
+ }
1368
1410
  });
1369
1411
  });
1370
1412
 
@@ -1392,7 +1434,8 @@ bucket_definitions:
1392
1434
  // but large enough in size to be split over multiple returned chunks.
1393
1435
  // Similar to the above test, but splits over 1MB chunks.
1394
1436
  await using factory = await generateStorageFactory();
1395
- const syncRules = await factory.updateSyncRules(
1437
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
1438
+ factory,
1396
1439
  updateSyncRulesFromYaml(
1397
1440
  `
1398
1441
  bucket_definitions:
@@ -1406,7 +1449,7 @@ bucket_definitions:
1406
1449
  }
1407
1450
  )
1408
1451
  );
1409
- const bucketStorage = factory.getInstance(syncRules);
1452
+ const bucketStorage = factory.getInstance(replicationStream);
1410
1453
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1411
1454
 
1412
1455
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config, 1);
@@ -1444,7 +1487,8 @@ bucket_definitions:
1444
1487
 
1445
1488
  test('unchanged checksums', async () => {
1446
1489
  await using factory = await generateStorageFactory();
1447
- const syncRules = await factory.updateSyncRules(
1490
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
1491
+ factory,
1448
1492
  updateSyncRulesFromYaml(
1449
1493
  `
1450
1494
  bucket_definitions:
@@ -1457,7 +1501,7 @@ bucket_definitions:
1457
1501
  }
1458
1502
  )
1459
1503
  );
1460
- const bucketStorage = factory.getInstance(syncRules);
1504
+ const bucketStorage = factory.getInstance(replicationStream);
1461
1505
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1462
1506
 
1463
1507
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
@@ -1485,7 +1529,8 @@ bucket_definitions:
1485
1529
 
1486
1530
  test('empty checkpoints (1)', async () => {
1487
1531
  await using factory = await generateStorageFactory();
1488
- const syncRules = await factory.updateSyncRules(
1532
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
1533
+ factory,
1489
1534
  updateSyncRulesFromYaml(
1490
1535
  `
1491
1536
  bucket_definitions:
@@ -1496,7 +1541,7 @@ bucket_definitions:
1496
1541
  { storageVersion }
1497
1542
  )
1498
1543
  );
1499
- const bucketStorage = factory.getInstance(syncRules);
1544
+ const bucketStorage = factory.getInstance(replicationStream);
1500
1545
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1501
1546
  await writer.markAllSnapshotDone('1/1');
1502
1547
  await writer.commit('1/1');
@@ -1521,7 +1566,8 @@ bucket_definitions:
1521
1566
 
1522
1567
  test('empty checkpoints (2)', async () => {
1523
1568
  await using factory = await generateStorageFactory();
1524
- const syncRules = await factory.updateSyncRules(
1569
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
1570
+ factory,
1525
1571
  updateSyncRulesFromYaml(
1526
1572
  `
1527
1573
  bucket_definitions:
@@ -1534,7 +1580,7 @@ bucket_definitions:
1534
1580
  }
1535
1581
  )
1536
1582
  );
1537
- const bucketStorage = factory.getInstance(syncRules);
1583
+ const bucketStorage = factory.getInstance(replicationStream);
1538
1584
  await using writer1 = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1539
1585
  await using writer2 = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1540
1586
  const sourceTable = await test_utils.resolveTestTable(writer2, 'test', ['id'], config);
@@ -1571,7 +1617,8 @@ bucket_definitions:
1571
1617
 
1572
1618
  test('empty checkpoints (sync rule activation)', async () => {
1573
1619
  await using factory = await generateStorageFactory();
1574
- const syncRules = await factory.updateSyncRules(
1620
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
1621
+ factory,
1575
1622
  updateSyncRulesFromYaml(
1576
1623
  `
1577
1624
  bucket_definitions:
@@ -1584,7 +1631,7 @@ bucket_definitions:
1584
1631
  }
1585
1632
  )
1586
1633
  );
1587
- const bucketStorage = factory.getInstance(syncRules);
1634
+ const bucketStorage = factory.getInstance(replicationStream);
1588
1635
 
1589
1636
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1590
1637
  const result1 = await writer.commit('1/1', { createEmptyCheckpoints: false });
@@ -1609,8 +1656,8 @@ bucket_definitions:
1609
1656
  const cp2 = await bucketStorage.getCheckpoint();
1610
1657
  expect(cp2.lsn).toEqual('3/1');
1611
1658
 
1612
- const activeSyncRules = await factory.getActiveSyncRulesContent();
1613
- expect(activeSyncRules?.id).toEqual(syncRules.id);
1659
+ const activeSyncRules = await factory.getActiveSyncConfig();
1660
+ expect(activeSyncRules?.content.replicationStreamId).toEqual(syncRules.replicationStreamId);
1614
1661
 
1615
1662
  // At this point, it should be a truely empty checkpoint
1616
1663
  const result4 = await writer.commit('4/1', { createEmptyCheckpoints: false });
@@ -1623,7 +1670,8 @@ bucket_definitions:
1623
1670
 
1624
1671
  test.runIf(storageVersion >= 3)('deleting while streaming', async () => {
1625
1672
  await using factory = await generateStorageFactory();
1626
- const syncRules = await factory.updateSyncRules(
1673
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
1674
+ factory,
1627
1675
  updateSyncRulesFromYaml(
1628
1676
  `
1629
1677
  bucket_definitions:
@@ -1636,7 +1684,7 @@ bucket_definitions:
1636
1684
  }
1637
1685
  )
1638
1686
  );
1639
- const bucketStorage = factory.getInstance(syncRules);
1687
+ const bucketStorage = factory.getInstance(replicationStream);
1640
1688
  await using snapshotWriter = await bucketStorage.createWriter({
1641
1689
  ...test_utils.BATCH_OPTIONS,
1642
1690
  skipExistingRows: true
@@ -1692,7 +1740,8 @@ export function testChecksumBatching(config: storage.TestStorageConfig) {
1692
1740
  const storageVersion = config.storageVersion ?? CURRENT_STORAGE_VERSION;
1693
1741
  test('checksums for multiple buckets', async () => {
1694
1742
  await using factory = await config.factory();
1695
- const syncRules = await factory.updateSyncRules(
1743
+ const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
1744
+ factory,
1696
1745
  updateSyncRulesFromYaml(
1697
1746
  `
1698
1747
  bucket_definitions:
@@ -1706,7 +1755,7 @@ bucket_definitions:
1706
1755
  }
1707
1756
  )
1708
1757
  );
1709
- const bucketStorage = factory.getInstance(syncRules);
1758
+ const bucketStorage = factory.getInstance(replicationStream);
1710
1759
  await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
1711
1760
  const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
1712
1761
  await writer.markAllSnapshotDone('1/1');
@@ -1756,7 +1805,11 @@ streams:
1756
1805
  `)
1757
1806
  );
1758
1807
 
1759
- const { errors } = deployed.parsed({ defaultSchema: 'ignored' }).syncConfigWithErrors;
1808
+ const [deployedContent] = deployed.syncConfigContent;
1809
+ expect(deployedContent).toBeDefined();
1810
+ const [deployedConfig] = deployedContent.parsed({ defaultSchema: 'ignored' }).syncConfigs;
1811
+ expect(deployedConfig).toBeDefined();
1812
+ const { errors } = deployedConfig;
1760
1813
  expect(errors).toHaveLength(1);
1761
1814
  expect(errors[0].message).toStrictEqual('Expected a SELECT statement');
1762
1815
  expect(errors[0].location).toStrictEqual({