@powersync/service-core-tests 0.13.1 → 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.
- package/CHANGELOG.md +32 -0
- package/dist/test-utils/general-utils.d.ts +0 -1
- package/dist/test-utils/general-utils.js +0 -24
- package/dist/test-utils/general-utils.js.map +1 -1
- package/dist/tests/register-compacting-tests.js +40 -51
- package/dist/tests/register-compacting-tests.js.map +1 -1
- package/dist/tests/register-data-storage-checkpoint-tests.js +11 -26
- package/dist/tests/register-data-storage-checkpoint-tests.js.map +1 -1
- package/dist/tests/register-data-storage-data-tests.js +80 -96
- package/dist/tests/register-data-storage-data-tests.js.map +1 -1
- package/dist/tests/register-data-storage-parameter-tests.js +84 -46
- package/dist/tests/register-data-storage-parameter-tests.js.map +1 -1
- package/dist/tests/register-parameter-compacting-tests.js +5 -9
- package/dist/tests/register-parameter-compacting-tests.js.map +1 -1
- package/dist/tests/register-sync-tests.d.ts +3 -1
- package/dist/tests/register-sync-tests.js +29 -22
- package/dist/tests/register-sync-tests.js.map +1 -1
- package/dist/tests/util.d.ts +5 -1
- package/dist/tests/util.js +14 -0
- package/dist/tests/util.js.map +1 -1
- package/package.json +4 -4
- package/src/test-utils/general-utils.ts +1 -25
- package/src/tests/register-compacting-tests.ts +56 -51
- package/src/tests/register-data-storage-checkpoint-tests.ts +21 -26
- package/src/tests/register-data-storage-data-tests.ts +135 -101
- package/src/tests/register-data-storage-parameter-tests.ts +102 -47
- package/src/tests/register-parameter-compacting-tests.ts +9 -9
- package/src/tests/register-sync-tests.ts +32 -22
- package/src/tests/util.ts +21 -0
- 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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
{
|
|
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
|
-
|
|
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
|
-
|
|
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([
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
+
}
|