@powersync/service-core-tests 0.14.0 → 0.15.1

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 (38) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/test-utils/general-utils.d.ts +22 -3
  3. package/dist/test-utils/general-utils.js +56 -3
  4. package/dist/test-utils/general-utils.js.map +1 -1
  5. package/dist/test-utils/stream_utils.js +2 -2
  6. package/dist/test-utils/stream_utils.js.map +1 -1
  7. package/dist/tests/register-compacting-tests.d.ts +1 -1
  8. package/dist/tests/register-compacting-tests.js +360 -297
  9. package/dist/tests/register-compacting-tests.js.map +1 -1
  10. package/dist/tests/register-data-storage-checkpoint-tests.d.ts +1 -1
  11. package/dist/tests/register-data-storage-checkpoint-tests.js +59 -48
  12. package/dist/tests/register-data-storage-checkpoint-tests.js.map +1 -1
  13. package/dist/tests/register-data-storage-data-tests.d.ts +2 -2
  14. package/dist/tests/register-data-storage-data-tests.js +1112 -612
  15. package/dist/tests/register-data-storage-data-tests.js.map +1 -1
  16. package/dist/tests/register-data-storage-parameter-tests.d.ts +1 -1
  17. package/dist/tests/register-data-storage-parameter-tests.js +273 -254
  18. package/dist/tests/register-data-storage-parameter-tests.js.map +1 -1
  19. package/dist/tests/register-parameter-compacting-tests.d.ts +1 -1
  20. package/dist/tests/register-parameter-compacting-tests.js +83 -87
  21. package/dist/tests/register-parameter-compacting-tests.js.map +1 -1
  22. package/dist/tests/register-sync-tests.d.ts +2 -1
  23. package/dist/tests/register-sync-tests.js +479 -451
  24. package/dist/tests/register-sync-tests.js.map +1 -1
  25. package/dist/tests/util.d.ts +5 -4
  26. package/dist/tests/util.js +27 -12
  27. package/dist/tests/util.js.map +1 -1
  28. package/package.json +3 -3
  29. package/src/test-utils/general-utils.ts +81 -4
  30. package/src/test-utils/stream_utils.ts +2 -2
  31. package/src/tests/register-compacting-tests.ts +376 -322
  32. package/src/tests/register-data-storage-checkpoint-tests.ts +85 -53
  33. package/src/tests/register-data-storage-data-tests.ts +1050 -559
  34. package/src/tests/register-data-storage-parameter-tests.ts +330 -288
  35. package/src/tests/register-parameter-compacting-tests.ts +87 -90
  36. package/src/tests/register-sync-tests.ts +390 -380
  37. package/src/tests/util.ts +46 -17
  38. package/tsconfig.tsbuildinfo +1 -1
@@ -57,11 +57,9 @@ import * as timers from 'timers/promises';
57
57
  import { fileURLToPath } from 'url';
58
58
  import { expect, test } from 'vitest';
59
59
  import * as test_utils from '../test-utils/test-utils-index.js';
60
- import { METRICS_HELPER } from '../test-utils/test-utils-index.js';
61
- import { bucketRequest } from './util.js';
60
+ import { bucketRequest, METRICS_HELPER } from '../test-utils/test-utils-index.js';
62
61
  const __filename = fileURLToPath(import.meta.url);
63
62
  const __dirname = path.dirname(__filename);
64
- const TEST_TABLE = test_utils.makeTestTable('test', ['id']);
65
63
  const BASIC_SYNC_RULES = `
66
64
  bucket_definitions:
67
65
  mybucket:
@@ -77,7 +75,11 @@ export const SYNC_SNAPSHOT_PATH = path.resolve(__dirname, '../__snapshots/sync.t
77
75
  * });
78
76
  * ```
79
77
  */
80
- export function registerSyncTests(factory, options = {}) {
78
+ export function registerSyncTests(configOrFactory, options = {}) {
79
+ const config = typeof configOrFactory == 'function'
80
+ ? { factory: configOrFactory, tableIdStrings: options.tableIdStrings ?? true }
81
+ : configOrFactory;
82
+ const factory = config.factory;
81
83
  createCoreAPIMetrics(METRICS_HELPER.metricsEngine);
82
84
  const tracker = new sync.RequestTracker(METRICS_HELPER.metricsEngine);
83
85
  const syncContext = new sync.SyncContext({
@@ -99,27 +101,28 @@ export function registerSyncTests(factory, options = {}) {
99
101
  content: BASIC_SYNC_RULES
100
102
  });
101
103
  const bucketStorage = f.getInstance(syncRules);
102
- const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
103
- await batch.save({
104
- sourceTable: TEST_TABLE,
105
- tag: storage.SaveOperationTag.INSERT,
106
- after: {
107
- id: 't1',
108
- description: 'Test 1'
109
- },
110
- afterReplicaId: 't1'
111
- });
112
- await batch.save({
113
- sourceTable: TEST_TABLE,
114
- tag: storage.SaveOperationTag.INSERT,
115
- after: {
116
- id: 't2',
117
- description: 'Test 2'
118
- },
119
- afterReplicaId: 't2'
120
- });
121
- await batch.commit('0/1');
104
+ const writer = __addDisposableResource(env_1, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
105
+ const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
106
+ await writer.markAllSnapshotDone('0/1');
107
+ await writer.save({
108
+ sourceTable,
109
+ tag: storage.SaveOperationTag.INSERT,
110
+ after: {
111
+ id: 't1',
112
+ description: 'Test 1'
113
+ },
114
+ afterReplicaId: 't1'
115
+ });
116
+ await writer.save({
117
+ sourceTable,
118
+ tag: storage.SaveOperationTag.INSERT,
119
+ after: {
120
+ id: 't2',
121
+ description: 'Test 2'
122
+ },
123
+ afterReplicaId: 't2'
122
124
  });
125
+ await writer.commit('0/1');
123
126
  const stream = sync.streamResponse({
124
127
  syncContext,
125
128
  bucketStorage: bucketStorage,
@@ -164,27 +167,28 @@ bucket_definitions:
164
167
  `
165
168
  });
166
169
  const bucketStorage = f.getInstance(syncRules);
167
- const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
168
- await batch.save({
169
- sourceTable: TEST_TABLE,
170
- tag: storage.SaveOperationTag.INSERT,
171
- after: {
172
- id: 't1',
173
- description: 'Test 1'
174
- },
175
- afterReplicaId: 't1'
176
- });
177
- await batch.save({
178
- sourceTable: TEST_TABLE,
179
- tag: storage.SaveOperationTag.INSERT,
180
- after: {
181
- id: 'earlier',
182
- description: 'Test 2'
183
- },
184
- afterReplicaId: 'earlier'
185
- });
186
- await batch.commit('0/1');
170
+ const writer = __addDisposableResource(env_2, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
171
+ const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
172
+ await writer.markAllSnapshotDone('0/1');
173
+ await writer.save({
174
+ sourceTable: testTable,
175
+ tag: storage.SaveOperationTag.INSERT,
176
+ after: {
177
+ id: 't1',
178
+ description: 'Test 1'
179
+ },
180
+ afterReplicaId: 't1'
181
+ });
182
+ await writer.save({
183
+ sourceTable: testTable,
184
+ tag: storage.SaveOperationTag.INSERT,
185
+ after: {
186
+ id: 'earlier',
187
+ description: 'Test 2'
188
+ },
189
+ afterReplicaId: 'earlier'
187
190
  });
191
+ await writer.commit('0/1');
188
192
  const stream = sync.streamResponse({
189
193
  syncContext,
190
194
  bucketStorage,
@@ -229,30 +233,31 @@ bucket_definitions:
229
233
  `
230
234
  });
231
235
  const bucketStorage = f.getInstance(syncRules);
232
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
233
- // Initial data: Add one priority row and 10k low-priority rows.
234
- await batch.save({
235
- sourceTable: TEST_TABLE,
236
+ const writer = __addDisposableResource(env_3, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
237
+ const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
238
+ await writer.markAllSnapshotDone('0/1');
239
+ // Initial data: Add one priority row and 10k low-priority rows.
240
+ await writer.save({
241
+ sourceTable: testTable,
242
+ tag: storage.SaveOperationTag.INSERT,
243
+ after: {
244
+ id: 'highprio',
245
+ description: 'High priority row'
246
+ },
247
+ afterReplicaId: 'highprio'
248
+ });
249
+ for (let i = 0; i < 10_000; i++) {
250
+ await writer.save({
251
+ sourceTable: testTable,
236
252
  tag: storage.SaveOperationTag.INSERT,
237
253
  after: {
238
- id: 'highprio',
239
- description: 'High priority row'
254
+ id: `${i}`,
255
+ description: 'low prio'
240
256
  },
241
- afterReplicaId: 'highprio'
257
+ afterReplicaId: `${i}`
242
258
  });
243
- for (let i = 0; i < 10_000; i++) {
244
- await batch.save({
245
- sourceTable: TEST_TABLE,
246
- tag: storage.SaveOperationTag.INSERT,
247
- after: {
248
- id: `${i}`,
249
- description: 'low prio'
250
- },
251
- afterReplicaId: `${i}`
252
- });
253
- }
254
- await batch.commit('0/1');
255
- });
259
+ }
260
+ await writer.commit('0/1');
256
261
  const stream = sync.streamResponse({
257
262
  syncContext,
258
263
  bucketStorage,
@@ -276,19 +281,17 @@ bucket_definitions:
276
281
  if ('partial_checkpoint_complete' in next) {
277
282
  if (sentCheckpoints == 1) {
278
283
  // Save new data to interrupt the low-priority sync.
279
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
280
- // Add another high-priority row. This should interrupt the long-running low-priority sync.
281
- await batch.save({
282
- sourceTable: TEST_TABLE,
283
- tag: storage.SaveOperationTag.INSERT,
284
- after: {
285
- id: 'highprio2',
286
- description: 'Another high-priority row'
287
- },
288
- afterReplicaId: 'highprio2'
289
- });
290
- await batch.commit('0/2');
284
+ // Add another high-priority row. This should interrupt the long-running low-priority sync.
285
+ await writer.save({
286
+ sourceTable: testTable,
287
+ tag: storage.SaveOperationTag.INSERT,
288
+ after: {
289
+ id: 'highprio2',
290
+ description: 'Another high-priority row'
291
+ },
292
+ afterReplicaId: 'highprio2'
291
293
  });
294
+ await writer.commit('0/2');
292
295
  }
293
296
  else {
294
297
  // Low-priority sync from the first checkpoint was interrupted. This should not happen before
@@ -340,30 +343,31 @@ bucket_definitions:
340
343
  `
341
344
  });
342
345
  const bucketStorage = f.getInstance(syncRules);
343
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
344
- // Initial data: Add one priority row and 10k low-priority rows.
345
- await batch.save({
346
- sourceTable: TEST_TABLE,
346
+ const writer = __addDisposableResource(env_4, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
347
+ const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
348
+ await writer.markAllSnapshotDone('0/1');
349
+ // Initial data: Add one priority row and 10k low-priority rows.
350
+ await writer.save({
351
+ sourceTable: testTable,
352
+ tag: storage.SaveOperationTag.INSERT,
353
+ after: {
354
+ id: 'highprio',
355
+ description: 'user_one'
356
+ },
357
+ afterReplicaId: 'highprio'
358
+ });
359
+ for (let i = 0; i < 10_000; i++) {
360
+ await writer.save({
361
+ sourceTable: testTable,
347
362
  tag: storage.SaveOperationTag.INSERT,
348
363
  after: {
349
- id: 'highprio',
350
- description: 'user_one'
364
+ id: `${i}`,
365
+ description: 'low prio'
351
366
  },
352
- afterReplicaId: 'highprio'
367
+ afterReplicaId: `${i}`
353
368
  });
354
- for (let i = 0; i < 10_000; i++) {
355
- await batch.save({
356
- sourceTable: TEST_TABLE,
357
- tag: storage.SaveOperationTag.INSERT,
358
- after: {
359
- id: `${i}`,
360
- description: 'low prio'
361
- },
362
- afterReplicaId: `${i}`
363
- });
364
- }
365
- await batch.commit('0/1');
366
- });
369
+ }
370
+ await writer.commit('0/1');
367
371
  const stream = sync.streamResponse({
368
372
  syncContext,
369
373
  bucketStorage,
@@ -392,19 +396,17 @@ bucket_definitions:
392
396
  if (typeof next === 'object' && next !== null) {
393
397
  if ('partial_checkpoint_complete' in next) {
394
398
  if (sentCheckpoints == 1) {
395
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
396
- // Add a high-priority row that doesn't affect this sync stream.
397
- await batch.save({
398
- sourceTable: TEST_TABLE,
399
- tag: storage.SaveOperationTag.INSERT,
400
- after: {
401
- id: 'highprio2',
402
- description: 'user_two'
403
- },
404
- afterReplicaId: 'highprio2'
405
- });
406
- await batch.commit('0/2');
399
+ // Add a high-priority row that doesn't affect this sync stream.
400
+ await writer.save({
401
+ sourceTable: testTable,
402
+ tag: storage.SaveOperationTag.INSERT,
403
+ after: {
404
+ id: 'highprio2',
405
+ description: 'user_two'
406
+ },
407
+ afterReplicaId: 'highprio2'
407
408
  });
409
+ await writer.commit('0/2');
408
410
  }
409
411
  else {
410
412
  expect(sentCheckpoints).toBe(2);
@@ -424,19 +426,17 @@ bucket_definitions:
424
426
  }
425
427
  if (completedCheckpoints == 1) {
426
428
  expect(sentRows).toBe(10001);
427
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
428
- // Add a high-priority row that affects this sync stream.
429
- await batch.save({
430
- sourceTable: TEST_TABLE,
431
- tag: storage.SaveOperationTag.INSERT,
432
- after: {
433
- id: 'highprio3',
434
- description: 'user_one'
435
- },
436
- afterReplicaId: 'highprio3'
437
- });
438
- await batch.commit('0/3');
429
+ // Add a high-priority row that affects this sync stream.
430
+ await writer.save({
431
+ sourceTable: testTable,
432
+ tag: storage.SaveOperationTag.INSERT,
433
+ after: {
434
+ id: 'highprio3',
435
+ description: 'user_one'
436
+ },
437
+ afterReplicaId: 'highprio3'
439
438
  });
439
+ await writer.commit('0/3');
440
440
  }
441
441
  }
442
442
  }
@@ -479,30 +479,31 @@ bucket_definitions:
479
479
  `
480
480
  });
481
481
  const bucketStorage = f.getInstance(syncRules);
482
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
483
- // Initial data: Add one priority row and 10k low-priority rows.
484
- await batch.save({
485
- sourceTable: TEST_TABLE,
482
+ const writer = __addDisposableResource(env_5, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
483
+ const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
484
+ await writer.markAllSnapshotDone('0/1');
485
+ // Initial data: Add one priority row and 10k low-priority rows.
486
+ await writer.save({
487
+ sourceTable: testTable,
488
+ tag: storage.SaveOperationTag.INSERT,
489
+ after: {
490
+ id: 'highprio',
491
+ description: 'High priority row'
492
+ },
493
+ afterReplicaId: 'highprio'
494
+ });
495
+ for (let i = 0; i < 2_000; i++) {
496
+ await writer.save({
497
+ sourceTable: testTable,
486
498
  tag: storage.SaveOperationTag.INSERT,
487
499
  after: {
488
- id: 'highprio',
489
- description: 'High priority row'
500
+ id: `${i}`,
501
+ description: 'low prio'
490
502
  },
491
- afterReplicaId: 'highprio'
503
+ afterReplicaId: `${i}`
492
504
  });
493
- for (let i = 0; i < 2_000; i++) {
494
- await batch.save({
495
- sourceTable: TEST_TABLE,
496
- tag: storage.SaveOperationTag.INSERT,
497
- after: {
498
- id: `${i}`,
499
- description: 'low prio'
500
- },
501
- afterReplicaId: `${i}`
502
- });
503
- }
504
- await batch.commit('0/1');
505
- });
505
+ }
506
+ await writer.commit('0/1');
506
507
  const stream = sync.streamResponse({
507
508
  syncContext,
508
509
  bucketStorage,
@@ -534,29 +535,27 @@ bucket_definitions:
534
535
  sentRows += next.data.data.length;
535
536
  if (sentRows == 1001) {
536
537
  // Save new data to interrupt the low-priority sync.
537
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
538
- // Add another high-priority row. This should interrupt the long-running low-priority sync.
539
- await batch.save({
540
- sourceTable: TEST_TABLE,
541
- tag: storage.SaveOperationTag.INSERT,
542
- after: {
543
- id: 'highprio2',
544
- description: 'Another high-priority row'
545
- },
546
- afterReplicaId: 'highprio2'
547
- });
548
- // Also add a low-priority row
549
- await batch.save({
550
- sourceTable: TEST_TABLE,
551
- tag: storage.SaveOperationTag.INSERT,
552
- after: {
553
- id: '2001',
554
- description: 'Another low-priority row'
555
- },
556
- afterReplicaId: '2001'
557
- });
558
- await batch.commit('0/2');
538
+ // Add another high-priority row. This should interrupt the long-running low-priority sync.
539
+ await writer.save({
540
+ sourceTable: testTable,
541
+ tag: storage.SaveOperationTag.INSERT,
542
+ after: {
543
+ id: 'highprio2',
544
+ description: 'Another high-priority row'
545
+ },
546
+ afterReplicaId: 'highprio2'
547
+ });
548
+ // Also add a low-priority row
549
+ await writer.save({
550
+ sourceTable: testTable,
551
+ tag: storage.SaveOperationTag.INSERT,
552
+ after: {
553
+ id: '2001',
554
+ description: 'Another low-priority row'
555
+ },
556
+ afterReplicaId: '2001'
559
557
  });
558
+ await writer.commit('0/2');
560
559
  }
561
560
  if (sentRows >= 1000 && sentRows <= 2001) {
562
561
  // pause for a bit to give the stream time to process interruptions.
@@ -607,18 +606,19 @@ bucket_definitions:
607
606
  content: BASIC_SYNC_RULES
608
607
  });
609
608
  const bucketStorage = f.getInstance(syncRules);
610
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
611
- await batch.save({
612
- sourceTable: TEST_TABLE,
613
- tag: storage.SaveOperationTag.INSERT,
614
- after: {
615
- id: 't1',
616
- description: 'sync'
617
- },
618
- afterReplicaId: 't1'
619
- });
620
- await batch.commit('0/1');
609
+ const writer = __addDisposableResource(env_6, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
610
+ const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
611
+ await writer.markAllSnapshotDone('0/1');
612
+ await writer.save({
613
+ sourceTable: testTable,
614
+ tag: storage.SaveOperationTag.INSERT,
615
+ after: {
616
+ id: 't1',
617
+ description: 'sync'
618
+ },
619
+ afterReplicaId: 't1'
621
620
  });
621
+ await writer.commit('0/1');
622
622
  const stream = sync.streamResponse({
623
623
  syncContext,
624
624
  bucketStorage,
@@ -645,9 +645,7 @@ bucket_definitions:
645
645
  if (receivedCompletions == 1) {
646
646
  // Trigger an empty bucket update.
647
647
  await bucketStorage.createManagedWriteCheckpoint({ user_id: '', heads: { '1': '1/0' } });
648
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
649
- await batch.commit('1/0');
650
- });
648
+ await writer.commit('1/0');
651
649
  }
652
650
  else {
653
651
  break;
@@ -668,14 +666,18 @@ bucket_definitions:
668
666
  }
669
667
  });
670
668
  test('sync legacy non-raw data', async () => {
671
- const f = await factory();
672
- const syncRules = await updateSyncRules(f, {
673
- content: BASIC_SYNC_RULES
674
- });
675
- const bucketStorage = await f.getInstance(syncRules);
676
- const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
677
- await batch.save({
678
- sourceTable: TEST_TABLE,
669
+ const env_7 = { stack: [], error: void 0, hasError: false };
670
+ try {
671
+ const f = __addDisposableResource(env_7, await factory(), true);
672
+ const syncRules = await updateSyncRules(f, {
673
+ content: BASIC_SYNC_RULES
674
+ });
675
+ const bucketStorage = await f.getInstance(syncRules);
676
+ const writer = __addDisposableResource(env_7, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
677
+ const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
678
+ await writer.markAllSnapshotDone('0/1');
679
+ await writer.save({
680
+ sourceTable: testTable,
679
681
  tag: storage.SaveOperationTag.INSERT,
680
682
  after: {
681
683
  id: 't1',
@@ -684,30 +686,39 @@ bucket_definitions:
684
686
  },
685
687
  afterReplicaId: 't1'
686
688
  });
687
- await batch.commit('0/1');
688
- });
689
- const stream = sync.streamResponse({
690
- syncContext,
691
- bucketStorage,
692
- syncRules: bucketStorage.getParsedSyncRules(test_utils.PARSE_OPTIONS),
693
- params: {
694
- buckets: [],
695
- include_checksum: true,
696
- raw_data: false
697
- },
698
- tracker,
699
- token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
700
- isEncodingAsBson: false
701
- });
702
- const lines = await consumeCheckpointLines(stream);
703
- expect(lines).toMatchSnapshot();
704
- // Specifically check the number - this is the important part of the test
705
- expect(lines[1].data.data[0].data.large_num).toEqual(12345678901234567890n);
689
+ await writer.commit('0/1');
690
+ const stream = sync.streamResponse({
691
+ syncContext,
692
+ bucketStorage,
693
+ syncRules: bucketStorage.getParsedSyncRules(test_utils.PARSE_OPTIONS),
694
+ params: {
695
+ buckets: [],
696
+ include_checksum: true,
697
+ raw_data: false
698
+ },
699
+ tracker,
700
+ token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
701
+ isEncodingAsBson: false
702
+ });
703
+ const lines = await consumeCheckpointLines(stream);
704
+ expect(lines).toMatchSnapshot();
705
+ // Specifically check the number - this is the important part of the test
706
+ expect(lines[1].data.data[0].data.large_num).toEqual(12345678901234567890n);
707
+ }
708
+ catch (e_7) {
709
+ env_7.error = e_7;
710
+ env_7.hasError = true;
711
+ }
712
+ finally {
713
+ const result_7 = __disposeResources(env_7);
714
+ if (result_7)
715
+ await result_7;
716
+ }
706
717
  });
707
718
  test('expired token', async () => {
708
- const env_7 = { stack: [], error: void 0, hasError: false };
719
+ const env_8 = { stack: [], error: void 0, hasError: false };
709
720
  try {
710
- const f = __addDisposableResource(env_7, await factory(), true);
721
+ const f = __addDisposableResource(env_8, await factory(), true);
711
722
  const syncRules = await updateSyncRules(f, {
712
723
  content: BASIC_SYNC_RULES
713
724
  });
@@ -728,28 +739,29 @@ bucket_definitions:
728
739
  const lines = await consumeCheckpointLines(stream);
729
740
  expect(lines).toMatchSnapshot();
730
741
  }
731
- catch (e_7) {
732
- env_7.error = e_7;
733
- env_7.hasError = true;
742
+ catch (e_8) {
743
+ env_8.error = e_8;
744
+ env_8.hasError = true;
734
745
  }
735
746
  finally {
736
- const result_7 = __disposeResources(env_7);
737
- if (result_7)
738
- await result_7;
747
+ const result_8 = __disposeResources(env_8);
748
+ if (result_8)
749
+ await result_8;
739
750
  }
740
751
  });
741
752
  test('sync updates to global data', async (context) => {
742
- const env_8 = { stack: [], error: void 0, hasError: false };
753
+ const env_9 = { stack: [], error: void 0, hasError: false };
743
754
  try {
744
- const f = __addDisposableResource(env_8, await factory(), true);
755
+ const f = __addDisposableResource(env_9, await factory(), true);
745
756
  const syncRules = await updateSyncRules(f, {
746
757
  content: BASIC_SYNC_RULES
747
758
  });
748
759
  const bucketStorage = await f.getInstance(syncRules);
760
+ const writer = __addDisposableResource(env_9, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
761
+ const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
749
762
  // Activate
750
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
751
- await batch.keepalive('0/0');
752
- });
763
+ await writer.markAllSnapshotDone('0/0');
764
+ await writer.keepalive('0/0');
753
765
  const stream = sync.streamResponse({
754
766
  syncContext,
755
767
  bucketStorage,
@@ -768,47 +780,43 @@ bucket_definitions:
768
780
  iter.return?.();
769
781
  });
770
782
  expect(await getCheckpointLines(iter)).toMatchSnapshot();
771
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
772
- await batch.save({
773
- sourceTable: TEST_TABLE,
774
- tag: storage.SaveOperationTag.INSERT,
775
- after: {
776
- id: 't1',
777
- description: 'Test 1'
778
- },
779
- afterReplicaId: 't1'
780
- });
781
- await batch.commit('0/1');
783
+ await writer.save({
784
+ sourceTable: testTable,
785
+ tag: storage.SaveOperationTag.INSERT,
786
+ after: {
787
+ id: 't1',
788
+ description: 'Test 1'
789
+ },
790
+ afterReplicaId: 't1'
782
791
  });
792
+ await writer.commit('0/1');
783
793
  expect(await getCheckpointLines(iter)).toMatchSnapshot();
784
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
785
- await batch.save({
786
- sourceTable: TEST_TABLE,
787
- tag: storage.SaveOperationTag.INSERT,
788
- after: {
789
- id: 't2',
790
- description: 'Test 2'
791
- },
792
- afterReplicaId: 't2'
793
- });
794
- await batch.commit('0/2');
794
+ await writer.save({
795
+ sourceTable: testTable,
796
+ tag: storage.SaveOperationTag.INSERT,
797
+ after: {
798
+ id: 't2',
799
+ description: 'Test 2'
800
+ },
801
+ afterReplicaId: 't2'
795
802
  });
803
+ await writer.commit('0/2');
796
804
  expect(await getCheckpointLines(iter)).toMatchSnapshot();
797
805
  }
798
- catch (e_8) {
799
- env_8.error = e_8;
800
- env_8.hasError = true;
806
+ catch (e_9) {
807
+ env_9.error = e_9;
808
+ env_9.hasError = true;
801
809
  }
802
810
  finally {
803
- const result_8 = __disposeResources(env_8);
804
- if (result_8)
805
- await result_8;
811
+ const result_9 = __disposeResources(env_9);
812
+ if (result_9)
813
+ await result_9;
806
814
  }
807
815
  });
808
816
  test('sync updates to parameter query only', async (context) => {
809
- const env_9 = { stack: [], error: void 0, hasError: false };
817
+ const env_10 = { stack: [], error: void 0, hasError: false };
810
818
  try {
811
- const f = __addDisposableResource(env_9, await factory(), true);
819
+ const f = __addDisposableResource(env_10, await factory(), true);
812
820
  const syncRules = await updateSyncRules(f, {
813
821
  content: `bucket_definitions:
814
822
  by_user:
@@ -817,13 +825,12 @@ bucket_definitions:
817
825
  - select * from lists where user_id = bucket.user_id
818
826
  `
819
827
  });
820
- const usersTable = test_utils.makeTestTable('users', ['id']);
821
- const listsTable = test_utils.makeTestTable('lists', ['id']);
822
828
  const bucketStorage = await f.getInstance(syncRules);
829
+ const writer = __addDisposableResource(env_10, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
830
+ const usersTable = await test_utils.resolveTestTable(writer, 'users', ['id'], config, 1);
823
831
  // Activate
824
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
825
- await batch.keepalive('0/0');
826
- });
832
+ await writer.markAllSnapshotDone('0/0');
833
+ await writer.keepalive('0/0');
827
834
  const stream = sync.streamResponse({
828
835
  syncContext,
829
836
  bucketStorage,
@@ -846,36 +853,35 @@ bucket_definitions:
846
853
  expect(checkpoint1[0].checkpoint?.buckets?.map((b) => b.bucket)).toEqual([]);
847
854
  expect(checkpoint1).toMatchSnapshot();
848
855
  // Add user
849
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
850
- await batch.save({
851
- sourceTable: usersTable,
852
- tag: storage.SaveOperationTag.INSERT,
853
- after: {
854
- id: 'user1',
855
- name: 'User 1'
856
- },
857
- afterReplicaId: 'user1'
858
- });
859
- await batch.commit('0/1');
856
+ await writer.save({
857
+ sourceTable: usersTable,
858
+ tag: storage.SaveOperationTag.INSERT,
859
+ after: {
860
+ id: 'user1',
861
+ name: 'User 1'
862
+ },
863
+ afterReplicaId: 'user1'
860
864
  });
865
+ await writer.commit('0/1');
861
866
  const checkpoint2 = await getCheckpointLines(iter);
862
- expect(checkpoint2[0].checkpoint_diff?.updated_buckets?.map((b) => b.bucket)).toEqual([bucketRequest(syncRules, 'by_user["user1"]')]);
867
+ const { bucket } = test_utils.bucketRequest(syncRules, 'by_user["user1"]');
868
+ expect(checkpoint2[0].checkpoint_diff?.updated_buckets?.map((b) => b.bucket)).toEqual([bucket]);
863
869
  expect(checkpoint2).toMatchSnapshot();
864
870
  }
865
- catch (e_9) {
866
- env_9.error = e_9;
867
- env_9.hasError = true;
871
+ catch (e_10) {
872
+ env_10.error = e_10;
873
+ env_10.hasError = true;
868
874
  }
869
875
  finally {
870
- const result_9 = __disposeResources(env_9);
871
- if (result_9)
872
- await result_9;
876
+ const result_10 = __disposeResources(env_10);
877
+ if (result_10)
878
+ await result_10;
873
879
  }
874
880
  });
875
881
  test('sync updates to data query only', async (context) => {
876
- const env_10 = { stack: [], error: void 0, hasError: false };
882
+ const env_11 = { stack: [], error: void 0, hasError: false };
877
883
  try {
878
- const f = __addDisposableResource(env_10, await factory(), true);
884
+ const f = __addDisposableResource(env_11, await factory(), true);
879
885
  const syncRules = await updateSyncRules(f, {
880
886
  content: `bucket_definitions:
881
887
  by_user:
@@ -884,21 +890,21 @@ bucket_definitions:
884
890
  - select * from lists where user_id = bucket.user_id
885
891
  `
886
892
  });
887
- const usersTable = test_utils.makeTestTable('users', ['id']);
888
- const listsTable = test_utils.makeTestTable('lists', ['id']);
889
893
  const bucketStorage = await f.getInstance(syncRules);
890
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
891
- await batch.save({
892
- sourceTable: usersTable,
893
- tag: storage.SaveOperationTag.INSERT,
894
- after: {
895
- id: 'user1',
896
- name: 'User 1'
897
- },
898
- afterReplicaId: 'user1'
899
- });
900
- await batch.commit('0/1');
894
+ const writer = __addDisposableResource(env_11, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
895
+ const usersTable = await test_utils.resolveTestTable(writer, 'users', ['id'], config, 1);
896
+ const listsTable = await test_utils.resolveTestTable(writer, 'lists', ['id'], config, 2);
897
+ await writer.markAllSnapshotDone('0/1');
898
+ await writer.save({
899
+ sourceTable: usersTable,
900
+ tag: storage.SaveOperationTag.INSERT,
901
+ after: {
902
+ id: 'user1',
903
+ name: 'User 1'
904
+ },
905
+ afterReplicaId: 'user1'
901
906
  });
907
+ await writer.commit('0/1');
902
908
  const stream = sync.streamResponse({
903
909
  syncContext,
904
910
  bucketStorage,
@@ -916,42 +922,39 @@ bucket_definitions:
916
922
  context.onTestFinished(() => {
917
923
  iter.return?.();
918
924
  });
925
+ const { bucket } = bucketRequest(syncRules, 'by_user["user1"]');
919
926
  const checkpoint1 = await getCheckpointLines(iter);
920
- expect(checkpoint1[0].checkpoint?.buckets?.map((b) => b.bucket)).toEqual([
921
- bucketRequest(syncRules, 'by_user["user1"]')
922
- ]);
927
+ expect(checkpoint1[0].checkpoint?.buckets?.map((b) => b.bucket)).toEqual([bucket]);
923
928
  expect(checkpoint1).toMatchSnapshot();
924
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
925
- await batch.save({
926
- sourceTable: listsTable,
927
- tag: storage.SaveOperationTag.INSERT,
928
- after: {
929
- id: 'list1',
930
- user_id: 'user1',
931
- name: 'User 1'
932
- },
933
- afterReplicaId: 'list1'
934
- });
935
- await batch.commit('0/1');
929
+ await writer.save({
930
+ sourceTable: listsTable,
931
+ tag: storage.SaveOperationTag.INSERT,
932
+ after: {
933
+ id: 'list1',
934
+ user_id: 'user1',
935
+ name: 'User 1'
936
+ },
937
+ afterReplicaId: 'list1'
936
938
  });
939
+ await writer.commit('0/1');
937
940
  const checkpoint2 = await getCheckpointLines(iter);
938
- expect(checkpoint2[0].checkpoint_diff?.updated_buckets?.map((b) => b.bucket)).toEqual([bucketRequest(syncRules, 'by_user["user1"]')]);
941
+ expect(checkpoint2[0].checkpoint_diff?.updated_buckets?.map((b) => b.bucket)).toEqual([bucket]);
939
942
  expect(checkpoint2).toMatchSnapshot();
940
943
  }
941
- catch (e_10) {
942
- env_10.error = e_10;
943
- env_10.hasError = true;
944
+ catch (e_11) {
945
+ env_11.error = e_11;
946
+ env_11.hasError = true;
944
947
  }
945
948
  finally {
946
- const result_10 = __disposeResources(env_10);
947
- if (result_10)
948
- await result_10;
949
+ const result_11 = __disposeResources(env_11);
950
+ if (result_11)
951
+ await result_11;
949
952
  }
950
953
  });
951
954
  test('sync updates to parameter query + data', async (context) => {
952
- const env_11 = { stack: [], error: void 0, hasError: false };
955
+ const env_12 = { stack: [], error: void 0, hasError: false };
953
956
  try {
954
- const f = __addDisposableResource(env_11, await factory(), true);
957
+ const f = __addDisposableResource(env_12, await factory(), true);
955
958
  const syncRules = await updateSyncRules(f, {
956
959
  content: `bucket_definitions:
957
960
  by_user:
@@ -960,13 +963,13 @@ bucket_definitions:
960
963
  - select * from lists where user_id = bucket.user_id
961
964
  `
962
965
  });
963
- const usersTable = test_utils.makeTestTable('users', ['id']);
964
- const listsTable = test_utils.makeTestTable('lists', ['id']);
965
966
  const bucketStorage = await f.getInstance(syncRules);
967
+ const writer = __addDisposableResource(env_12, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
968
+ const usersTable = await test_utils.resolveTestTable(writer, 'users', ['id'], config, 1);
969
+ const listsTable = await test_utils.resolveTestTable(writer, 'lists', ['id'], config, 2);
966
970
  // Activate
967
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
968
- await batch.keepalive('0/0');
969
- });
971
+ await writer.markAllSnapshotDone('0/0');
972
+ await writer.keepalive('0/0');
970
973
  const stream = sync.streamResponse({
971
974
  syncContext,
972
975
  bucketStorage,
@@ -986,54 +989,54 @@ bucket_definitions:
986
989
  });
987
990
  // Initial empty checkpoint
988
991
  expect(await getCheckpointLines(iter)).toMatchSnapshot();
989
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
990
- await batch.save({
991
- sourceTable: listsTable,
992
- tag: storage.SaveOperationTag.INSERT,
993
- after: {
994
- id: 'list1',
995
- user_id: 'user1',
996
- name: 'User 1'
997
- },
998
- afterReplicaId: 'list1'
999
- });
1000
- await batch.save({
1001
- sourceTable: usersTable,
1002
- tag: storage.SaveOperationTag.INSERT,
1003
- after: {
1004
- id: 'user1',
1005
- name: 'User 1'
1006
- },
1007
- afterReplicaId: 'user1'
1008
- });
1009
- await batch.commit('0/1');
992
+ await writer.markAllSnapshotDone('0/1');
993
+ await writer.save({
994
+ sourceTable: listsTable,
995
+ tag: storage.SaveOperationTag.INSERT,
996
+ after: {
997
+ id: 'list1',
998
+ user_id: 'user1',
999
+ name: 'User 1'
1000
+ },
1001
+ afterReplicaId: 'list1'
1002
+ });
1003
+ await writer.save({
1004
+ sourceTable: usersTable,
1005
+ tag: storage.SaveOperationTag.INSERT,
1006
+ after: {
1007
+ id: 'user1',
1008
+ name: 'User 1'
1009
+ },
1010
+ afterReplicaId: 'user1'
1010
1011
  });
1012
+ await writer.commit('0/1');
1013
+ const { bucket } = test_utils.bucketRequest(syncRules, 'by_user["user1"]');
1011
1014
  const checkpoint2 = await getCheckpointLines(iter);
1012
- expect(checkpoint2[0].checkpoint_diff?.updated_buckets?.map((b) => b.bucket)).toEqual([bucketRequest(syncRules, 'by_user["user1"]')]);
1015
+ expect(checkpoint2[0].checkpoint_diff?.updated_buckets?.map((b) => b.bucket)).toEqual([bucket]);
1013
1016
  expect(checkpoint2).toMatchSnapshot();
1014
1017
  }
1015
- catch (e_11) {
1016
- env_11.error = e_11;
1017
- env_11.hasError = true;
1018
+ catch (e_12) {
1019
+ env_12.error = e_12;
1020
+ env_12.hasError = true;
1018
1021
  }
1019
1022
  finally {
1020
- const result_11 = __disposeResources(env_11);
1021
- if (result_11)
1022
- await result_11;
1023
+ const result_12 = __disposeResources(env_12);
1024
+ if (result_12)
1025
+ await result_12;
1023
1026
  }
1024
1027
  });
1025
1028
  test('expiring token', async (context) => {
1026
- const env_12 = { stack: [], error: void 0, hasError: false };
1029
+ const env_13 = { stack: [], error: void 0, hasError: false };
1027
1030
  try {
1028
- const f = __addDisposableResource(env_12, await factory(), true);
1031
+ const f = __addDisposableResource(env_13, await factory(), true);
1029
1032
  const syncRules = await updateSyncRules(f, {
1030
1033
  content: BASIC_SYNC_RULES
1031
1034
  });
1032
1035
  const bucketStorage = await f.getInstance(syncRules);
1036
+ const writer = __addDisposableResource(env_13, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
1033
1037
  // Activate
1034
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
1035
- await batch.keepalive('0/0');
1036
- });
1038
+ await writer.markAllSnapshotDone('0/0');
1039
+ await writer.keepalive('0/0');
1037
1040
  const exp = Date.now() / 1000 + 0.1;
1038
1041
  const stream = sync.streamResponse({
1039
1042
  syncContext,
@@ -1057,49 +1060,50 @@ bucket_definitions:
1057
1060
  const expLines = await getCheckpointLines(iter);
1058
1061
  expect(expLines).toMatchSnapshot();
1059
1062
  }
1060
- catch (e_12) {
1061
- env_12.error = e_12;
1062
- env_12.hasError = true;
1063
+ catch (e_13) {
1064
+ env_13.error = e_13;
1065
+ env_13.hasError = true;
1063
1066
  }
1064
1067
  finally {
1065
- const result_12 = __disposeResources(env_12);
1066
- if (result_12)
1067
- await result_12;
1068
+ const result_13 = __disposeResources(env_13);
1069
+ if (result_13)
1070
+ await result_13;
1068
1071
  }
1069
1072
  });
1070
1073
  test('compacting data - invalidate checkpoint', async (context) => {
1071
- const env_13 = { stack: [], error: void 0, hasError: false };
1074
+ const env_14 = { stack: [], error: void 0, hasError: false };
1072
1075
  try {
1073
1076
  // This tests a case of a compact operation invalidating a checkpoint in the
1074
1077
  // middle of syncing data.
1075
1078
  // This is expected to be rare in practice, but it is important to handle
1076
1079
  // this case correctly to maintain consistency on the client.
1077
- const f = __addDisposableResource(env_13, await factory(), true);
1080
+ const f = __addDisposableResource(env_14, await factory(), true);
1078
1081
  const syncRules = await updateSyncRules(f, {
1079
1082
  content: BASIC_SYNC_RULES
1080
1083
  });
1081
1084
  const bucketStorage = await f.getInstance(syncRules);
1082
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
1083
- await batch.save({
1084
- sourceTable: TEST_TABLE,
1085
- tag: storage.SaveOperationTag.INSERT,
1086
- after: {
1087
- id: 't1',
1088
- description: 'Test 1'
1089
- },
1090
- afterReplicaId: 't1'
1091
- });
1092
- await batch.save({
1093
- sourceTable: TEST_TABLE,
1094
- tag: storage.SaveOperationTag.INSERT,
1095
- after: {
1096
- id: 't2',
1097
- description: 'Test 2'
1098
- },
1099
- afterReplicaId: 't2'
1100
- });
1101
- await batch.commit('0/1');
1085
+ const writer = __addDisposableResource(env_14, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
1086
+ const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
1087
+ await writer.markAllSnapshotDone('0/1');
1088
+ await writer.save({
1089
+ sourceTable: testTable,
1090
+ tag: storage.SaveOperationTag.INSERT,
1091
+ after: {
1092
+ id: 't1',
1093
+ description: 'Test 1'
1094
+ },
1095
+ afterReplicaId: 't1'
1102
1096
  });
1097
+ await writer.save({
1098
+ sourceTable: testTable,
1099
+ tag: storage.SaveOperationTag.INSERT,
1100
+ after: {
1101
+ id: 't2',
1102
+ description: 'Test 2'
1103
+ },
1104
+ afterReplicaId: 't2'
1105
+ });
1106
+ await writer.commit('0/1');
1103
1107
  const stream = sync.streamResponse({
1104
1108
  syncContext,
1105
1109
  bucketStorage,
@@ -1127,27 +1131,26 @@ bucket_definitions:
1127
1131
  });
1128
1132
  // Now we save additional data AND compact before continuing.
1129
1133
  // This invalidates the checkpoint we've received above.
1130
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
1131
- await batch.save({
1132
- sourceTable: TEST_TABLE,
1133
- tag: storage.SaveOperationTag.UPDATE,
1134
- after: {
1135
- id: 't1',
1136
- description: 'Test 1b'
1137
- },
1138
- afterReplicaId: 't1'
1139
- });
1140
- await batch.save({
1141
- sourceTable: TEST_TABLE,
1142
- tag: storage.SaveOperationTag.UPDATE,
1143
- after: {
1144
- id: 't2',
1145
- description: 'Test 2b'
1146
- },
1147
- afterReplicaId: 't2'
1148
- });
1149
- await batch.commit('0/2');
1134
+ await writer.markAllSnapshotDone('0/1');
1135
+ await writer.save({
1136
+ sourceTable: testTable,
1137
+ tag: storage.SaveOperationTag.UPDATE,
1138
+ after: {
1139
+ id: 't1',
1140
+ description: 'Test 1b'
1141
+ },
1142
+ afterReplicaId: 't1'
1150
1143
  });
1144
+ await writer.save({
1145
+ sourceTable: testTable,
1146
+ tag: storage.SaveOperationTag.UPDATE,
1147
+ after: {
1148
+ id: 't2',
1149
+ description: 'Test 2b'
1150
+ },
1151
+ afterReplicaId: 't2'
1152
+ });
1153
+ await writer.commit('0/2');
1151
1154
  await bucketStorage.compact({
1152
1155
  minBucketChanges: 1,
1153
1156
  minChangeRatio: 0
@@ -1195,28 +1198,28 @@ bucket_definitions:
1195
1198
  })
1196
1199
  });
1197
1200
  }
1198
- catch (e_13) {
1199
- env_13.error = e_13;
1200
- env_13.hasError = true;
1201
+ catch (e_14) {
1202
+ env_14.error = e_14;
1203
+ env_14.hasError = true;
1201
1204
  }
1202
1205
  finally {
1203
- const result_13 = __disposeResources(env_13);
1204
- if (result_13)
1205
- await result_13;
1206
+ const result_14 = __disposeResources(env_14);
1207
+ if (result_14)
1208
+ await result_14;
1206
1209
  }
1207
1210
  });
1208
1211
  test('write checkpoint', async () => {
1209
- const env_14 = { stack: [], error: void 0, hasError: false };
1212
+ const env_15 = { stack: [], error: void 0, hasError: false };
1210
1213
  try {
1211
- const f = __addDisposableResource(env_14, await factory(), true);
1214
+ const f = __addDisposableResource(env_15, await factory(), true);
1212
1215
  const syncRules = await updateSyncRules(f, {
1213
1216
  content: BASIC_SYNC_RULES
1214
1217
  });
1215
1218
  const bucketStorage = f.getInstance(syncRules);
1216
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
1217
- // <= the managed write checkpoint LSN below
1218
- await batch.commit('0/1');
1219
- });
1219
+ const writer = __addDisposableResource(env_15, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
1220
+ await writer.markAllSnapshotDone('0/1');
1221
+ // <= the managed write checkpoint LSN below
1222
+ await writer.commit('0/1');
1220
1223
  const checkpoint = await bucketStorage.createManagedWriteCheckpoint({
1221
1224
  user_id: 'test',
1222
1225
  heads: { '1': '1/0' }
@@ -1244,10 +1247,9 @@ bucket_definitions:
1244
1247
  write_checkpoint: undefined
1245
1248
  })
1246
1249
  });
1247
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
1248
- // must be >= the managed write checkpoint LSN
1249
- await batch.commit('1/0');
1250
- });
1250
+ await writer.markAllSnapshotDone('0/1');
1251
+ // must be >= the managed write checkpoint LSN
1252
+ await writer.commit('1/0');
1251
1253
  // At this point the LSN has advanced, so the write checkpoint should be
1252
1254
  // included in the next checkpoint message.
1253
1255
  const stream2 = sync.streamResponse(params);
@@ -1259,21 +1261,24 @@ bucket_definitions:
1259
1261
  })
1260
1262
  });
1261
1263
  }
1262
- catch (e_14) {
1263
- env_14.error = e_14;
1264
- env_14.hasError = true;
1264
+ catch (e_15) {
1265
+ env_15.error = e_15;
1266
+ env_15.hasError = true;
1265
1267
  }
1266
1268
  finally {
1267
- const result_14 = __disposeResources(env_14);
1268
- if (result_14)
1269
- await result_14;
1269
+ const result_15 = __disposeResources(env_15);
1270
+ if (result_15)
1271
+ await result_15;
1270
1272
  }
1271
1273
  });
1272
- test('encodes sync rules id in buckes for streams', async () => {
1273
- const env_15 = { stack: [], error: void 0, hasError: false };
1274
+ test('encodes sync rules id in buckets for streams', async () => {
1275
+ const env_16 = { stack: [], error: void 0, hasError: false };
1274
1276
  try {
1275
- const f = __addDisposableResource(env_15, await factory(), true);
1276
- const rules = `
1277
+ const f = __addDisposableResource(env_16, await factory(), true);
1278
+ // This test relies making an actual update to sync rules to test the different bucket names.
1279
+ // The actual naming scheme may change, as long as the two buckets have different names.
1280
+ const rules = [
1281
+ `
1277
1282
  streams:
1278
1283
  test:
1279
1284
  auto_subscribe: true
@@ -1281,15 +1286,29 @@ streams:
1281
1286
 
1282
1287
  config:
1283
1288
  edition: 2
1284
- `;
1289
+ `,
1290
+ `
1291
+ streams:
1292
+ test2:
1293
+ auto_subscribe: true
1294
+ query: SELECT * FROM test WHERE 1;
1295
+
1296
+ config:
1297
+ edition: 2
1298
+ `
1299
+ ];
1285
1300
  for (let i = 0; i < 2; i++) {
1286
- const syncRules = await updateSyncRules(f, {
1287
- content: rules
1288
- });
1289
- const bucketStorage = f.getInstance(syncRules);
1290
- await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
1291
- await batch.save({
1292
- sourceTable: TEST_TABLE,
1301
+ const env_17 = { stack: [], error: void 0, hasError: false };
1302
+ try {
1303
+ const syncRules = await updateSyncRules(f, {
1304
+ content: rules[i]
1305
+ });
1306
+ const bucketStorage = f.getInstance(syncRules);
1307
+ const writer = __addDisposableResource(env_17, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
1308
+ const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config, i + 1);
1309
+ await writer.markAllSnapshotDone('0/1');
1310
+ await writer.save({
1311
+ sourceTable: testTable,
1293
1312
  tag: storage.SaveOperationTag.INSERT,
1294
1313
  after: {
1295
1314
  id: 't1',
@@ -1297,33 +1316,42 @@ config:
1297
1316
  },
1298
1317
  afterReplicaId: 't1'
1299
1318
  });
1300
- await batch.commit('0/1');
1301
- });
1302
- const stream = sync.streamResponse({
1303
- syncContext,
1304
- bucketStorage: bucketStorage,
1305
- syncRules: bucketStorage.getParsedSyncRules(test_utils.PARSE_OPTIONS),
1306
- params: {
1307
- buckets: [],
1308
- include_checksum: true,
1309
- raw_data: true
1310
- },
1311
- tracker,
1312
- token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
1313
- isEncodingAsBson: false
1314
- });
1315
- const lines = await consumeCheckpointLines(stream);
1316
- expect(lines).toMatchSnapshot();
1319
+ await writer.commit('0/1');
1320
+ const stream = sync.streamResponse({
1321
+ syncContext,
1322
+ bucketStorage: bucketStorage,
1323
+ syncRules: bucketStorage.getParsedSyncRules(test_utils.PARSE_OPTIONS),
1324
+ params: {
1325
+ buckets: [],
1326
+ include_checksum: true,
1327
+ raw_data: true
1328
+ },
1329
+ tracker,
1330
+ token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
1331
+ isEncodingAsBson: false
1332
+ });
1333
+ const lines = await consumeCheckpointLines(stream);
1334
+ expect(lines).toMatchSnapshot();
1335
+ }
1336
+ catch (e_16) {
1337
+ env_17.error = e_16;
1338
+ env_17.hasError = true;
1339
+ }
1340
+ finally {
1341
+ const result_16 = __disposeResources(env_17);
1342
+ if (result_16)
1343
+ await result_16;
1344
+ }
1317
1345
  }
1318
1346
  }
1319
- catch (e_15) {
1320
- env_15.error = e_15;
1321
- env_15.hasError = true;
1347
+ catch (e_17) {
1348
+ env_16.error = e_17;
1349
+ env_16.hasError = true;
1322
1350
  }
1323
1351
  finally {
1324
- const result_15 = __disposeResources(env_15);
1325
- if (result_15)
1326
- await result_15;
1352
+ const result_17 = __disposeResources(env_16);
1353
+ if (result_17)
1354
+ await result_17;
1327
1355
  }
1328
1356
  });
1329
1357
  }