@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.
Files changed (68) hide show
  1. package/.probes/poll +1 -0
  2. package/CHANGELOG.md +12 -0
  3. package/dist/sync/sync.js +8 -1
  4. package/dist/sync/sync.js.map +1 -1
  5. package/package.json +3 -3
  6. package/src/sync/sync.ts +8 -1
  7. package/test/dist/auth.test.d.ts +1 -0
  8. package/test/dist/auth.test.js +332 -0
  9. package/test/dist/auth.test.js.map +1 -0
  10. package/test/dist/broadcast_iterable.test.d.ts +1 -0
  11. package/test/dist/broadcast_iterable.test.js +131 -0
  12. package/test/dist/broadcast_iterable.test.js.map +1 -0
  13. package/test/dist/bucket_validation.d.ts +26 -0
  14. package/test/dist/bucket_validation.js +56 -0
  15. package/test/dist/bucket_validation.js.map +1 -0
  16. package/test/dist/bucket_validation.test.d.ts +1 -0
  17. package/test/dist/bucket_validation.test.js +134 -0
  18. package/test/dist/bucket_validation.test.js.map +1 -0
  19. package/test/dist/checksum_cache.test.d.ts +1 -0
  20. package/test/dist/checksum_cache.test.js +375 -0
  21. package/test/dist/checksum_cache.test.js.map +1 -0
  22. package/test/dist/compacting.test.d.ts +1 -0
  23. package/test/dist/compacting.test.js +254 -0
  24. package/test/dist/compacting.test.js.map +1 -0
  25. package/test/dist/data_storage.test.d.ts +1 -0
  26. package/test/dist/data_storage.test.js +1306 -0
  27. package/test/dist/data_storage.test.js.map +1 -0
  28. package/test/dist/demultiplexer.test.d.ts +1 -0
  29. package/test/dist/demultiplexer.test.js +166 -0
  30. package/test/dist/demultiplexer.test.js.map +1 -0
  31. package/test/dist/env.d.ts +3 -0
  32. package/test/dist/env.js +5 -0
  33. package/test/dist/env.js.map +1 -0
  34. package/test/dist/merge_iterable.test.d.ts +1 -0
  35. package/test/dist/merge_iterable.test.js +321 -0
  36. package/test/dist/merge_iterable.test.js.map +1 -0
  37. package/test/dist/routes/probes.integration.test.d.ts +1 -0
  38. package/test/dist/routes/probes.integration.test.js +192 -0
  39. package/test/dist/routes/probes.integration.test.js.map +1 -0
  40. package/test/dist/routes/probes.test.d.ts +1 -0
  41. package/test/dist/routes/probes.test.js +119 -0
  42. package/test/dist/routes/probes.test.js.map +1 -0
  43. package/test/dist/setup.d.ts +1 -0
  44. package/test/dist/setup.js +7 -0
  45. package/test/dist/setup.js.map +1 -0
  46. package/test/dist/stream_utils.d.ts +6 -0
  47. package/test/dist/stream_utils.js +37 -0
  48. package/test/dist/stream_utils.js.map +1 -0
  49. package/test/dist/sync/BucketChecksumState.test.d.ts +1 -0
  50. package/test/dist/sync/BucketChecksumState.test.js +499 -0
  51. package/test/dist/sync/BucketChecksumState.test.js.map +1 -0
  52. package/test/dist/sync/checksum_state.test.d.ts +1 -0
  53. package/test/dist/sync/checksum_state.test.js +21 -0
  54. package/test/dist/sync/checksum_state.test.js.map +1 -0
  55. package/test/dist/sync/util.test.d.ts +1 -0
  56. package/test/dist/sync/util.test.js +28 -0
  57. package/test/dist/sync/util.test.js.map +1 -0
  58. package/test/dist/sync.test.d.ts +1 -0
  59. package/test/dist/sync.test.js +428 -0
  60. package/test/dist/sync.test.js.map +1 -0
  61. package/test/dist/util.d.ts +36 -0
  62. package/test/dist/util.js +114 -0
  63. package/test/dist/util.js.map +1 -0
  64. package/test/dist/util.test.d.ts +1 -0
  65. package/test/dist/util.test.js +45 -0
  66. package/test/dist/util.test.js.map +1 -0
  67. package/test/tsconfig.tsbuildinfo +1 -0
  68. 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 {};