@powersync/service-core-tests 0.13.2 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/test-utils/general-utils.d.ts +0 -1
  3. package/dist/test-utils/general-utils.js +0 -24
  4. package/dist/test-utils/general-utils.js.map +1 -1
  5. package/dist/tests/register-compacting-tests.js +40 -51
  6. package/dist/tests/register-compacting-tests.js.map +1 -1
  7. package/dist/tests/register-data-storage-checkpoint-tests.js +11 -26
  8. package/dist/tests/register-data-storage-checkpoint-tests.js.map +1 -1
  9. package/dist/tests/register-data-storage-data-tests.js +80 -96
  10. package/dist/tests/register-data-storage-data-tests.js.map +1 -1
  11. package/dist/tests/register-data-storage-parameter-tests.js +84 -46
  12. package/dist/tests/register-data-storage-parameter-tests.js.map +1 -1
  13. package/dist/tests/register-parameter-compacting-tests.js +5 -9
  14. package/dist/tests/register-parameter-compacting-tests.js.map +1 -1
  15. package/dist/tests/register-sync-tests.d.ts +3 -1
  16. package/dist/tests/register-sync-tests.js +29 -22
  17. package/dist/tests/register-sync-tests.js.map +1 -1
  18. package/dist/tests/util.d.ts +5 -1
  19. package/dist/tests/util.js +14 -0
  20. package/dist/tests/util.js.map +1 -1
  21. package/package.json +3 -3
  22. package/src/test-utils/general-utils.ts +1 -25
  23. package/src/tests/register-compacting-tests.ts +56 -51
  24. package/src/tests/register-data-storage-checkpoint-tests.ts +21 -26
  25. package/src/tests/register-data-storage-data-tests.ts +135 -101
  26. package/src/tests/register-data-storage-parameter-tests.ts +102 -47
  27. package/src/tests/register-parameter-compacting-tests.ts +9 -9
  28. package/src/tests/register-sync-tests.ts +32 -22
  29. package/src/tests/util.ts +21 -0
  30. package/tsconfig.tsbuildinfo +1 -1
@@ -1,9 +1,9 @@
1
- import { JwtPayload, storage } from '@powersync/service-core';
1
+ import { JwtPayload, storage, updateSyncRulesFromYaml } from '@powersync/service-core';
2
2
  import { RequestParameters, ScopedParameterLookup, SqliteJsonRow } from '@powersync/service-sync-rules';
3
3
  import { expect, test } from 'vitest';
4
4
  import * as test_utils from '../test-utils/test-utils-index.js';
5
- import { TEST_TABLE } from './util.js';
6
- import { ParameterLookupScope } from '@powersync/service-sync-rules/src/HydrationState.js';
5
+ import { bucketRequest, TEST_TABLE } from './util.js';
6
+ import { ParameterLookupScope } from '@powersync/service-sync-rules';
7
7
 
8
8
  /**
9
9
  * @example
@@ -20,15 +20,15 @@ export function registerDataStorageParameterTests(generateStorageFactory: storag
20
20
 
21
21
  test('save and load parameters', async () => {
22
22
  await using factory = await generateStorageFactory();
23
- const syncRules = await factory.updateSyncRules({
24
- content: `
23
+ const syncRules = await factory.updateSyncRules(
24
+ updateSyncRulesFromYaml(`
25
25
  bucket_definitions:
26
26
  mybucket:
27
27
  parameters:
28
28
  - SELECT group_id FROM test WHERE id1 = token_parameters.user_id OR id2 = token_parameters.user_id
29
29
  data: []
30
- `
31
- });
30
+ `)
31
+ );
32
32
  const bucketStorage = factory.getInstance(syncRules);
33
33
 
34
34
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
@@ -70,15 +70,15 @@ bucket_definitions:
70
70
 
71
71
  test('it should use the latest version', async () => {
72
72
  await using factory = await generateStorageFactory();
73
- const syncRules = await factory.updateSyncRules({
74
- content: `
73
+ const syncRules = await factory.updateSyncRules(
74
+ updateSyncRulesFromYaml(`
75
75
  bucket_definitions:
76
76
  mybucket:
77
77
  parameters:
78
78
  - SELECT group_id FROM test WHERE id = token_parameters.user_id
79
79
  data: []
80
- `
81
- });
80
+ `)
81
+ );
82
82
  const bucketStorage = factory.getInstance(syncRules);
83
83
 
84
84
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
@@ -126,8 +126,8 @@ bucket_definitions:
126
126
 
127
127
  test('it should use the latest version after updates', async () => {
128
128
  await using factory = await generateStorageFactory();
129
- const syncRules = await factory.updateSyncRules({
130
- content: `
129
+ const syncRules = await factory.updateSyncRules(
130
+ updateSyncRulesFromYaml(`
131
131
  bucket_definitions:
132
132
  mybucket:
133
133
  parameters:
@@ -135,8 +135,8 @@ bucket_definitions:
135
135
  FROM todos
136
136
  WHERE list_id IN token_parameters.list_id
137
137
  data: []
138
- `
139
- });
138
+ `)
139
+ );
140
140
  const bucketStorage = factory.getInstance(syncRules);
141
141
 
142
142
  const table = test_utils.makeTestTable('todos', ['id', 'list_id']);
@@ -201,15 +201,15 @@ bucket_definitions:
201
201
 
202
202
  test('save and load parameters with different number types', async () => {
203
203
  await using factory = await generateStorageFactory();
204
- const syncRules = await factory.updateSyncRules({
205
- content: `
204
+ const syncRules = await factory.updateSyncRules(
205
+ updateSyncRulesFromYaml(`
206
206
  bucket_definitions:
207
207
  mybucket:
208
208
  parameters:
209
209
  - SELECT group_id FROM test WHERE n1 = token_parameters.n1 and f2 = token_parameters.f2 and f3 = token_parameters.f3
210
210
  data: []
211
- `
212
- });
211
+ `)
212
+ );
213
213
  const bucketStorage = factory.getInstance(syncRules);
214
214
 
215
215
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
@@ -251,15 +251,15 @@ bucket_definitions:
251
251
  // test this to ensure correct deserialization.
252
252
 
253
253
  await using factory = await generateStorageFactory();
254
- const syncRules = await factory.updateSyncRules({
255
- content: `
254
+ const syncRules = await factory.updateSyncRules(
255
+ updateSyncRulesFromYaml(`
256
256
  bucket_definitions:
257
257
  mybucket:
258
258
  parameters:
259
259
  - SELECT group_id FROM test WHERE n1 = token_parameters.n1
260
260
  data: []
261
- `
262
- });
261
+ `)
262
+ );
263
263
  const bucketStorage = factory.getInstance(syncRules);
264
264
 
265
265
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
@@ -304,16 +304,16 @@ bucket_definitions:
304
304
  const WORKSPACE_TABLE = test_utils.makeTestTable('workspace', ['id']);
305
305
 
306
306
  await using factory = await generateStorageFactory();
307
- const syncRules = await factory.updateSyncRules({
308
- content: `
307
+ const syncRules = await factory.updateSyncRules(
308
+ updateSyncRulesFromYaml(`
309
309
  bucket_definitions:
310
310
  by_workspace:
311
311
  parameters:
312
312
  - SELECT id as workspace_id FROM workspace WHERE
313
313
  workspace."userId" = token_parameters.user_id
314
314
  data: []
315
- `
316
- });
315
+ `)
316
+ );
317
317
  const sync_rules = syncRules.parsed(test_utils.PARSE_OPTIONS).hydratedSyncRules();
318
318
  const bucketStorage = factory.getInstance(syncRules);
319
319
 
@@ -345,7 +345,12 @@ bucket_definitions:
345
345
  }
346
346
  });
347
347
  expect(buckets).toEqual([
348
- { bucket: 'by_workspace["workspace1"]', priority: 3, definition: 'by_workspace', inclusion_reasons: ['default'] }
348
+ {
349
+ bucket: bucketRequest(syncRules, 'by_workspace["workspace1"]'),
350
+ priority: 3,
351
+ definition: 'by_workspace',
352
+ inclusion_reasons: ['default']
353
+ }
349
354
  ]);
350
355
  });
351
356
 
@@ -353,16 +358,16 @@ bucket_definitions:
353
358
  const WORKSPACE_TABLE = test_utils.makeTestTable('workspace');
354
359
 
355
360
  await using factory = await generateStorageFactory();
356
- const syncRules = await factory.updateSyncRules({
357
- content: `
361
+ const syncRules = await factory.updateSyncRules(
362
+ updateSyncRulesFromYaml(`
358
363
  bucket_definitions:
359
364
  by_public_workspace:
360
365
  parameters:
361
366
  - SELECT id as workspace_id FROM workspace WHERE
362
367
  workspace.visibility = 'public'
363
368
  data: []
364
- `
365
- });
369
+ `)
370
+ );
366
371
  const sync_rules = syncRules.parsed(test_utils.PARSE_OPTIONS).hydratedSyncRules();
367
372
  const bucketStorage = factory.getInstance(syncRules);
368
373
 
@@ -421,13 +426,13 @@ bucket_definitions:
421
426
  buckets.sort((a, b) => a.bucket.localeCompare(b.bucket));
422
427
  expect(buckets).toEqual([
423
428
  {
424
- bucket: 'by_public_workspace["workspace1"]',
429
+ bucket: bucketRequest(syncRules, 'by_public_workspace["workspace1"]'),
425
430
  priority: 3,
426
431
  definition: 'by_public_workspace',
427
432
  inclusion_reasons: ['default']
428
433
  },
429
434
  {
430
- bucket: 'by_public_workspace["workspace3"]',
435
+ bucket: bucketRequest(syncRules, 'by_public_workspace["workspace3"]'),
431
436
  priority: 3,
432
437
  definition: 'by_public_workspace',
433
438
  inclusion_reasons: ['default']
@@ -439,8 +444,8 @@ bucket_definitions:
439
444
  const WORKSPACE_TABLE = test_utils.makeTestTable('workspace');
440
445
 
441
446
  await using factory = await generateStorageFactory();
442
- const syncRules = await factory.updateSyncRules({
443
- content: `
447
+ const syncRules = await factory.updateSyncRules(
448
+ updateSyncRulesFromYaml(`
444
449
  bucket_definitions:
445
450
  by_workspace:
446
451
  parameters:
@@ -449,8 +454,8 @@ bucket_definitions:
449
454
  - SELECT id as workspace_id FROM workspace WHERE
450
455
  workspace.user_id = token_parameters.user_id
451
456
  data: []
452
- `
453
- });
457
+ `)
458
+ );
454
459
  const sync_rules = syncRules.parsed(test_utils.PARSE_OPTIONS).hydratedSyncRules();
455
460
  const bucketStorage = factory.getInstance(syncRules);
456
461
 
@@ -528,20 +533,23 @@ bucket_definitions:
528
533
  expect(parameter_sets).toEqual([{ workspace_id: 'workspace1' }, { workspace_id: 'workspace3' }]);
529
534
 
530
535
  buckets.sort();
531
- expect(buckets).toEqual(['by_workspace["workspace1"]', 'by_workspace["workspace3"]']);
536
+ expect(buckets).toEqual([
537
+ bucketRequest(syncRules, 'by_workspace["workspace1"]'),
538
+ bucketRequest(syncRules, 'by_workspace["workspace3"]')
539
+ ]);
532
540
  });
533
541
 
534
542
  test('truncate parameters', async () => {
535
543
  await using factory = await generateStorageFactory();
536
- const syncRules = await factory.updateSyncRules({
537
- content: `
544
+ const syncRules = await factory.updateSyncRules(
545
+ updateSyncRulesFromYaml(`
538
546
  bucket_definitions:
539
547
  mybucket:
540
548
  parameters:
541
549
  - SELECT group_id FROM test WHERE id1 = token_parameters.user_id OR id2 = token_parameters.user_id
542
550
  data: []
543
- `
544
- });
551
+ `)
552
+ );
545
553
  const bucketStorage = factory.getInstance(syncRules);
546
554
 
547
555
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
@@ -568,16 +576,16 @@ bucket_definitions:
568
576
 
569
577
  test('invalidate cached parsed sync rules', async () => {
570
578
  await using bucketStorageFactory = await generateStorageFactory();
571
- const syncRules = await bucketStorageFactory.updateSyncRules({
572
- content: `
579
+ const syncRules = await bucketStorageFactory.updateSyncRules(
580
+ updateSyncRulesFromYaml(`
573
581
  bucket_definitions:
574
582
  by_workspace:
575
583
  parameters:
576
584
  - SELECT id as workspace_id FROM workspace WHERE
577
585
  workspace."userId" = token_parameters.user_id
578
586
  data: []
579
- `
580
- });
587
+ `)
588
+ );
581
589
  const syncBucketStorage = bucketStorageFactory.getInstance(syncRules);
582
590
 
583
591
  const parsedSchema1 = syncBucketStorage.getParsedSyncRules({
@@ -600,4 +608,51 @@ bucket_definitions:
600
608
  expect(parsedSchema3).not.equals(parsedSchema2);
601
609
  expect(parsedSchema3.getSourceTables()[0].schema).equals('databasename');
602
610
  });
611
+
612
+ test('sync streams smoke test', async () => {
613
+ await using factory = await generateStorageFactory();
614
+ const syncRules = await factory.updateSyncRules(
615
+ updateSyncRulesFromYaml(`
616
+ config:
617
+ edition: 3
618
+
619
+ streams:
620
+ stream:
621
+ query: |
622
+ SELECT data.* FROM test AS data, test AS param
623
+ WHERE data.foo = param.bar AND param.baz = auth.user_id()
624
+ `)
625
+ );
626
+ const bucketStorage = factory.getInstance(syncRules);
627
+
628
+ await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
629
+ await batch.save({
630
+ sourceTable: TEST_TABLE,
631
+ tag: storage.SaveOperationTag.INSERT,
632
+ after: {
633
+ baz: 'baz',
634
+ bar: 'bar'
635
+ },
636
+ afterReplicaId: test_utils.rid('t1')
637
+ });
638
+
639
+ await batch.commit('1/1');
640
+ });
641
+
642
+ const checkpoint = await bucketStorage.getCheckpoint();
643
+ const parameters = await checkpoint.getParameterSets([
644
+ ScopedParameterLookup.direct(
645
+ {
646
+ lookupName: 'lookup',
647
+ queryId: '0'
648
+ },
649
+ ['baz']
650
+ )
651
+ ]);
652
+ expect(parameters).toEqual([
653
+ {
654
+ '0': 'bar'
655
+ }
656
+ ]);
657
+ });
603
658
  }
@@ -1,4 +1,4 @@
1
- import { storage } from '@powersync/service-core';
1
+ import { storage, updateSyncRulesFromYaml } from '@powersync/service-core';
2
2
  import { ScopedParameterLookup } from '@powersync/service-sync-rules';
3
3
  import { expect, test } from 'vitest';
4
4
  import * as test_utils from '../test-utils/test-utils-index.js';
@@ -8,14 +8,14 @@ const TEST_TABLE = test_utils.makeTestTable('test', ['id']);
8
8
  export function registerParameterCompactTests(generateStorageFactory: storage.TestStorageFactory) {
9
9
  test('compacting parameters', async () => {
10
10
  await using factory = await generateStorageFactory();
11
- const syncRules = await factory.updateSyncRules({
12
- content: `
11
+ const syncRules = await factory.updateSyncRules(
12
+ updateSyncRulesFromYaml(`
13
13
  bucket_definitions:
14
14
  test:
15
15
  parameters: select id from test where id = request.user_id()
16
16
  data: []
17
- `
18
- });
17
+ `)
18
+ );
19
19
  const bucketStorage = factory.getInstance(syncRules);
20
20
 
21
21
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
@@ -91,14 +91,14 @@ bucket_definitions:
91
91
  for (let cacheLimit of [1, 10]) {
92
92
  test(`compacting deleted parameters with cache size ${cacheLimit}`, async () => {
93
93
  await using factory = await generateStorageFactory();
94
- const syncRules = await factory.updateSyncRules({
95
- content: `
94
+ const syncRules = await factory.updateSyncRules(
95
+ updateSyncRulesFromYaml(`
96
96
  bucket_definitions:
97
97
  test:
98
98
  parameters: select id from test where uid = request.user_id()
99
99
  data: []
100
- `
101
- });
100
+ `)
101
+ );
102
102
  const bucketStorage = factory.getInstance(syncRules);
103
103
 
104
104
  await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
@@ -5,16 +5,17 @@ import {
5
5
  StreamingSyncCheckpoint,
6
6
  StreamingSyncCheckpointDiff,
7
7
  sync,
8
+ updateSyncRulesFromYaml,
8
9
  utils
9
10
  } from '@powersync/service-core';
10
11
  import { JSONBig } from '@powersync/service-jsonbig';
11
- import { BucketSourceType, RequestParameters } from '@powersync/service-sync-rules';
12
12
  import path from 'path';
13
13
  import * as timers from 'timers/promises';
14
14
  import { fileURLToPath } from 'url';
15
15
  import { expect, test } from 'vitest';
16
16
  import * as test_utils from '../test-utils/test-utils-index.js';
17
17
  import { METRICS_HELPER } from '../test-utils/test-utils-index.js';
18
+ import { bucketRequest } from './util.js';
18
19
 
19
20
  const __filename = fileURLToPath(import.meta.url);
20
21
  const __dirname = path.dirname(__filename);
@@ -38,7 +39,7 @@ export const SYNC_SNAPSHOT_PATH = path.resolve(__dirname, '../__snapshots/sync.t
38
39
  * });
39
40
  * ```
40
41
  */
41
- export function registerSyncTests(factory: storage.TestStorageFactory) {
42
+ export function registerSyncTests(factory: storage.TestStorageFactory, options: { storageVersion?: number } = {}) {
42
43
  createCoreAPIMetrics(METRICS_HELPER.metricsEngine);
43
44
  const tracker = new sync.RequestTracker(METRICS_HELPER.metricsEngine);
44
45
  const syncContext = new sync.SyncContext({
@@ -47,10 +48,19 @@ export function registerSyncTests(factory: storage.TestStorageFactory) {
47
48
  maxDataFetchConcurrency: 2
48
49
  });
49
50
 
51
+ const updateSyncRules = (bucketStorageFactory: storage.BucketStorageFactory, updateOptions: { content: string }) => {
52
+ return bucketStorageFactory.updateSyncRules(
53
+ updateSyncRulesFromYaml(updateOptions.content, {
54
+ validate: true,
55
+ storageVersion: options.storageVersion
56
+ })
57
+ );
58
+ };
59
+
50
60
  test('sync global data', async () => {
51
61
  await using f = await factory();
52
62
 
53
- const syncRules = await f.updateSyncRules({
63
+ const syncRules = await updateSyncRules(f, {
54
64
  content: BASIC_SYNC_RULES
55
65
  });
56
66
 
@@ -101,7 +111,7 @@ export function registerSyncTests(factory: storage.TestStorageFactory) {
101
111
  test('sync buckets in order', async () => {
102
112
  await using f = await factory();
103
113
 
104
- const syncRules = await f.updateSyncRules({
114
+ const syncRules = await updateSyncRules(f, {
105
115
  content: `
106
116
  bucket_definitions:
107
117
  b0:
@@ -162,7 +172,7 @@ bucket_definitions:
162
172
  test('sync interrupts low-priority buckets on new checkpoints', async () => {
163
173
  await using f = await factory();
164
174
 
165
- const syncRules = await f.updateSyncRules({
175
+ const syncRules = await updateSyncRules(f, {
166
176
  content: `
167
177
  bucket_definitions:
168
178
  b0:
@@ -271,7 +281,7 @@ bucket_definitions:
271
281
  test('sync interruptions with unrelated data', async () => {
272
282
  await using f = await factory();
273
283
 
274
- const syncRules = await f.updateSyncRules({
284
+ const syncRules = await updateSyncRules(f, {
275
285
  content: `
276
286
  bucket_definitions:
277
287
  b0:
@@ -409,7 +419,7 @@ bucket_definitions:
409
419
  // then interrupt checkpoint with new data for all buckets
410
420
  // -> data for all buckets should be sent in the new checkpoint
411
421
 
412
- const syncRules = await f.updateSyncRules({
422
+ const syncRules = await updateSyncRules(f, {
413
423
  content: `
414
424
  bucket_definitions:
415
425
  b0a:
@@ -553,7 +563,7 @@ bucket_definitions:
553
563
  test('sends checkpoint complete line for empty checkpoint', async () => {
554
564
  await using f = await factory();
555
565
 
556
- const syncRules = await f.updateSyncRules({
566
+ const syncRules = await updateSyncRules(f, {
557
567
  content: BASIC_SYNC_RULES
558
568
  });
559
569
  const bucketStorage = f.getInstance(syncRules);
@@ -616,7 +626,7 @@ bucket_definitions:
616
626
  test('sync legacy non-raw data', async () => {
617
627
  const f = await factory();
618
628
 
619
- const syncRules = await f.updateSyncRules({
629
+ const syncRules = await updateSyncRules(f, {
620
630
  content: BASIC_SYNC_RULES
621
631
  });
622
632
 
@@ -660,7 +670,7 @@ bucket_definitions:
660
670
  test('expired token', async () => {
661
671
  await using f = await factory();
662
672
 
663
- const syncRules = await f.updateSyncRules({
673
+ const syncRules = await updateSyncRules(f, {
664
674
  content: BASIC_SYNC_RULES
665
675
  });
666
676
 
@@ -687,7 +697,7 @@ bucket_definitions:
687
697
  test('sync updates to global data', async (context) => {
688
698
  await using f = await factory();
689
699
 
690
- const syncRules = await f.updateSyncRules({
700
+ const syncRules = await updateSyncRules(f, {
691
701
  content: BASIC_SYNC_RULES
692
702
  });
693
703
 
@@ -753,7 +763,7 @@ bucket_definitions:
753
763
  test('sync updates to parameter query only', async (context) => {
754
764
  await using f = await factory();
755
765
 
756
- const syncRules = await f.updateSyncRules({
766
+ const syncRules = await updateSyncRules(f, {
757
767
  content: `bucket_definitions:
758
768
  by_user:
759
769
  parameters: select users.id as user_id from users where users.id = request.user_id()
@@ -812,14 +822,14 @@ bucket_definitions:
812
822
  const checkpoint2 = await getCheckpointLines(iter);
813
823
  expect(
814
824
  (checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
815
- ).toEqual(['by_user["user1"]']);
825
+ ).toEqual([bucketRequest(syncRules, 'by_user["user1"]')]);
816
826
  expect(checkpoint2).toMatchSnapshot();
817
827
  });
818
828
 
819
829
  test('sync updates to data query only', async (context) => {
820
830
  await using f = await factory();
821
831
 
822
- const syncRules = await f.updateSyncRules({
832
+ const syncRules = await updateSyncRules(f, {
823
833
  content: `bucket_definitions:
824
834
  by_user:
825
835
  parameters: select users.id as user_id from users where users.id = request.user_id()
@@ -867,7 +877,7 @@ bucket_definitions:
867
877
 
868
878
  const checkpoint1 = await getCheckpointLines(iter);
869
879
  expect((checkpoint1[0] as StreamingSyncCheckpoint).checkpoint?.buckets?.map((b) => b.bucket)).toEqual([
870
- 'by_user["user1"]'
880
+ bucketRequest(syncRules, 'by_user["user1"]')
871
881
  ]);
872
882
  expect(checkpoint1).toMatchSnapshot();
873
883
 
@@ -889,14 +899,14 @@ bucket_definitions:
889
899
  const checkpoint2 = await getCheckpointLines(iter);
890
900
  expect(
891
901
  (checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
892
- ).toEqual(['by_user["user1"]']);
902
+ ).toEqual([bucketRequest(syncRules, 'by_user["user1"]')]);
893
903
  expect(checkpoint2).toMatchSnapshot();
894
904
  });
895
905
 
896
906
  test('sync updates to parameter query + data', async (context) => {
897
907
  await using f = await factory();
898
908
 
899
- const syncRules = await f.updateSyncRules({
909
+ const syncRules = await updateSyncRules(f, {
900
910
  content: `bucket_definitions:
901
911
  by_user:
902
912
  parameters: select users.id as user_id from users where users.id = request.user_id()
@@ -963,14 +973,14 @@ bucket_definitions:
963
973
  const checkpoint2 = await getCheckpointLines(iter);
964
974
  expect(
965
975
  (checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
966
- ).toEqual(['by_user["user1"]']);
976
+ ).toEqual([bucketRequest(syncRules, 'by_user["user1"]')]);
967
977
  expect(checkpoint2).toMatchSnapshot();
968
978
  });
969
979
 
970
980
  test('expiring token', async (context) => {
971
981
  await using f = await factory();
972
982
 
973
- const syncRules = await f.updateSyncRules({
983
+ const syncRules = await updateSyncRules(f, {
974
984
  content: BASIC_SYNC_RULES
975
985
  });
976
986
 
@@ -1015,7 +1025,7 @@ bucket_definitions:
1015
1025
 
1016
1026
  await using f = await factory();
1017
1027
 
1018
- const syncRules = await f.updateSyncRules({
1028
+ const syncRules = await updateSyncRules(f, {
1019
1029
  content: BASIC_SYNC_RULES
1020
1030
  });
1021
1031
 
@@ -1158,7 +1168,7 @@ bucket_definitions:
1158
1168
  test('write checkpoint', async () => {
1159
1169
  await using f = await factory();
1160
1170
 
1161
- const syncRules = await f.updateSyncRules({
1171
+ const syncRules = await updateSyncRules(f, {
1162
1172
  content: BASIC_SYNC_RULES
1163
1173
  });
1164
1174
 
@@ -1229,7 +1239,7 @@ config:
1229
1239
  `;
1230
1240
 
1231
1241
  for (let i = 0; i < 2; i++) {
1232
- const syncRules = await f.updateSyncRules({
1242
+ const syncRules = await updateSyncRules(f, {
1233
1243
  content: rules
1234
1244
  });
1235
1245
  const bucketStorage = f.getInstance(syncRules);
package/src/tests/util.ts CHANGED
@@ -1,3 +1,24 @@
1
+ import { storage } from '@powersync/service-core';
1
2
  import { test_utils } from '../index.js';
2
3
 
3
4
  export const TEST_TABLE = test_utils.makeTestTable('test', ['id']);
5
+
6
+ export function bucketRequest(syncRules: storage.PersistedSyncRulesContent, bucketName: string): string {
7
+ if (/^\d+#/.test(bucketName)) {
8
+ return bucketName;
9
+ }
10
+
11
+ const versionedBuckets = storage.STORAGE_VERSION_CONFIG[syncRules.storageVersion]?.versionedBuckets ?? false;
12
+ return versionedBuckets ? `${syncRules.id}#${bucketName}` : bucketName;
13
+ }
14
+
15
+ export function bucketRequests(syncRules: storage.PersistedSyncRulesContent, bucketNames: string[]): string[] {
16
+ return bucketNames.map((bucketName) => bucketRequest(syncRules, bucketName));
17
+ }
18
+
19
+ export function bucketRequestMap(
20
+ syncRules: storage.PersistedSyncRulesContent,
21
+ buckets: Iterable<readonly [string, bigint]>
22
+ ): Map<string, bigint> {
23
+ return new Map(Array.from(buckets, ([bucketName, opId]) => [bucketRequest(syncRules, bucketName), opId]));
24
+ }