@powersync/service-core-tests 0.0.0-dev-20260203155513 → 0.0.0-dev-20260223082111

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 +41 -5
  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 +52 -57
  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 +37 -49
  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 +47 -39
  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 +68 -57
  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 +58 -50
  27. package/src/tests/register-parameter-compacting-tests.ts +9 -9
  28. package/src/tests/register-sync-tests.ts +51 -39
  29. package/src/tests/util.ts +21 -0
  30. package/tsconfig.tsbuildinfo +1 -1
@@ -1,9 +1,9 @@
1
- import { 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
 
@@ -331,7 +331,7 @@ bucket_definitions:
331
331
  });
332
332
  const checkpoint = await bucketStorage.getCheckpoint();
333
333
 
334
- const parameters = new RequestParameters({ sub: 'u1' }, {});
334
+ const parameters = new RequestParameters(new JwtPayload({ sub: 'u1' }), {});
335
335
 
336
336
  const querier = sync_rules.getBucketParameterQuerier(test_utils.querierOptions(parameters)).querier;
337
337
 
@@ -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
 
@@ -402,7 +407,7 @@ bucket_definitions:
402
407
 
403
408
  const checkpoint = await bucketStorage.getCheckpoint();
404
409
 
405
- const parameters = new RequestParameters({ sub: 'unknown' }, {});
410
+ const parameters = new RequestParameters(new JwtPayload({ sub: 'unknown' }), {});
406
411
 
407
412
  const querier = sync_rules.getBucketParameterQuerier(test_utils.querierOptions(parameters)).querier;
408
413
 
@@ -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
 
@@ -502,7 +507,7 @@ bucket_definitions:
502
507
 
503
508
  const checkpoint = await bucketStorage.getCheckpoint();
504
509
 
505
- const parameters = new RequestParameters({ sub: 'u1' }, {});
510
+ const parameters = new RequestParameters(new JwtPayload({ sub: 'u1' }), {});
506
511
 
507
512
  // Test intermediate values - could be moved to sync_rules.test.ts
508
513
  const querier = sync_rules.getBucketParameterQuerier(test_utils.querierOptions(parameters)).querier;
@@ -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({
@@ -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) => {
@@ -1,19 +1,21 @@
1
1
  import {
2
2
  createCoreAPIMetrics,
3
+ JwtPayload,
3
4
  storage,
4
5
  StreamingSyncCheckpoint,
5
6
  StreamingSyncCheckpointDiff,
6
7
  sync,
8
+ updateSyncRulesFromYaml,
7
9
  utils
8
10
  } from '@powersync/service-core';
9
11
  import { JSONBig } from '@powersync/service-jsonbig';
10
- import { BucketSourceType, RequestParameters } from '@powersync/service-sync-rules';
11
12
  import path from 'path';
12
13
  import * as timers from 'timers/promises';
13
14
  import { fileURLToPath } from 'url';
14
15
  import { expect, test } from 'vitest';
15
16
  import * as test_utils from '../test-utils/test-utils-index.js';
16
17
  import { METRICS_HELPER } from '../test-utils/test-utils-index.js';
18
+ import { bucketRequest } from './util.js';
17
19
 
18
20
  const __filename = fileURLToPath(import.meta.url);
19
21
  const __dirname = path.dirname(__filename);
@@ -37,7 +39,7 @@ export const SYNC_SNAPSHOT_PATH = path.resolve(__dirname, '../__snapshots/sync.t
37
39
  * });
38
40
  * ```
39
41
  */
40
- export function registerSyncTests(factory: storage.TestStorageFactory) {
42
+ export function registerSyncTests(factory: storage.TestStorageFactory, options: { storageVersion?: number } = {}) {
41
43
  createCoreAPIMetrics(METRICS_HELPER.metricsEngine);
42
44
  const tracker = new sync.RequestTracker(METRICS_HELPER.metricsEngine);
43
45
  const syncContext = new sync.SyncContext({
@@ -46,10 +48,19 @@ export function registerSyncTests(factory: storage.TestStorageFactory) {
46
48
  maxDataFetchConcurrency: 2
47
49
  });
48
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
+
49
60
  test('sync global data', async () => {
50
61
  await using f = await factory();
51
62
 
52
- const syncRules = await f.updateSyncRules({
63
+ const syncRules = await updateSyncRules(f, {
53
64
  content: BASIC_SYNC_RULES
54
65
  });
55
66
 
@@ -89,7 +100,7 @@ export function registerSyncTests(factory: storage.TestStorageFactory) {
89
100
  raw_data: true
90
101
  },
91
102
  tracker,
92
- token: { sub: '', exp: Date.now() / 1000 + 10 } as any,
103
+ token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
93
104
  isEncodingAsBson: false
94
105
  });
95
106
 
@@ -100,7 +111,7 @@ export function registerSyncTests(factory: storage.TestStorageFactory) {
100
111
  test('sync buckets in order', async () => {
101
112
  await using f = await factory();
102
113
 
103
- const syncRules = await f.updateSyncRules({
114
+ const syncRules = await updateSyncRules(f, {
104
115
  content: `
105
116
  bucket_definitions:
106
117
  b0:
@@ -150,7 +161,7 @@ bucket_definitions:
150
161
  raw_data: true
151
162
  },
152
163
  tracker,
153
- token: { sub: '', exp: Date.now() / 1000 + 10 } as any,
164
+ token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
154
165
  isEncodingAsBson: false
155
166
  });
156
167
 
@@ -161,7 +172,7 @@ bucket_definitions:
161
172
  test('sync interrupts low-priority buckets on new checkpoints', async () => {
162
173
  await using f = await factory();
163
174
 
164
- const syncRules = await f.updateSyncRules({
175
+ const syncRules = await updateSyncRules(f, {
165
176
  content: `
166
177
  bucket_definitions:
167
178
  b0:
@@ -213,7 +224,7 @@ bucket_definitions:
213
224
  raw_data: true
214
225
  },
215
226
  tracker,
216
- token: { sub: '', exp: Date.now() / 1000 + 10 } as any,
227
+ token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
217
228
  isEncodingAsBson: false
218
229
  });
219
230
 
@@ -270,7 +281,7 @@ bucket_definitions:
270
281
  test('sync interruptions with unrelated data', async () => {
271
282
  await using f = await factory();
272
283
 
273
- const syncRules = await f.updateSyncRules({
284
+ const syncRules = await updateSyncRules(f, {
274
285
  content: `
275
286
  bucket_definitions:
276
287
  b0:
@@ -323,7 +334,7 @@ bucket_definitions:
323
334
  raw_data: true
324
335
  },
325
336
  tracker,
326
- token: { sub: 'user_one', exp: Date.now() / 1000 + 100000 } as any,
337
+ token: new JwtPayload({ sub: 'user_one', exp: Date.now() / 1000 + 100000 }),
327
338
  isEncodingAsBson: false
328
339
  });
329
340
 
@@ -408,7 +419,7 @@ bucket_definitions:
408
419
  // then interrupt checkpoint with new data for all buckets
409
420
  // -> data for all buckets should be sent in the new checkpoint
410
421
 
411
- const syncRules = await f.updateSyncRules({
422
+ const syncRules = await updateSyncRules(f, {
412
423
  content: `
413
424
  bucket_definitions:
414
425
  b0a:
@@ -464,7 +475,7 @@ bucket_definitions:
464
475
  raw_data: true
465
476
  },
466
477
  tracker,
467
- token: { sub: '', exp: Date.now() / 1000 + 10 } as any,
478
+ token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
468
479
  isEncodingAsBson: false
469
480
  });
470
481
 
@@ -552,7 +563,7 @@ bucket_definitions:
552
563
  test('sends checkpoint complete line for empty checkpoint', async () => {
553
564
  await using f = await factory();
554
565
 
555
- const syncRules = await f.updateSyncRules({
566
+ const syncRules = await updateSyncRules(f, {
556
567
  content: BASIC_SYNC_RULES
557
568
  });
558
569
  const bucketStorage = f.getInstance(syncRules);
@@ -580,7 +591,7 @@ bucket_definitions:
580
591
  raw_data: true
581
592
  },
582
593
  tracker,
583
- token: { sub: '', exp: Date.now() / 1000 + 100000 } as any,
594
+ token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 100000 }),
584
595
  isEncodingAsBson: false
585
596
  });
586
597
 
@@ -615,7 +626,7 @@ bucket_definitions:
615
626
  test('sync legacy non-raw data', async () => {
616
627
  const f = await factory();
617
628
 
618
- const syncRules = await f.updateSyncRules({
629
+ const syncRules = await updateSyncRules(f, {
619
630
  content: BASIC_SYNC_RULES
620
631
  });
621
632
 
@@ -646,7 +657,7 @@ bucket_definitions:
646
657
  raw_data: false
647
658
  },
648
659
  tracker,
649
- token: { sub: '', exp: Date.now() / 1000 + 10 } as any,
660
+ token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
650
661
  isEncodingAsBson: false
651
662
  });
652
663
 
@@ -659,7 +670,7 @@ bucket_definitions:
659
670
  test('expired token', async () => {
660
671
  await using f = await factory();
661
672
 
662
- const syncRules = await f.updateSyncRules({
673
+ const syncRules = await updateSyncRules(f, {
663
674
  content: BASIC_SYNC_RULES
664
675
  });
665
676
 
@@ -675,7 +686,7 @@ bucket_definitions:
675
686
  raw_data: true
676
687
  },
677
688
  tracker,
678
- token: { sub: '', exp: 0 } as any,
689
+ token: new JwtPayload({ sub: '', exp: 0 }),
679
690
  isEncodingAsBson: false
680
691
  });
681
692
 
@@ -686,7 +697,7 @@ bucket_definitions:
686
697
  test('sync updates to global data', async (context) => {
687
698
  await using f = await factory();
688
699
 
689
- const syncRules = await f.updateSyncRules({
700
+ const syncRules = await updateSyncRules(f, {
690
701
  content: BASIC_SYNC_RULES
691
702
  });
692
703
 
@@ -706,7 +717,7 @@ bucket_definitions:
706
717
  raw_data: true
707
718
  },
708
719
  tracker,
709
- token: { sub: '', exp: Date.now() / 1000 + 10 } as any,
720
+ token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
710
721
  isEncodingAsBson: false
711
722
  });
712
723
  const iter = stream[Symbol.asyncIterator]();
@@ -752,7 +763,7 @@ bucket_definitions:
752
763
  test('sync updates to parameter query only', async (context) => {
753
764
  await using f = await factory();
754
765
 
755
- const syncRules = await f.updateSyncRules({
766
+ const syncRules = await updateSyncRules(f, {
756
767
  content: `bucket_definitions:
757
768
  by_user:
758
769
  parameters: select users.id as user_id from users where users.id = request.user_id()
@@ -780,7 +791,7 @@ bucket_definitions:
780
791
  raw_data: true
781
792
  },
782
793
  tracker,
783
- token: { sub: 'user1', exp: Date.now() / 1000 + 100 } as any,
794
+ token: new JwtPayload({ sub: 'user1', exp: Date.now() / 1000 + 100 }),
784
795
  isEncodingAsBson: false
785
796
  });
786
797
  const iter = stream[Symbol.asyncIterator]();
@@ -811,14 +822,14 @@ bucket_definitions:
811
822
  const checkpoint2 = await getCheckpointLines(iter);
812
823
  expect(
813
824
  (checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
814
- ).toEqual(['by_user["user1"]']);
825
+ ).toEqual([bucketRequest(syncRules, 'by_user["user1"]')]);
815
826
  expect(checkpoint2).toMatchSnapshot();
816
827
  });
817
828
 
818
829
  test('sync updates to data query only', async (context) => {
819
830
  await using f = await factory();
820
831
 
821
- const syncRules = await f.updateSyncRules({
832
+ const syncRules = await updateSyncRules(f, {
822
833
  content: `bucket_definitions:
823
834
  by_user:
824
835
  parameters: select users.id as user_id from users where users.id = request.user_id()
@@ -856,7 +867,7 @@ bucket_definitions:
856
867
  raw_data: true
857
868
  },
858
869
  tracker,
859
- token: { sub: 'user1', exp: Date.now() / 1000 + 100 } as any,
870
+ token: new JwtPayload({ sub: 'user1', exp: Date.now() / 1000 + 100 }),
860
871
  isEncodingAsBson: false
861
872
  });
862
873
  const iter = stream[Symbol.asyncIterator]();
@@ -866,7 +877,7 @@ bucket_definitions:
866
877
 
867
878
  const checkpoint1 = await getCheckpointLines(iter);
868
879
  expect((checkpoint1[0] as StreamingSyncCheckpoint).checkpoint?.buckets?.map((b) => b.bucket)).toEqual([
869
- 'by_user["user1"]'
880
+ bucketRequest(syncRules, 'by_user["user1"]')
870
881
  ]);
871
882
  expect(checkpoint1).toMatchSnapshot();
872
883
 
@@ -888,14 +899,14 @@ bucket_definitions:
888
899
  const checkpoint2 = await getCheckpointLines(iter);
889
900
  expect(
890
901
  (checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
891
- ).toEqual(['by_user["user1"]']);
902
+ ).toEqual([bucketRequest(syncRules, 'by_user["user1"]')]);
892
903
  expect(checkpoint2).toMatchSnapshot();
893
904
  });
894
905
 
895
906
  test('sync updates to parameter query + data', async (context) => {
896
907
  await using f = await factory();
897
908
 
898
- const syncRules = await f.updateSyncRules({
909
+ const syncRules = await updateSyncRules(f, {
899
910
  content: `bucket_definitions:
900
911
  by_user:
901
912
  parameters: select users.id as user_id from users where users.id = request.user_id()
@@ -923,7 +934,7 @@ bucket_definitions:
923
934
  raw_data: true
924
935
  },
925
936
  tracker,
926
- token: { sub: 'user1', exp: Date.now() / 1000 + 100 } as any,
937
+ token: new JwtPayload({ sub: 'user1', exp: Date.now() / 1000 + 100 }),
927
938
  isEncodingAsBson: false
928
939
  });
929
940
  const iter = stream[Symbol.asyncIterator]();
@@ -962,14 +973,14 @@ bucket_definitions:
962
973
  const checkpoint2 = await getCheckpointLines(iter);
963
974
  expect(
964
975
  (checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
965
- ).toEqual(['by_user["user1"]']);
976
+ ).toEqual([bucketRequest(syncRules, 'by_user["user1"]')]);
966
977
  expect(checkpoint2).toMatchSnapshot();
967
978
  });
968
979
 
969
980
  test('expiring token', async (context) => {
970
981
  await using f = await factory();
971
982
 
972
- const syncRules = await f.updateSyncRules({
983
+ const syncRules = await updateSyncRules(f, {
973
984
  content: BASIC_SYNC_RULES
974
985
  });
975
986
 
@@ -991,7 +1002,7 @@ bucket_definitions:
991
1002
  raw_data: true
992
1003
  },
993
1004
  tracker,
994
- token: { sub: '', exp: exp } as any,
1005
+ token: new JwtPayload({ sub: '', exp: exp }),
995
1006
  isEncodingAsBson: false
996
1007
  });
997
1008
  const iter = stream[Symbol.asyncIterator]();
@@ -1014,7 +1025,7 @@ bucket_definitions:
1014
1025
 
1015
1026
  await using f = await factory();
1016
1027
 
1017
- const syncRules = await f.updateSyncRules({
1028
+ const syncRules = await updateSyncRules(f, {
1018
1029
  content: BASIC_SYNC_RULES
1019
1030
  });
1020
1031
 
@@ -1054,7 +1065,7 @@ bucket_definitions:
1054
1065
  raw_data: true
1055
1066
  },
1056
1067
  tracker,
1057
- token: { sub: '', exp: Date.now() / 1000 + 10 } as any,
1068
+ token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
1058
1069
  isEncodingAsBson: false
1059
1070
  });
1060
1071
 
@@ -1100,7 +1111,8 @@ bucket_definitions:
1100
1111
  });
1101
1112
 
1102
1113
  await bucketStorage.compact({
1103
- minBucketChanges: 1
1114
+ minBucketChanges: 1,
1115
+ minChangeRatio: 0
1104
1116
  });
1105
1117
 
1106
1118
  const lines2 = await getCheckpointLines(iter, { consume: true });
@@ -1156,7 +1168,7 @@ bucket_definitions:
1156
1168
  test('write checkpoint', async () => {
1157
1169
  await using f = await factory();
1158
1170
 
1159
- const syncRules = await f.updateSyncRules({
1171
+ const syncRules = await updateSyncRules(f, {
1160
1172
  content: BASIC_SYNC_RULES
1161
1173
  });
1162
1174
 
@@ -1182,7 +1194,7 @@ bucket_definitions:
1182
1194
  raw_data: true
1183
1195
  },
1184
1196
  tracker,
1185
- token: { sub: 'test', exp: Date.now() / 1000 + 10 } as any,
1197
+ token: new JwtPayload({ sub: 'test', exp: Date.now() / 1000 + 10 }),
1186
1198
  isEncodingAsBson: false
1187
1199
  };
1188
1200
  const stream1 = sync.streamResponse(params);
@@ -1227,7 +1239,7 @@ config:
1227
1239
  `;
1228
1240
 
1229
1241
  for (let i = 0; i < 2; i++) {
1230
- const syncRules = await f.updateSyncRules({
1242
+ const syncRules = await updateSyncRules(f, {
1231
1243
  content: rules
1232
1244
  });
1233
1245
  const bucketStorage = f.getInstance(syncRules);
@@ -1255,7 +1267,7 @@ config:
1255
1267
  raw_data: true
1256
1268
  },
1257
1269
  tracker,
1258
- token: { sub: '', exp: Date.now() / 1000 + 10 } as any,
1270
+ token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
1259
1271
  isEncodingAsBson: false
1260
1272
  });
1261
1273