@powersync/service-core 1.10.1 → 1.10.3
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/.probes/poll +1 -0
- package/CHANGELOG.md +12 -0
- package/dist/sync/sync.js +8 -1
- package/dist/sync/sync.js.map +1 -1
- package/package.json +3 -3
- package/src/sync/sync.ts +8 -1
- package/test/dist/auth.test.d.ts +1 -0
- package/test/dist/auth.test.js +332 -0
- package/test/dist/auth.test.js.map +1 -0
- package/test/dist/broadcast_iterable.test.d.ts +1 -0
- package/test/dist/broadcast_iterable.test.js +131 -0
- package/test/dist/broadcast_iterable.test.js.map +1 -0
- package/test/dist/bucket_validation.d.ts +26 -0
- package/test/dist/bucket_validation.js +56 -0
- package/test/dist/bucket_validation.js.map +1 -0
- package/test/dist/bucket_validation.test.d.ts +1 -0
- package/test/dist/bucket_validation.test.js +134 -0
- package/test/dist/bucket_validation.test.js.map +1 -0
- package/test/dist/checksum_cache.test.d.ts +1 -0
- package/test/dist/checksum_cache.test.js +375 -0
- package/test/dist/checksum_cache.test.js.map +1 -0
- package/test/dist/compacting.test.d.ts +1 -0
- package/test/dist/compacting.test.js +254 -0
- package/test/dist/compacting.test.js.map +1 -0
- package/test/dist/data_storage.test.d.ts +1 -0
- package/test/dist/data_storage.test.js +1306 -0
- package/test/dist/data_storage.test.js.map +1 -0
- package/test/dist/demultiplexer.test.d.ts +1 -0
- package/test/dist/demultiplexer.test.js +166 -0
- package/test/dist/demultiplexer.test.js.map +1 -0
- package/test/dist/env.d.ts +3 -0
- package/test/dist/env.js +5 -0
- package/test/dist/env.js.map +1 -0
- package/test/dist/merge_iterable.test.d.ts +1 -0
- package/test/dist/merge_iterable.test.js +321 -0
- package/test/dist/merge_iterable.test.js.map +1 -0
- package/test/dist/routes/probes.integration.test.d.ts +1 -0
- package/test/dist/routes/probes.integration.test.js +192 -0
- package/test/dist/routes/probes.integration.test.js.map +1 -0
- package/test/dist/routes/probes.test.d.ts +1 -0
- package/test/dist/routes/probes.test.js +119 -0
- package/test/dist/routes/probes.test.js.map +1 -0
- package/test/dist/setup.d.ts +1 -0
- package/test/dist/setup.js +7 -0
- package/test/dist/setup.js.map +1 -0
- package/test/dist/stream_utils.d.ts +6 -0
- package/test/dist/stream_utils.js +37 -0
- package/test/dist/stream_utils.js.map +1 -0
- package/test/dist/sync/BucketChecksumState.test.d.ts +1 -0
- package/test/dist/sync/BucketChecksumState.test.js +499 -0
- package/test/dist/sync/BucketChecksumState.test.js.map +1 -0
- package/test/dist/sync/checksum_state.test.d.ts +1 -0
- package/test/dist/sync/checksum_state.test.js +21 -0
- package/test/dist/sync/checksum_state.test.js.map +1 -0
- package/test/dist/sync/util.test.d.ts +1 -0
- package/test/dist/sync/util.test.js +28 -0
- package/test/dist/sync/util.test.js.map +1 -0
- package/test/dist/sync.test.d.ts +1 -0
- package/test/dist/sync.test.js +428 -0
- package/test/dist/sync.test.js.map +1 -0
- package/test/dist/util.d.ts +36 -0
- package/test/dist/util.js +114 -0
- package/test/dist/util.js.map +1 -0
- package/test/dist/util.test.d.ts +1 -0
- package/test/dist/util.test.js +45 -0
- package/test/dist/util.test.js.map +1 -0
- package/test/tsconfig.tsbuildinfo +1 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { OplogEntry } from '@/util/protocol-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validate this property, as described in /docs/bucket-properties.md:
|
|
4
|
+
*
|
|
5
|
+
* $r(B_{[..id_n]}) = r(r(B_{[..id_i]}) \cup B_{[id_{i+1}..id_n]}) \;\forall\; i \in [1..n]$
|
|
6
|
+
*
|
|
7
|
+
* We test that a client syncing the entire bucket in one go (left side of the equation),
|
|
8
|
+
* ends up with the same result as another client syncing up to operation id_i, then sync
|
|
9
|
+
* the rest.
|
|
10
|
+
*/
|
|
11
|
+
export declare function validateBucket(bucket: OplogEntry[]): void;
|
|
12
|
+
/**
|
|
13
|
+
* Validate these properties for a bucket $B$ and its compacted version $B'$,:
|
|
14
|
+
* as described in /docs/bucket-properties.md:
|
|
15
|
+
*
|
|
16
|
+
* 1. $r(B) = r(B')$
|
|
17
|
+
* 2. $r(B_{[..c]}) = r(r(B_{[..c_i]}) \cup B'_{[c_i+1..c]}) \;\forall\; c_i \in B$
|
|
18
|
+
*
|
|
19
|
+
* The first one is that the result of syncing the original bucket is the same as
|
|
20
|
+
* syncing the compacted bucket.
|
|
21
|
+
*
|
|
22
|
+
* The second property is that result of syncing the entire original bucket, is the same
|
|
23
|
+
* as syncing any partial version of that (up to op $c_i$), and then continue syncing
|
|
24
|
+
* using the compacted bucket.
|
|
25
|
+
*/
|
|
26
|
+
export declare function validateCompactedBucket(bucket: OplogEntry[], compacted: OplogEntry[]): void;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { reduceBucket } from '@/util/utils.js';
|
|
2
|
+
import { expect } from 'vitest';
|
|
3
|
+
/**
|
|
4
|
+
* Validate this property, as described in /docs/bucket-properties.md:
|
|
5
|
+
*
|
|
6
|
+
* $r(B_{[..id_n]}) = r(r(B_{[..id_i]}) \cup B_{[id_{i+1}..id_n]}) \;\forall\; i \in [1..n]$
|
|
7
|
+
*
|
|
8
|
+
* We test that a client syncing the entire bucket in one go (left side of the equation),
|
|
9
|
+
* ends up with the same result as another client syncing up to operation id_i, then sync
|
|
10
|
+
* the rest.
|
|
11
|
+
*/
|
|
12
|
+
export function validateBucket(bucket) {
|
|
13
|
+
const r1 = reduceBucket(bucket);
|
|
14
|
+
for (let i = 0; i <= bucket.length; i++) {
|
|
15
|
+
const r2 = reduceBucket(bucket.slice(0, i + 1));
|
|
16
|
+
const b3 = bucket.slice(i + 1);
|
|
17
|
+
const r3 = r2.concat(b3);
|
|
18
|
+
const r4 = reduceBucket(r3);
|
|
19
|
+
expect(r4).toEqual(r1);
|
|
20
|
+
}
|
|
21
|
+
// This is the same check, just implemented differently
|
|
22
|
+
validateCompactedBucket(bucket, bucket);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Validate these properties for a bucket $B$ and its compacted version $B'$,:
|
|
26
|
+
* as described in /docs/bucket-properties.md:
|
|
27
|
+
*
|
|
28
|
+
* 1. $r(B) = r(B')$
|
|
29
|
+
* 2. $r(B_{[..c]}) = r(r(B_{[..c_i]}) \cup B'_{[c_i+1..c]}) \;\forall\; c_i \in B$
|
|
30
|
+
*
|
|
31
|
+
* The first one is that the result of syncing the original bucket is the same as
|
|
32
|
+
* syncing the compacted bucket.
|
|
33
|
+
*
|
|
34
|
+
* The second property is that result of syncing the entire original bucket, is the same
|
|
35
|
+
* as syncing any partial version of that (up to op $c_i$), and then continue syncing
|
|
36
|
+
* using the compacted bucket.
|
|
37
|
+
*/
|
|
38
|
+
export function validateCompactedBucket(bucket, compacted) {
|
|
39
|
+
// r(B_{[..c]})
|
|
40
|
+
const r1 = reduceBucket(bucket);
|
|
41
|
+
// r(B) = r(B')
|
|
42
|
+
expect(reduceBucket(compacted)).toEqual(r1);
|
|
43
|
+
for (let i = 0; i < bucket.length; i++) {
|
|
44
|
+
// r(B_{[..c_i]})
|
|
45
|
+
const r2 = reduceBucket(bucket.slice(0, i + 1));
|
|
46
|
+
const c_i = BigInt(bucket[i].op_id);
|
|
47
|
+
// B'_{[c_i+1..c]}
|
|
48
|
+
const b3 = compacted.filter((op) => BigInt(op.op_id) > c_i);
|
|
49
|
+
// r(B_{[..c_i]}) \cup B'_{[c_i+1..c]}
|
|
50
|
+
const r3 = r2.concat(b3);
|
|
51
|
+
// r(r(B_{[..c_i]}) \cup B'_{[c_i+1..c]})
|
|
52
|
+
const r4 = reduceBucket(r3);
|
|
53
|
+
expect(r4).toEqual(r1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=bucket_validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bucket_validation.js","sourceRoot":"","sources":["../src/bucket_validation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,MAAoB;IACjD,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/B,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,MAAM,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;QAC5B,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IAED,uDAAuD;IACvD,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAoB,EAAE,SAAuB;IACnF,eAAe;IACf,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAChC,eAAe;IACf,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAE5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,iBAAiB;QACjB,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACpC,kBAAkB;QAClB,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;QAC5D,sCAAsC;QACtC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,yCAAyC;QACzC,MAAM,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;QAC5B,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import { validateBucket } from './bucket_validation.js';
|
|
3
|
+
import { reduceBucket } from '@/index.js';
|
|
4
|
+
// This tests the reduceBucket function.
|
|
5
|
+
// While this function is not used directly in the service implementation,
|
|
6
|
+
// it is an important part of validating consistency in other tests.
|
|
7
|
+
describe('bucket validation', () => {
|
|
8
|
+
const ops1 = [
|
|
9
|
+
{
|
|
10
|
+
op_id: '1',
|
|
11
|
+
op: 'PUT',
|
|
12
|
+
object_type: 'test',
|
|
13
|
+
object_id: 't1',
|
|
14
|
+
checksum: 2634521662,
|
|
15
|
+
subkey: '6544e3899293153fa7b38331/117ab485-4b42-58a2-ab32-0053a22c3423',
|
|
16
|
+
data: '{"id":"t1"}'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
op_id: '2',
|
|
20
|
+
op: 'PUT',
|
|
21
|
+
object_type: 'test',
|
|
22
|
+
object_id: 't2',
|
|
23
|
+
checksum: 4243212114,
|
|
24
|
+
subkey: '6544e3899293153fa7b38331/ec27c691-b47a-5d92-927a-9944feb89eee',
|
|
25
|
+
data: '{"id":"t2"}'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
op_id: '3',
|
|
29
|
+
op: 'REMOVE',
|
|
30
|
+
object_type: 'test',
|
|
31
|
+
object_id: 't1',
|
|
32
|
+
checksum: 4228978084,
|
|
33
|
+
subkey: '6544e3899293153fa7b38331/117ab485-4b42-58a2-ab32-0053a22c3423',
|
|
34
|
+
data: null
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
op_id: '4',
|
|
38
|
+
op: 'PUT',
|
|
39
|
+
object_type: 'test',
|
|
40
|
+
object_id: 't2',
|
|
41
|
+
checksum: 4243212114,
|
|
42
|
+
subkey: '6544e3899293153fa7b38331/ec27c691-b47a-5d92-927a-9944feb89eee',
|
|
43
|
+
data: '{"id":"t2"}'
|
|
44
|
+
}
|
|
45
|
+
];
|
|
46
|
+
test('reduce 1', () => {
|
|
47
|
+
expect(reduceBucket(ops1)).toEqual([
|
|
48
|
+
{
|
|
49
|
+
checksum: -1778190028,
|
|
50
|
+
op: 'CLEAR',
|
|
51
|
+
op_id: '0'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
checksum: 4243212114,
|
|
55
|
+
data: '{"id":"t2"}',
|
|
56
|
+
object_id: 't2',
|
|
57
|
+
object_type: 'test',
|
|
58
|
+
op: 'PUT',
|
|
59
|
+
op_id: '4',
|
|
60
|
+
subkey: '6544e3899293153fa7b38331/ec27c691-b47a-5d92-927a-9944feb89eee'
|
|
61
|
+
}
|
|
62
|
+
]);
|
|
63
|
+
expect(reduceBucket(reduceBucket(ops1))).toEqual([
|
|
64
|
+
{
|
|
65
|
+
checksum: -1778190028,
|
|
66
|
+
op: 'CLEAR',
|
|
67
|
+
op_id: '0'
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
checksum: 4243212114,
|
|
71
|
+
data: '{"id":"t2"}',
|
|
72
|
+
object_id: 't2',
|
|
73
|
+
object_type: 'test',
|
|
74
|
+
op: 'PUT',
|
|
75
|
+
op_id: '4',
|
|
76
|
+
subkey: '6544e3899293153fa7b38331/ec27c691-b47a-5d92-927a-9944feb89eee'
|
|
77
|
+
}
|
|
78
|
+
]);
|
|
79
|
+
validateBucket(ops1);
|
|
80
|
+
});
|
|
81
|
+
test('reduce 2', () => {
|
|
82
|
+
const bucket = [
|
|
83
|
+
...ops1,
|
|
84
|
+
{
|
|
85
|
+
checksum: 93784613,
|
|
86
|
+
op: 'CLEAR',
|
|
87
|
+
op_id: '5'
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
checksum: 5133378,
|
|
91
|
+
data: '{"id":"t3"}',
|
|
92
|
+
object_id: 't3',
|
|
93
|
+
object_type: 'test',
|
|
94
|
+
op: 'PUT',
|
|
95
|
+
op_id: '11',
|
|
96
|
+
subkey: '6544e3899293153fa7b38333/ec27c691-b47a-5d92-927a-9944feb89eee'
|
|
97
|
+
}
|
|
98
|
+
];
|
|
99
|
+
expect(reduceBucket(bucket)).toEqual([
|
|
100
|
+
{
|
|
101
|
+
checksum: 93784613,
|
|
102
|
+
op: 'CLEAR',
|
|
103
|
+
op_id: '0'
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
checksum: 5133378,
|
|
107
|
+
data: '{"id":"t3"}',
|
|
108
|
+
object_id: 't3',
|
|
109
|
+
object_type: 'test',
|
|
110
|
+
op: 'PUT',
|
|
111
|
+
op_id: '11',
|
|
112
|
+
subkey: '6544e3899293153fa7b38333/ec27c691-b47a-5d92-927a-9944feb89eee'
|
|
113
|
+
}
|
|
114
|
+
]);
|
|
115
|
+
expect(reduceBucket(reduceBucket(bucket))).toEqual([
|
|
116
|
+
{
|
|
117
|
+
checksum: 93784613,
|
|
118
|
+
op: 'CLEAR',
|
|
119
|
+
op_id: '0'
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
checksum: 5133378,
|
|
123
|
+
data: '{"id":"t3"}',
|
|
124
|
+
object_id: 't3',
|
|
125
|
+
object_type: 'test',
|
|
126
|
+
op: 'PUT',
|
|
127
|
+
op_id: '11',
|
|
128
|
+
subkey: '6544e3899293153fa7b38333/ec27c691-b47a-5d92-927a-9944feb89eee'
|
|
129
|
+
}
|
|
130
|
+
]);
|
|
131
|
+
validateBucket(bucket);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
//# sourceMappingURL=bucket_validation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bucket_validation.test.js","sourceRoot":"","sources":["../src/bucket_validation.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { ChecksumCache } from '@/storage/ChecksumCache.js';
|
|
2
|
+
import { addChecksums } from '@/util/util-index.js';
|
|
3
|
+
import * as crypto from 'node:crypto';
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
/**
|
|
6
|
+
* Create a deterministic BucketChecksum based on the bucket name and checkpoint for testing purposes.
|
|
7
|
+
*/
|
|
8
|
+
function testHash(bucket, checkpoint) {
|
|
9
|
+
const key = `${checkpoint}/${bucket}`;
|
|
10
|
+
const hash = crypto.createHash('sha256').update(key).digest().readInt32LE(0);
|
|
11
|
+
return hash;
|
|
12
|
+
}
|
|
13
|
+
function testPartialHash(request) {
|
|
14
|
+
if (request.start) {
|
|
15
|
+
const a = testHash(request.bucket, request.start);
|
|
16
|
+
const b = testHash(request.bucket, request.end);
|
|
17
|
+
return {
|
|
18
|
+
bucket: request.bucket,
|
|
19
|
+
partialCount: Number(request.end) - Number(request.start),
|
|
20
|
+
partialChecksum: addChecksums(b, -a),
|
|
21
|
+
isFullChecksum: false
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return {
|
|
26
|
+
bucket: request.bucket,
|
|
27
|
+
partialChecksum: testHash(request.bucket, request.end),
|
|
28
|
+
partialCount: Number(request.end),
|
|
29
|
+
isFullChecksum: true
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const TEST_123 = {
|
|
34
|
+
bucket: 'test',
|
|
35
|
+
count: 123,
|
|
36
|
+
checksum: 1104081737
|
|
37
|
+
};
|
|
38
|
+
const TEST_1234 = {
|
|
39
|
+
bucket: 'test',
|
|
40
|
+
count: 1234,
|
|
41
|
+
checksum: -1593864957
|
|
42
|
+
};
|
|
43
|
+
const TEST2_123 = {
|
|
44
|
+
bucket: 'test2',
|
|
45
|
+
count: 123,
|
|
46
|
+
checksum: 1741377449
|
|
47
|
+
};
|
|
48
|
+
const TEST3_123 = {
|
|
49
|
+
bucket: 'test3',
|
|
50
|
+
count: 123,
|
|
51
|
+
checksum: -2085080402
|
|
52
|
+
};
|
|
53
|
+
function fetchTestChecksums(batch) {
|
|
54
|
+
return new Map(batch.map((v) => {
|
|
55
|
+
return [v.bucket, testPartialHash(v)];
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
describe('checksum cache', function () {
|
|
59
|
+
const factory = (fetch) => {
|
|
60
|
+
return new ChecksumCache({ fetchChecksums: fetch });
|
|
61
|
+
};
|
|
62
|
+
it('should handle a sequential lookups (a)', async function () {
|
|
63
|
+
let lookups = [];
|
|
64
|
+
const cache = factory(async (batch) => {
|
|
65
|
+
lookups.push(batch);
|
|
66
|
+
return fetchTestChecksums(batch);
|
|
67
|
+
});
|
|
68
|
+
expect(await cache.getChecksums(123n, ['test'])).toEqual([TEST_123]);
|
|
69
|
+
expect(await cache.getChecksums(1234n, ['test'])).toEqual([TEST_1234]);
|
|
70
|
+
expect(await cache.getChecksums(123n, ['test2'])).toEqual([TEST2_123]);
|
|
71
|
+
expect(lookups).toEqual([
|
|
72
|
+
[{ bucket: 'test', end: 123n }],
|
|
73
|
+
// This should use the previous lookup
|
|
74
|
+
[{ bucket: 'test', start: 123n, end: 1234n }],
|
|
75
|
+
[{ bucket: 'test2', end: 123n }]
|
|
76
|
+
]);
|
|
77
|
+
});
|
|
78
|
+
it('should handle a sequential lookups (b)', async function () {
|
|
79
|
+
// Reverse order of the above
|
|
80
|
+
let lookups = [];
|
|
81
|
+
const cache = factory(async (batch) => {
|
|
82
|
+
lookups.push(batch);
|
|
83
|
+
return fetchTestChecksums(batch);
|
|
84
|
+
});
|
|
85
|
+
expect(await cache.getChecksums(123n, ['test2'])).toEqual([TEST2_123]);
|
|
86
|
+
expect(await cache.getChecksums(1234n, ['test'])).toEqual([TEST_1234]);
|
|
87
|
+
expect(await cache.getChecksums(123n, ['test'])).toEqual([TEST_123]);
|
|
88
|
+
expect(lookups).toEqual([
|
|
89
|
+
// With this order, there is no option for a partial lookup
|
|
90
|
+
[{ bucket: 'test2', end: 123n }],
|
|
91
|
+
[{ bucket: 'test', end: 1234n }],
|
|
92
|
+
[{ bucket: 'test', end: 123n }]
|
|
93
|
+
]);
|
|
94
|
+
});
|
|
95
|
+
it('should handle a concurrent lookups (a)', async function () {
|
|
96
|
+
let lookups = [];
|
|
97
|
+
const cache = factory(async (batch) => {
|
|
98
|
+
lookups.push(batch);
|
|
99
|
+
return fetchTestChecksums(batch);
|
|
100
|
+
});
|
|
101
|
+
const p1 = cache.getChecksums(123n, ['test']);
|
|
102
|
+
const p2 = cache.getChecksums(1234n, ['test']);
|
|
103
|
+
const p3 = cache.getChecksums(123n, ['test2']);
|
|
104
|
+
expect(await p1).toEqual([TEST_123]);
|
|
105
|
+
expect(await p2).toEqual([TEST_1234]);
|
|
106
|
+
expect(await p3).toEqual([TEST2_123]);
|
|
107
|
+
// Concurrent requests, so we can't do a partial lookup for 123 -> 1234
|
|
108
|
+
expect(lookups).toEqual([
|
|
109
|
+
[{ bucket: 'test', end: 123n }],
|
|
110
|
+
[{ bucket: 'test', end: 1234n }],
|
|
111
|
+
[{ bucket: 'test2', end: 123n }]
|
|
112
|
+
]);
|
|
113
|
+
});
|
|
114
|
+
it('should handle a concurrent lookups (b)', async function () {
|
|
115
|
+
let lookups = [];
|
|
116
|
+
const cache = factory(async (batch) => {
|
|
117
|
+
lookups.push(batch);
|
|
118
|
+
return fetchTestChecksums(batch);
|
|
119
|
+
});
|
|
120
|
+
const p1 = cache.getChecksums(123n, ['test']);
|
|
121
|
+
const p2 = cache.getChecksums(123n, ['test']);
|
|
122
|
+
expect(await p1).toEqual([TEST_123]);
|
|
123
|
+
expect(await p2).toEqual([TEST_123]);
|
|
124
|
+
// The lookup should be deduplicated, even though it's in progress
|
|
125
|
+
expect(lookups).toEqual([[{ bucket: 'test', end: 123n }]]);
|
|
126
|
+
});
|
|
127
|
+
it('should handle serial + concurrent lookups', async function () {
|
|
128
|
+
let lookups = [];
|
|
129
|
+
const cache = factory(async (batch) => {
|
|
130
|
+
lookups.push(batch);
|
|
131
|
+
return fetchTestChecksums(batch);
|
|
132
|
+
});
|
|
133
|
+
expect(await cache.getChecksums(123n, ['test'])).toEqual([TEST_123]);
|
|
134
|
+
const p2 = cache.getChecksums(1234n, ['test']);
|
|
135
|
+
const p3 = cache.getChecksums(1234n, ['test']);
|
|
136
|
+
expect(await p2).toEqual([TEST_1234]);
|
|
137
|
+
expect(await p3).toEqual([TEST_1234]);
|
|
138
|
+
expect(lookups).toEqual([
|
|
139
|
+
[{ bucket: 'test', end: 123n }],
|
|
140
|
+
// This lookup is deduplicated
|
|
141
|
+
[{ bucket: 'test', start: 123n, end: 1234n }]
|
|
142
|
+
]);
|
|
143
|
+
});
|
|
144
|
+
it('should handle multiple buckets', async function () {
|
|
145
|
+
let lookups = [];
|
|
146
|
+
const cache = factory(async (batch) => {
|
|
147
|
+
lookups.push(batch);
|
|
148
|
+
return fetchTestChecksums(batch);
|
|
149
|
+
});
|
|
150
|
+
expect(await cache.getChecksums(123n, ['test', 'test2'])).toEqual([TEST_123, TEST2_123]);
|
|
151
|
+
expect(lookups).toEqual([
|
|
152
|
+
[
|
|
153
|
+
// Both lookups in the same request
|
|
154
|
+
{ bucket: 'test', end: 123n },
|
|
155
|
+
{ bucket: 'test2', end: 123n }
|
|
156
|
+
]
|
|
157
|
+
]);
|
|
158
|
+
});
|
|
159
|
+
it('should handle multiple buckets with partial caching (a)', async function () {
|
|
160
|
+
let lookups = [];
|
|
161
|
+
const cache = factory(async (batch) => {
|
|
162
|
+
lookups.push(batch);
|
|
163
|
+
return fetchTestChecksums(batch);
|
|
164
|
+
});
|
|
165
|
+
expect(await cache.getChecksums(123n, ['test'])).toEqual([TEST_123]);
|
|
166
|
+
expect(await cache.getChecksums(123n, ['test', 'test2'])).toEqual([TEST_123, TEST2_123]);
|
|
167
|
+
expect(lookups).toEqual([
|
|
168
|
+
// Request 1
|
|
169
|
+
[{ bucket: 'test', end: 123n }],
|
|
170
|
+
// Request 2
|
|
171
|
+
[{ bucket: 'test2', end: 123n }]
|
|
172
|
+
]);
|
|
173
|
+
});
|
|
174
|
+
it('should handle multiple buckets with partial caching (b)', async function () {
|
|
175
|
+
let lookups = [];
|
|
176
|
+
const cache = factory(async (batch) => {
|
|
177
|
+
lookups.push(batch);
|
|
178
|
+
return fetchTestChecksums(batch);
|
|
179
|
+
});
|
|
180
|
+
const a = cache.getChecksums(123n, ['test', 'test2']);
|
|
181
|
+
const b = cache.getChecksums(123n, ['test2', 'test3']);
|
|
182
|
+
expect(await a).toEqual([TEST_123, TEST2_123]);
|
|
183
|
+
expect(await b).toEqual([TEST2_123, TEST3_123]);
|
|
184
|
+
expect(lookups).toEqual([
|
|
185
|
+
// Request A
|
|
186
|
+
[
|
|
187
|
+
{ bucket: 'test', end: 123n },
|
|
188
|
+
{ bucket: 'test2', end: 123n }
|
|
189
|
+
],
|
|
190
|
+
// Request B (re-uses the checksum for test2 from request a)
|
|
191
|
+
[{ bucket: 'test3', end: 123n }]
|
|
192
|
+
]);
|
|
193
|
+
});
|
|
194
|
+
it('should handle out-of-order requests', async function () {
|
|
195
|
+
let lookups = [];
|
|
196
|
+
const cache = factory(async (batch) => {
|
|
197
|
+
lookups.push(batch);
|
|
198
|
+
return fetchTestChecksums(batch);
|
|
199
|
+
});
|
|
200
|
+
expect(await cache.getChecksums(123n, ['test'])).toEqual([TEST_123]);
|
|
201
|
+
expect(await cache.getChecksums(125n, ['test'])).toEqual([
|
|
202
|
+
{
|
|
203
|
+
bucket: 'test',
|
|
204
|
+
checksum: -1865121912,
|
|
205
|
+
count: 125
|
|
206
|
+
}
|
|
207
|
+
]);
|
|
208
|
+
expect(await cache.getChecksums(124n, ['test'])).toEqual([
|
|
209
|
+
{
|
|
210
|
+
bucket: 'test',
|
|
211
|
+
checksum: 1887460431,
|
|
212
|
+
count: 124
|
|
213
|
+
}
|
|
214
|
+
]);
|
|
215
|
+
expect(lookups).toEqual([
|
|
216
|
+
[{ bucket: 'test', end: 123n }],
|
|
217
|
+
[{ bucket: 'test', start: 123n, end: 125n }],
|
|
218
|
+
[{ bucket: 'test', start: 123n, end: 124n }]
|
|
219
|
+
]);
|
|
220
|
+
});
|
|
221
|
+
it('should handle errors', async function () {
|
|
222
|
+
let lookups = [];
|
|
223
|
+
const TEST_ERROR = new Error('Simulated error');
|
|
224
|
+
const cache = factory(async (batch) => {
|
|
225
|
+
lookups.push(batch);
|
|
226
|
+
if (lookups.length == 1) {
|
|
227
|
+
throw new Error('Simulated error');
|
|
228
|
+
}
|
|
229
|
+
return fetchTestChecksums(batch);
|
|
230
|
+
});
|
|
231
|
+
const a = cache.getChecksums(123n, ['test', 'test2']);
|
|
232
|
+
const b = cache.getChecksums(123n, ['test2', 'test3']);
|
|
233
|
+
await expect(a).rejects.toEqual(TEST_ERROR);
|
|
234
|
+
await expect(b).rejects.toEqual(TEST_ERROR);
|
|
235
|
+
const a2 = cache.getChecksums(123n, ['test', 'test2']);
|
|
236
|
+
const b2 = cache.getChecksums(123n, ['test2', 'test3']);
|
|
237
|
+
expect(await a2).toEqual([TEST_123, TEST2_123]);
|
|
238
|
+
expect(await b2).toEqual([TEST2_123, TEST3_123]);
|
|
239
|
+
expect(lookups).toEqual([
|
|
240
|
+
// Request A (fails)
|
|
241
|
+
[
|
|
242
|
+
{ bucket: 'test', end: 123n },
|
|
243
|
+
{ bucket: 'test2', end: 123n }
|
|
244
|
+
],
|
|
245
|
+
// Request B (re-uses the checksum for test2 from request a)
|
|
246
|
+
// Even thought the full request fails, this batch succeeds
|
|
247
|
+
[{ bucket: 'test3', end: 123n }],
|
|
248
|
+
// Retry request A
|
|
249
|
+
[
|
|
250
|
+
{ bucket: 'test', end: 123n },
|
|
251
|
+
{ bucket: 'test2', end: 123n }
|
|
252
|
+
]
|
|
253
|
+
]);
|
|
254
|
+
});
|
|
255
|
+
it('should handle missing checksums (a)', async function () {
|
|
256
|
+
let lookups = [];
|
|
257
|
+
const cache = factory(async (batch) => {
|
|
258
|
+
lookups.push(batch);
|
|
259
|
+
return fetchTestChecksums(batch.filter((b) => b.bucket != 'test'));
|
|
260
|
+
});
|
|
261
|
+
expect(await cache.getChecksums(123n, ['test'])).toEqual([{ bucket: 'test', checksum: 0, count: 0 }]);
|
|
262
|
+
expect(await cache.getChecksums(123n, ['test', 'test2'])).toEqual([
|
|
263
|
+
{ bucket: 'test', checksum: 0, count: 0 },
|
|
264
|
+
TEST2_123
|
|
265
|
+
]);
|
|
266
|
+
});
|
|
267
|
+
it('should handle missing checksums (b)', async function () {
|
|
268
|
+
let lookups = [];
|
|
269
|
+
const cache = factory(async (batch) => {
|
|
270
|
+
lookups.push(batch);
|
|
271
|
+
return fetchTestChecksums(batch.filter((b) => b.bucket != 'test' || b.end != 123n));
|
|
272
|
+
});
|
|
273
|
+
expect(await cache.getChecksums(123n, ['test'])).toEqual([{ bucket: 'test', checksum: 0, count: 0 }]);
|
|
274
|
+
expect(await cache.getChecksums(1234n, ['test'])).toEqual([
|
|
275
|
+
{
|
|
276
|
+
bucket: 'test',
|
|
277
|
+
checksum: 1597020602,
|
|
278
|
+
count: 1111
|
|
279
|
+
}
|
|
280
|
+
]);
|
|
281
|
+
expect(lookups).toEqual([[{ bucket: 'test', end: 123n }], [{ bucket: 'test', start: 123n, end: 1234n }]]);
|
|
282
|
+
});
|
|
283
|
+
it('should use maxSize', async function () {
|
|
284
|
+
let lookups = [];
|
|
285
|
+
const cache = new ChecksumCache({
|
|
286
|
+
fetchChecksums: async (batch) => {
|
|
287
|
+
lookups.push(batch);
|
|
288
|
+
return fetchTestChecksums(batch);
|
|
289
|
+
},
|
|
290
|
+
maxSize: 2
|
|
291
|
+
});
|
|
292
|
+
expect(await cache.getChecksums(123n, ['test'])).toEqual([TEST_123]);
|
|
293
|
+
expect(await cache.getChecksums(124n, ['test'])).toEqual([
|
|
294
|
+
{
|
|
295
|
+
bucket: 'test',
|
|
296
|
+
checksum: 1887460431,
|
|
297
|
+
count: 124
|
|
298
|
+
}
|
|
299
|
+
]);
|
|
300
|
+
expect(await cache.getChecksums(125n, ['test'])).toEqual([
|
|
301
|
+
{
|
|
302
|
+
bucket: 'test',
|
|
303
|
+
checksum: -1865121912,
|
|
304
|
+
count: 125
|
|
305
|
+
}
|
|
306
|
+
]);
|
|
307
|
+
expect(await cache.getChecksums(126n, ['test'])).toEqual([
|
|
308
|
+
{
|
|
309
|
+
bucket: 'test',
|
|
310
|
+
checksum: -1720007310,
|
|
311
|
+
count: 126
|
|
312
|
+
}
|
|
313
|
+
]);
|
|
314
|
+
expect(await cache.getChecksums(124n, ['test'])).toEqual([
|
|
315
|
+
{
|
|
316
|
+
bucket: 'test',
|
|
317
|
+
checksum: 1887460431,
|
|
318
|
+
count: 124
|
|
319
|
+
}
|
|
320
|
+
]);
|
|
321
|
+
expect(await cache.getChecksums(123n, ['test'])).toEqual([TEST_123]);
|
|
322
|
+
expect(lookups).toEqual([
|
|
323
|
+
[{ bucket: 'test', end: 123n }],
|
|
324
|
+
[{ bucket: 'test', start: 123n, end: 124n }],
|
|
325
|
+
[{ bucket: 'test', start: 124n, end: 125n }],
|
|
326
|
+
[{ bucket: 'test', start: 125n, end: 126n }],
|
|
327
|
+
[{ bucket: 'test', end: 124n }],
|
|
328
|
+
[{ bucket: 'test', end: 123n }]
|
|
329
|
+
]);
|
|
330
|
+
});
|
|
331
|
+
it('should handle concurrent requests greater than cache size', async function () {
|
|
332
|
+
// This will not be cached efficiently, but we test that we don't get errors at least.
|
|
333
|
+
let lookups = [];
|
|
334
|
+
const cache = new ChecksumCache({
|
|
335
|
+
fetchChecksums: async (batch) => {
|
|
336
|
+
lookups.push(batch);
|
|
337
|
+
return fetchTestChecksums(batch);
|
|
338
|
+
},
|
|
339
|
+
maxSize: 2
|
|
340
|
+
});
|
|
341
|
+
const p3 = cache.getChecksums(123n, ['test3']);
|
|
342
|
+
const p4 = cache.getChecksums(123n, ['test4']);
|
|
343
|
+
const p1 = cache.getChecksums(123n, ['test']);
|
|
344
|
+
const p2 = cache.getChecksums(123n, ['test2']);
|
|
345
|
+
expect(await p1).toEqual([TEST_123]);
|
|
346
|
+
expect(await p2).toEqual([TEST2_123]);
|
|
347
|
+
expect(await p3).toEqual([TEST3_123]);
|
|
348
|
+
expect(await p4).toEqual([
|
|
349
|
+
{
|
|
350
|
+
bucket: 'test4',
|
|
351
|
+
checksum: 1004797863,
|
|
352
|
+
count: 123
|
|
353
|
+
}
|
|
354
|
+
]);
|
|
355
|
+
// The lookup should be deduplicated, even though it's in progress
|
|
356
|
+
expect(lookups).toEqual([
|
|
357
|
+
[{ bucket: 'test3', end: 123n }],
|
|
358
|
+
[{ bucket: 'test4', end: 123n }],
|
|
359
|
+
[{ bucket: 'test', end: 123n }],
|
|
360
|
+
[{ bucket: 'test2', end: 123n }]
|
|
361
|
+
]);
|
|
362
|
+
});
|
|
363
|
+
it('should handle CLEAR/isFullChecksum checksums', async function () {
|
|
364
|
+
let lookups = [];
|
|
365
|
+
const cache = factory(async (batch) => {
|
|
366
|
+
lookups.push(batch);
|
|
367
|
+
// This forces a `isFullChecksum: true` result
|
|
368
|
+
delete batch[0].start;
|
|
369
|
+
return fetchTestChecksums(batch);
|
|
370
|
+
});
|
|
371
|
+
expect(await cache.getChecksums(123n, ['test'])).toEqual([TEST_123]);
|
|
372
|
+
expect(await cache.getChecksums(1234n, ['test'])).toEqual([TEST_1234]);
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
//# sourceMappingURL=checksum_cache.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checksum_cache.test.js","sourceRoot":"","sources":["../src/checksum_cache.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|