@aztec/kv-store 0.0.0-test.1 → 0.0.1-commit.017a351

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 (221) hide show
  1. package/README.md +8 -1
  2. package/dest/bench/shared_map_bench.d.ts +19 -0
  3. package/dest/bench/shared_map_bench.d.ts.map +1 -0
  4. package/dest/bench/shared_map_bench.js +91 -0
  5. package/dest/indexeddb/array.d.ts +3 -2
  6. package/dest/indexeddb/array.d.ts.map +1 -1
  7. package/dest/indexeddb/array.js +24 -7
  8. package/dest/indexeddb/index.d.ts +3 -3
  9. package/dest/indexeddb/index.d.ts.map +1 -1
  10. package/dest/indexeddb/index.js +4 -7
  11. package/dest/indexeddb/map.d.ts +18 -6
  12. package/dest/indexeddb/map.d.ts.map +1 -1
  13. package/dest/indexeddb/map.js +51 -63
  14. package/dest/indexeddb/multi_map.d.ts +14 -0
  15. package/dest/indexeddb/multi_map.d.ts.map +1 -0
  16. package/dest/indexeddb/multi_map.js +107 -0
  17. package/dest/indexeddb/set.d.ts +1 -1
  18. package/dest/indexeddb/set.d.ts.map +1 -1
  19. package/dest/indexeddb/singleton.d.ts +3 -2
  20. package/dest/indexeddb/singleton.d.ts.map +1 -1
  21. package/dest/indexeddb/singleton.js +6 -2
  22. package/dest/indexeddb/store.d.ts +15 -16
  23. package/dest/indexeddb/store.d.ts.map +1 -1
  24. package/dest/indexeddb/store.js +51 -46
  25. package/dest/interfaces/array.d.ts +5 -4
  26. package/dest/interfaces/array.d.ts.map +1 -1
  27. package/dest/interfaces/array.js +1 -3
  28. package/dest/interfaces/array_test_suite.d.ts +1 -1
  29. package/dest/interfaces/array_test_suite.d.ts.map +1 -1
  30. package/dest/interfaces/array_test_suite.js +33 -34
  31. package/dest/interfaces/common.d.ts +11 -9
  32. package/dest/interfaces/common.d.ts.map +1 -1
  33. package/dest/interfaces/common.js +8 -3
  34. package/dest/interfaces/counter.d.ts +1 -1
  35. package/dest/interfaces/index.d.ts +4 -2
  36. package/dest/interfaces/index.d.ts.map +1 -1
  37. package/dest/interfaces/index.js +2 -0
  38. package/dest/interfaces/map.d.ts +21 -49
  39. package/dest/interfaces/map.d.ts.map +1 -1
  40. package/dest/interfaces/map.js +1 -1
  41. package/dest/interfaces/map_test_suite.d.ts +1 -1
  42. package/dest/interfaces/map_test_suite.d.ts.map +1 -1
  43. package/dest/interfaces/map_test_suite.js +193 -83
  44. package/dest/interfaces/multi_map.d.ts +41 -0
  45. package/dest/interfaces/multi_map.d.ts.map +1 -0
  46. package/dest/interfaces/multi_map.js +3 -0
  47. package/dest/interfaces/multi_map_test_suite.d.ts +3 -0
  48. package/dest/interfaces/multi_map_test_suite.d.ts.map +1 -0
  49. package/dest/interfaces/multi_map_test_suite.js +363 -0
  50. package/dest/interfaces/set.d.ts +1 -1
  51. package/dest/interfaces/set_test_suite.d.ts +1 -1
  52. package/dest/interfaces/set_test_suite.d.ts.map +1 -1
  53. package/dest/interfaces/set_test_suite.js +13 -14
  54. package/dest/interfaces/singleton.d.ts +1 -1
  55. package/dest/interfaces/singleton_test_suite.d.ts +1 -1
  56. package/dest/interfaces/singleton_test_suite.d.ts.map +1 -1
  57. package/dest/interfaces/singleton_test_suite.js +6 -7
  58. package/dest/interfaces/store.d.ts +18 -43
  59. package/dest/interfaces/store.d.ts.map +1 -1
  60. package/dest/interfaces/utils.d.ts +3 -1
  61. package/dest/interfaces/utils.d.ts.map +1 -1
  62. package/dest/interfaces/utils.js +3 -1
  63. package/dest/lmdb/array.d.ts +3 -2
  64. package/dest/lmdb/array.d.ts.map +1 -1
  65. package/dest/lmdb/array.js +4 -2
  66. package/dest/lmdb/counter.d.ts +1 -1
  67. package/dest/lmdb/counter.d.ts.map +1 -1
  68. package/dest/lmdb/index.d.ts +3 -3
  69. package/dest/lmdb/index.d.ts.map +1 -1
  70. package/dest/lmdb/index.js +6 -6
  71. package/dest/lmdb/map.d.ts +11 -23
  72. package/dest/lmdb/map.d.ts.map +1 -1
  73. package/dest/lmdb/map.js +15 -81
  74. package/dest/lmdb/multi_map.d.ts +13 -0
  75. package/dest/lmdb/multi_map.d.ts.map +1 -0
  76. package/dest/lmdb/multi_map.js +44 -0
  77. package/dest/lmdb/set.d.ts +1 -1
  78. package/dest/lmdb/set.d.ts.map +1 -1
  79. package/dest/lmdb/singleton.d.ts +1 -1
  80. package/dest/lmdb/singleton.d.ts.map +1 -1
  81. package/dest/lmdb/store.d.ts +11 -27
  82. package/dest/lmdb/store.d.ts.map +1 -1
  83. package/dest/lmdb/store.js +24 -40
  84. package/dest/lmdb-v2/array.d.ts +4 -3
  85. package/dest/lmdb-v2/array.d.ts.map +1 -1
  86. package/dest/lmdb-v2/array.js +4 -2
  87. package/dest/lmdb-v2/factory.d.ts +32 -10
  88. package/dest/lmdb-v2/factory.d.ts.map +1 -1
  89. package/dest/lmdb-v2/factory.js +83 -18
  90. package/dest/lmdb-v2/index.d.ts +1 -1
  91. package/dest/lmdb-v2/map.d.ts +12 -45
  92. package/dest/lmdb-v2/map.d.ts.map +1 -1
  93. package/dest/lmdb-v2/map.js +17 -104
  94. package/dest/lmdb-v2/message.d.ts +24 -5
  95. package/dest/lmdb-v2/message.d.ts.map +1 -1
  96. package/dest/lmdb-v2/message.js +6 -4
  97. package/dest/lmdb-v2/multi_map.d.ts +52 -0
  98. package/dest/lmdb-v2/multi_map.d.ts.map +1 -0
  99. package/dest/lmdb-v2/multi_map.js +123 -0
  100. package/dest/lmdb-v2/read_transaction.d.ts +3 -1
  101. package/dest/lmdb-v2/read_transaction.d.ts.map +1 -1
  102. package/dest/lmdb-v2/read_transaction.js +47 -11
  103. package/dest/lmdb-v2/set.d.ts +15 -0
  104. package/dest/lmdb-v2/set.d.ts.map +1 -0
  105. package/dest/lmdb-v2/set.js +23 -0
  106. package/dest/lmdb-v2/singleton.d.ts +2 -2
  107. package/dest/lmdb-v2/singleton.d.ts.map +1 -1
  108. package/dest/lmdb-v2/singleton.js +1 -1
  109. package/dest/lmdb-v2/store.d.ts +13 -13
  110. package/dest/lmdb-v2/store.d.ts.map +1 -1
  111. package/dest/lmdb-v2/store.js +22 -32
  112. package/dest/lmdb-v2/tx-helpers.d.ts +6 -0
  113. package/dest/lmdb-v2/tx-helpers.d.ts.map +1 -0
  114. package/dest/lmdb-v2/tx-helpers.js +21 -0
  115. package/dest/lmdb-v2/utils.d.ts +3 -14
  116. package/dest/lmdb-v2/utils.d.ts.map +1 -1
  117. package/dest/lmdb-v2/utils.js +0 -94
  118. package/dest/lmdb-v2/write_transaction.d.ts +3 -5
  119. package/dest/lmdb-v2/write_transaction.d.ts.map +1 -1
  120. package/dest/lmdb-v2/write_transaction.js +9 -5
  121. package/dest/sqlite-opfs/array.d.ts +21 -0
  122. package/dest/sqlite-opfs/array.d.ts.map +1 -0
  123. package/dest/sqlite-opfs/array.js +128 -0
  124. package/dest/sqlite-opfs/errors.d.ts +27 -0
  125. package/dest/sqlite-opfs/errors.d.ts.map +1 -0
  126. package/dest/sqlite-opfs/errors.js +34 -0
  127. package/dest/sqlite-opfs/index.d.ts +16 -0
  128. package/dest/sqlite-opfs/index.d.ts.map +1 -0
  129. package/dest/sqlite-opfs/index.js +22 -0
  130. package/dest/sqlite-opfs/internal/ordered-binary-browser.d.ts +32 -0
  131. package/dest/sqlite-opfs/internal/ordered-binary-browser.d.ts.map +1 -0
  132. package/dest/sqlite-opfs/internal/ordered-binary-browser.js +448 -0
  133. package/dest/sqlite-opfs/map.d.ts +35 -0
  134. package/dest/sqlite-opfs/map.d.ts.map +1 -0
  135. package/dest/sqlite-opfs/map.js +163 -0
  136. package/dest/sqlite-opfs/messages.d.ts +66 -0
  137. package/dest/sqlite-opfs/messages.d.ts.map +1 -0
  138. package/dest/sqlite-opfs/messages.js +5 -0
  139. package/dest/sqlite-opfs/multi_map.d.ts +16 -0
  140. package/dest/sqlite-opfs/multi_map.d.ts.map +1 -0
  141. package/dest/sqlite-opfs/multi_map.js +67 -0
  142. package/dest/sqlite-opfs/set.d.ts +13 -0
  143. package/dest/sqlite-opfs/set.d.ts.map +1 -0
  144. package/dest/sqlite-opfs/set.js +19 -0
  145. package/dest/sqlite-opfs/singleton.d.ts +13 -0
  146. package/dest/sqlite-opfs/singleton.d.ts.map +1 -0
  147. package/dest/sqlite-opfs/singleton.js +48 -0
  148. package/dest/sqlite-opfs/store.d.ts +79 -0
  149. package/dest/sqlite-opfs/store.d.ts.map +1 -0
  150. package/dest/sqlite-opfs/store.js +281 -0
  151. package/dest/sqlite-opfs/worker.d.ts +2 -0
  152. package/dest/sqlite-opfs/worker.d.ts.map +1 -0
  153. package/dest/sqlite-opfs/worker.js +249 -0
  154. package/dest/stores/index.d.ts +2 -1
  155. package/dest/stores/index.d.ts.map +1 -1
  156. package/dest/stores/index.js +1 -0
  157. package/dest/stores/l2_tips_store.d.ts +25 -9
  158. package/dest/stores/l2_tips_store.d.ts.map +1 -1
  159. package/dest/stores/l2_tips_store.js +64 -46
  160. package/dest/utils.d.ts +9 -6
  161. package/dest/utils.d.ts.map +1 -1
  162. package/dest/utils.js +51 -16
  163. package/package.json +44 -33
  164. package/src/bench/shared_map_bench.ts +111 -0
  165. package/src/indexeddb/array.ts +9 -5
  166. package/src/indexeddb/index.ts +11 -9
  167. package/src/indexeddb/map.ts +51 -56
  168. package/src/indexeddb/multi_map.ts +105 -0
  169. package/src/indexeddb/singleton.ts +5 -2
  170. package/src/indexeddb/store.ts +77 -60
  171. package/src/interfaces/array.ts +5 -3
  172. package/src/interfaces/array_test_suite.ts +33 -35
  173. package/src/interfaces/common.ts +20 -9
  174. package/src/interfaces/index.ts +3 -1
  175. package/src/interfaces/map.ts +19 -53
  176. package/src/interfaces/map_test_suite.ts +113 -58
  177. package/src/interfaces/multi_map.ts +45 -0
  178. package/src/interfaces/multi_map_test_suite.ts +372 -0
  179. package/src/interfaces/set_test_suite.ts +13 -15
  180. package/src/interfaces/singleton_test_suite.ts +6 -8
  181. package/src/interfaces/store.ts +18 -53
  182. package/src/interfaces/utils.ts +2 -0
  183. package/src/lmdb/array.ts +2 -1
  184. package/src/lmdb/index.ts +13 -8
  185. package/src/lmdb/map.ts +23 -94
  186. package/src/lmdb/multi_map.ts +51 -0
  187. package/src/lmdb/store.ts +36 -56
  188. package/src/lmdb-v2/array.ts +8 -3
  189. package/src/lmdb-v2/factory.ts +107 -26
  190. package/src/lmdb-v2/map.ts +30 -127
  191. package/src/lmdb-v2/message.ts +23 -0
  192. package/src/lmdb-v2/multi_map.ts +150 -0
  193. package/src/lmdb-v2/read_transaction.ts +53 -13
  194. package/src/lmdb-v2/set.ts +33 -0
  195. package/src/lmdb-v2/singleton.ts +6 -2
  196. package/src/lmdb-v2/store.ts +28 -44
  197. package/src/lmdb-v2/tx-helpers.ts +29 -0
  198. package/src/lmdb-v2/utils.ts +0 -118
  199. package/src/lmdb-v2/write_transaction.ts +11 -10
  200. package/src/sqlite-opfs/array.ts +124 -0
  201. package/src/sqlite-opfs/errors.ts +44 -0
  202. package/src/sqlite-opfs/index.ts +39 -0
  203. package/src/sqlite-opfs/internal/ordered-binary-browser.js +465 -0
  204. package/src/sqlite-opfs/map.ts +163 -0
  205. package/src/sqlite-opfs/messages.ts +39 -0
  206. package/src/sqlite-opfs/multi_map.ts +74 -0
  207. package/src/sqlite-opfs/set.ts +29 -0
  208. package/src/sqlite-opfs/singleton.ts +48 -0
  209. package/src/sqlite-opfs/store.ts +296 -0
  210. package/src/sqlite-opfs/worker.ts +231 -0
  211. package/src/stores/index.ts +2 -0
  212. package/src/stores/l2_tips_store.ts +68 -49
  213. package/src/utils.ts +79 -21
  214. package/dest/config.d.ts +0 -17
  215. package/dest/config.d.ts.map +0 -1
  216. package/dest/config.js +0 -24
  217. package/dest/interfaces/store_test_suite.d.ts +0 -3
  218. package/dest/interfaces/store_test_suite.d.ts.map +0 -1
  219. package/dest/interfaces/store_test_suite.js +0 -37
  220. package/src/config.ts +0 -34
  221. package/src/interfaces/store_test_suite.ts +0 -56
package/README.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # KV Store
2
2
 
3
- The Aztec KV store is an implementation of a durable key-value database with a pluggable backend. The only supported backend right now is LMDB by using the [`lmdb-js` package](https://github.com/kriszyp/lmdb-js).
3
+ The Aztec KV store is an implementation of a durable key-value database with a pluggable backend. Four backends are available, each exposed as its own package entrypoint:
4
+
5
+ - `@aztec/kv-store/lmdb-v2`: server / Node. The current default for node components.
6
+ - `@aztec/kv-store/lmdb`: the legacy LMDB backend, backed by [`lmdb-js`](https://github.com/kriszyp/lmdb-js).
7
+ - `@aztec/kv-store/indexeddb`: browser, backed by IndexedDB.
8
+ - `@aztec/kv-store/sqlite-opfs`: browser, backed by SQLite over the Origin Private File System.
9
+
10
+ The backend is selected at import time. You import `createStore` (and friends) from the entrypoint you want.
4
11
 
5
12
  This package exports a number of primitive data structures that can be used to build domain-specific databases in each node component (e.g. a PXE database or an Archiver database). The data structures supported:
6
13
 
@@ -0,0 +1,19 @@
1
+ import type { Logger } from '@aztec/foundation/log';
2
+ import type { AztecAsyncKVStore } from '../interfaces/store.js';
3
+ /** One benchmark measurement. */
4
+ export type BenchResult = {
5
+ /** Benchmark name (includes the backend prefix for disambiguation). */
6
+ name: string;
7
+ value: number;
8
+ unit: 'ms' | 'us';
9
+ };
10
+ export type BenchReporter = (results: BenchResult[]) => void | Promise<void>;
11
+ /**
12
+ * Runs the standard Map benchmark suite against any `AztecAsyncKVStore` backend,
13
+ * populates `results`, and calls `reporter` in `afterAll`.
14
+ *
15
+ * Kept free of Node-only deps (`fs`, `path`) so the same runner works under
16
+ * vitest-browser for IndexedDB and SQLite-OPFS.
17
+ */
18
+ export declare function describeAztecMapBench(backendPrefix: string, getStore: () => Promise<AztecAsyncKVStore>, logger: Logger, reporter: BenchReporter): void;
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkX21hcF9iZW5jaC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2JlbmNoL3NoYXJlZF9tYXBfYmVuY2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFLcEQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUVoRSxpQ0FBaUM7QUFDakMsTUFBTSxNQUFNLFdBQVcsR0FBRztJQUN4Qix1RUFBdUU7SUFDdkUsSUFBSSxFQUFFLE1BQU0sQ0FBQztJQUNiLEtBQUssRUFBRSxNQUFNLENBQUM7SUFDZCxJQUFJLEVBQUUsSUFBSSxHQUFHLElBQUksQ0FBQztDQUNuQixDQUFDO0FBRUYsTUFBTSxNQUFNLGFBQWEsR0FBRyxDQUFDLE9BQU8sRUFBRSxXQUFXLEVBQUUsS0FBSyxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBRTdFOzs7Ozs7R0FNRztBQUNILHdCQUFnQixxQkFBcUIsQ0FDbkMsYUFBYSxFQUFFLE1BQU0sRUFDckIsUUFBUSxFQUFFLE1BQU0sT0FBTyxDQUFDLGlCQUFpQixDQUFDLEVBQzFDLE1BQU0sRUFBRSxNQUFNLEVBQ2QsUUFBUSxFQUFFLGFBQWEsUUFrRnhCIn0=
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared_map_bench.d.ts","sourceRoot":"","sources":["../../src/bench/shared_map_bench.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAKpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,iCAAiC;AACjC,MAAM,MAAM,WAAW,GAAG;IACxB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE7E;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,EAC1C,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,aAAa,QAkFxB"}
@@ -0,0 +1,91 @@
1
+ import { Timer } from '@aztec/foundation/timer';
2
+ /**
3
+ * Runs the standard Map benchmark suite against any `AztecAsyncKVStore` backend,
4
+ * populates `results`, and calls `reporter` in `afterAll`.
5
+ *
6
+ * Kept free of Node-only deps (`fs`, `path`) so the same runner works under
7
+ * vitest-browser for IndexedDB and SQLite-OPFS.
8
+ */ export function describeAztecMapBench(backendPrefix, getStore, logger, reporter) {
9
+ describe(`${backendPrefix} Map benchmarks`, ()=>{
10
+ let store;
11
+ let map;
12
+ const results = [];
13
+ const generateKeyValuePairs = (count, offset = 0)=>{
14
+ const keys = Array.from({
15
+ length: count
16
+ }, (_, i)=>`key-${i + offset}`);
17
+ const values = Array.from({
18
+ length: count
19
+ }, (_, i)=>`value-${i + offset}`);
20
+ return keys.map((key, i)=>({
21
+ key,
22
+ value: values[i]
23
+ }));
24
+ };
25
+ const record = (name, value, unit)=>{
26
+ results.push({
27
+ name: `${backendPrefix}/Map/${name}`,
28
+ value,
29
+ unit
30
+ });
31
+ };
32
+ beforeEach(async ()=>{
33
+ store = await getStore();
34
+ map = store.openMap('test');
35
+ });
36
+ afterEach(async ()=>{
37
+ await store.delete();
38
+ });
39
+ afterAll(async ()=>{
40
+ const pretty = results.map((r)=>`${r.name}: ${r.value.toFixed(2)} ${r.unit}`).join('\n');
41
+ logger.info(`\n${pretty}\n`);
42
+ await reporter(results);
43
+ });
44
+ it('adds individual values', async ()=>{
45
+ const pairs = generateKeyValuePairs(1000);
46
+ const timer = new Timer();
47
+ for (const pair of pairs){
48
+ await map.set(pair.key, pair.value);
49
+ }
50
+ record('Individual insertion', timer.ms() / pairs.length, 'ms');
51
+ });
52
+ it('adds batched values', async ()=>{
53
+ const batches = Array.from({
54
+ length: 100
55
+ }, (_, i)=>generateKeyValuePairs(1000, i * 1000));
56
+ const timer = new Timer();
57
+ for (const batch of batches){
58
+ await map.setMany(batch);
59
+ }
60
+ record(`Batch insertion of ${batches[0].length} items`, timer.ms() / batches.length, 'ms');
61
+ });
62
+ it('reads individual values', async ()=>{
63
+ const pairs = generateKeyValuePairs(10000);
64
+ await map.setMany(pairs);
65
+ const timer = new Timer();
66
+ for (const pair of pairs){
67
+ await map.getAsync(pair.key);
68
+ }
69
+ record('Individual read', timer.ms() * 1000 / pairs.length, 'us');
70
+ });
71
+ it('reads via a cursor', async ()=>{
72
+ const pairs = generateKeyValuePairs(10000);
73
+ await map.setMany(pairs);
74
+ const timer = new Timer();
75
+ for await (const _ of map.entriesAsync()){
76
+ // consume
77
+ }
78
+ record(`Iterator per item read of ${pairs.length} items`, timer.ms() * 1000 / pairs.length, 'us');
79
+ });
80
+ it('reads the size of the map', async ()=>{
81
+ const numIterations = 1000;
82
+ const pairs = generateKeyValuePairs(10000);
83
+ await map.setMany(pairs);
84
+ const timer = new Timer();
85
+ for(let i = 0; i < numIterations; i++){
86
+ await map.sizeAsync();
87
+ }
88
+ record(`Read size of ${pairs.length} items`, timer.ms() * 1000 / numIterations, 'us');
89
+ });
90
+ });
91
+ }
@@ -1,10 +1,11 @@
1
1
  import type { IDBPDatabase, IDBPObjectStore } from 'idb';
2
2
  import type { AztecAsyncArray } from '../interfaces/array.js';
3
+ import type { Value } from '../interfaces/common.js';
3
4
  import type { AztecIDBSchema } from './store.js';
4
5
  /**
5
6
  * A persistent array backed by IndexedDB.
6
7
  */
7
- export declare class IndexedDBAztecArray<T> implements AztecAsyncArray<T> {
8
+ export declare class IndexedDBAztecArray<T extends Value> implements AztecAsyncArray<T> {
8
9
  #private;
9
10
  constructor(rootDB: IDBPDatabase<AztecIDBSchema>, name: string);
10
11
  set db(db: IDBPObjectStore<AztecIDBSchema, ['data'], 'data', 'readwrite'> | undefined);
@@ -18,4 +19,4 @@ export declare class IndexedDBAztecArray<T> implements AztecAsyncArray<T> {
18
19
  valuesAsync(): AsyncIterableIterator<T>;
19
20
  [Symbol.asyncIterator](): AsyncIterableIterator<T>;
20
21
  }
21
- //# sourceMappingURL=array.d.ts.map
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXkuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9pbmRleGVkZGIvYXJyYXkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUd6RCxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM5RCxPQUFPLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRCxPQUFPLEtBQUssRUFBRSxjQUFjLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFakQ7O0dBRUc7QUFDSCxxQkFBYSxtQkFBbUIsQ0FBQyxDQUFDLFNBQVMsS0FBSyxDQUFFLFlBQVcsZUFBZSxDQUFDLENBQUMsQ0FBQzs7SUFNN0UsWUFBWSxNQUFNLEVBQUUsWUFBWSxDQUFDLGNBQWMsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBSTdEO0lBRUQsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLGVBQWUsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLEdBQUcsU0FBUyxFQUVwRjtJQUVELElBQUksRUFBRSxJQUFJLGVBQWUsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLENBRXZFO0lBRUssV0FBVyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FNbkM7SUFFSyxJQUFJLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQWN4QztJQUVLLEdBQUcsSUFBSSxPQUFPLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQVdsQztJQUVLLE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBU25EO0lBRUssS0FBSyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBb0JuRDtJQUVNLFlBQVksSUFBSSxxQkFBcUIsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQU14RDtJQUVNLFdBQVcsSUFBSSxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FJN0M7SUFFRCxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBSSxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FFakQ7Q0FLRiJ9
@@ -1 +1 @@
1
- {"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src/indexeddb/array.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAEzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;GAEG;AACH,qBAAa,mBAAmB,CAAC,CAAC,CAAE,YAAW,eAAe,CAAC,CAAC,CAAC;;gBAMnD,MAAM,EAAE,YAAY,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM;IAM9D,IAAI,EAAE,CAAC,EAAE,EAAE,eAAe,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,GAAG,SAAS,EAEpF;IAED,IAAI,EAAE,IAAI,eAAe,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAEvE;IAEK,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAQ9B,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAenC,GAAG,IAAI,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAa7B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAW9C,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAqB7C,YAAY,IAAI,qBAAqB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAQlD,WAAW,IAAI,qBAAqB,CAAC,CAAC,CAAC;IAM9C,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,CAAC,CAAC;CAOnD"}
1
+ {"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src/indexeddb/array.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAGzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;GAEG;AACH,qBAAa,mBAAmB,CAAC,CAAC,SAAS,KAAK,CAAE,YAAW,eAAe,CAAC,CAAC,CAAC;;IAM7E,YAAY,MAAM,EAAE,YAAY,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAI7D;IAED,IAAI,EAAE,CAAC,EAAE,EAAE,eAAe,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,GAAG,SAAS,EAEpF;IAED,IAAI,EAAE,IAAI,eAAe,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAEvE;IAEK,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAMnC;IAEK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAcxC;IAEK,GAAG,IAAI,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAWlC;IAEK,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CASnD;IAEK,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAoBnD;IAEM,YAAY,IAAI,qBAAqB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAMxD;IAEM,WAAW,IAAI,qBAAqB,CAAC,CAAC,CAAC,CAI7C;IAED,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,CAAC,CAAC,CAEjD;CAKF"}
@@ -1,3 +1,6 @@
1
+ var _computedKey;
2
+ import { hash } from 'ohash';
3
+ _computedKey = Symbol.asyncIterator;
1
4
  /**
2
5
  * A persistent array backed by IndexedDB.
3
6
  */ export class IndexedDBAztecArray {
@@ -19,10 +22,14 @@
19
22
  async lengthAsync() {
20
23
  return await this.db.index('key').count(IDBKeyRange.bound([
21
24
  this.#container,
22
- this.#name
25
+ [
26
+ this.#name
27
+ ]
23
28
  ], [
24
29
  this.#container,
25
- this.#name
30
+ [
31
+ this.#name
32
+ ]
26
33
  ])) ?? 0;
27
34
  }
28
35
  async push(...vals) {
@@ -30,8 +37,11 @@
30
37
  for (const val of vals){
31
38
  await this.db.put({
32
39
  value: val,
40
+ hash: hash(val),
33
41
  container: this.#container,
34
- key: this.#name,
42
+ key: [
43
+ this.#name
44
+ ],
35
45
  keyCount: length + 1,
36
46
  slot: this.#slot(length)
37
47
  });
@@ -67,8 +77,11 @@
67
77
  }
68
78
  await this.db.put({
69
79
  value: val,
80
+ hash: hash(val),
70
81
  container: this.#container,
71
- key: this.#name,
82
+ key: [
83
+ this.#name
84
+ ],
72
85
  keyCount: index + 1,
73
86
  slot: this.#slot(index)
74
87
  });
@@ -78,10 +91,14 @@
78
91
  const index = this.db.index('key');
79
92
  const rangeQuery = IDBKeyRange.bound([
80
93
  this.#container,
81
- this.#name
94
+ [
95
+ this.#name
96
+ ]
82
97
  ], [
83
98
  this.#container,
84
- this.#name
99
+ [
100
+ this.#name
101
+ ]
85
102
  ]);
86
103
  for await (const cursor of index.iterate(rangeQuery)){
87
104
  yield [
@@ -95,7 +112,7 @@
95
112
  yield value;
96
113
  }
97
114
  }
98
- [Symbol.asyncIterator]() {
115
+ [_computedKey]() {
99
116
  return this.valuesAsync();
100
117
  }
101
118
  #slot(index) {
@@ -1,7 +1,7 @@
1
1
  import { type Logger } from '@aztec/foundation/log';
2
- import type { DataStoreConfig } from '../config.js';
2
+ import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
3
3
  import { AztecIndexedDBStore } from './store.js';
4
4
  export { AztecIndexedDBStore } from './store.js';
5
- export declare function createStore(name: string, config: DataStoreConfig, log?: Logger): Promise<AztecIndexedDBStore>;
5
+ export declare function createStore(name: string, config: DataStoreConfig, schemaVersion?: number | undefined, log?: Logger): Promise<AztecIndexedDBStore>;
6
6
  export declare function openTmpStore(ephemeral?: boolean): Promise<AztecIndexedDBStore>;
7
- //# sourceMappingURL=index.d.ts.map
7
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9pbmRleGVkZGIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBQ2xFLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRzlELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUVqRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFakQsd0JBQXNCLFdBQVcsQ0FDL0IsSUFBSSxFQUFFLE1BQU0sRUFDWixNQUFNLEVBQUUsZUFBZSxFQUN2QixhQUFhLEdBQUUsTUFBTSxHQUFHLFNBQXFCLEVBQzdDLEdBQUcsR0FBRSxNQUFpQyxnQ0FjdkM7QUFFRCx3QkFBZ0IsWUFBWSxDQUFDLFNBQVMsR0FBRSxPQUFlLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBRXJGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/indexeddb/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAElE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,GAAE,MAAiC,gCAgB9G;AAED,wBAAgB,YAAY,CAAC,SAAS,GAAE,OAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAErF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/indexeddb/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,eAAe,EACvB,aAAa,GAAE,MAAM,GAAG,SAAqB,EAC7C,GAAG,GAAE,MAAiC,gCAcvC;AAED,wBAAgB,YAAY,CAAC,SAAS,GAAE,OAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAErF"}
@@ -1,18 +1,15 @@
1
1
  import { createLogger } from '@aztec/foundation/log';
2
- import { initStoreForRollup } from '../utils.js';
2
+ import { initStoreForRollupAndSchemaVersion } from '../utils.js';
3
3
  import { AztecIndexedDBStore } from './store.js';
4
4
  export { AztecIndexedDBStore } from './store.js';
5
- export async function createStore(name, config, log = createLogger('kv-store')) {
5
+ export async function createStore(name, config, schemaVersion = undefined, log = createLogger('kv-store')) {
6
6
  let { dataDirectory } = config;
7
7
  if (typeof dataDirectory !== 'undefined') {
8
8
  dataDirectory = `${dataDirectory}/${name}`;
9
9
  }
10
- log.info(dataDirectory ? `Creating ${name} data store at directory ${dataDirectory} with map size ${config.dataStoreMapSizeKB} KB` : `Creating ${name} ephemeral data store with map size ${config.dataStoreMapSizeKB} KB`);
10
+ log.info(dataDirectory ? `Creating ${name} data store at directory ${dataDirectory} with map size ${config.dataStoreMapSizeKb} KB` : `Creating ${name} ephemeral data store with map size ${config.dataStoreMapSizeKb} KB`);
11
11
  const store = await AztecIndexedDBStore.open(createLogger('kv-store:indexeddb'), dataDirectory ?? '', false);
12
- if (config.l1Contracts?.rollupAddress) {
13
- return initStoreForRollup(store, config.l1Contracts.rollupAddress, log);
14
- }
15
- return store;
12
+ return initStoreForRollupAndSchemaVersion(store, schemaVersion, config.rollupAddress, log);
16
13
  }
17
14
  export function openTmpStore(ephemeral = false) {
18
15
  return AztecIndexedDBStore.open(createLogger('kv-store:indexeddb'), undefined, ephemeral);
@@ -1,26 +1,38 @@
1
1
  import type { IDBPDatabase, IDBPObjectStore } from 'idb';
2
- import type { Key, Range } from '../interfaces/common.js';
3
- import type { AztecAsyncMultiMap } from '../interfaces/map.js';
2
+ import type { Key, Range, Value } from '../interfaces/common.js';
3
+ import type { AztecAsyncMap } from '../interfaces/map.js';
4
4
  import type { AztecIDBSchema } from './store.js';
5
5
  /**
6
6
  * A map backed by IndexedDB.
7
7
  */
8
- export declare class IndexedDBAztecMap<K extends Key, V> implements AztecAsyncMultiMap<K, V> {
8
+ export declare class IndexedDBAztecMap<K extends Key, V extends Value> implements AztecAsyncMap<K, V> {
9
9
  #private;
10
10
  protected name: string;
11
+ protected container: string;
11
12
  constructor(rootDB: IDBPDatabase<AztecIDBSchema>, mapName: string);
12
13
  set db(db: IDBPObjectStore<AztecIDBSchema, ['data'], 'data', 'readwrite'> | undefined);
13
14
  get db(): IDBPObjectStore<AztecIDBSchema, ['data'], 'data', 'readwrite'>;
14
15
  getAsync(key: K): Promise<V | undefined>;
15
- getValuesAsync(key: K): AsyncIterableIterator<V>;
16
16
  hasAsync(key: K): Promise<boolean>;
17
+ sizeAsync(): Promise<number>;
17
18
  set(key: K, val: V): Promise<void>;
19
+ setMany(entries: {
20
+ key: K;
21
+ value: V;
22
+ }[]): Promise<void>;
18
23
  swap(_key: K, _fn: (val: V | undefined) => V): Promise<void>;
19
24
  setIfNotExists(key: K, val: V): Promise<boolean>;
20
25
  delete(key: K): Promise<void>;
21
- deleteValue(key: K, val: V): Promise<void>;
22
26
  entriesAsync(range?: Range<K>): AsyncIterableIterator<[K, V]>;
23
27
  valuesAsync(range?: Range<K>): AsyncIterableIterator<V>;
24
28
  keysAsync(range?: Range<K>): AsyncIterableIterator<K>;
29
+ /**
30
+ * IndexedDB's structured clone downcasts Buffer (a Node.js subclass of Uint8Array) to plain Uint8Array.
31
+ * This breaks .toString() behavior: Buffer.toString() returns UTF-8, Uint8Array.toString() returns
32
+ * comma-separated decimal bytes. We restore Buffer identity on read so callers get consistent behavior.
33
+ */
34
+ protected restoreBuffers(val: V): V;
35
+ protected normalizeKey(key: K): (string | number | Uint8Array)[];
36
+ protected slot(key: K, index?: number): string;
25
37
  }
26
- //# sourceMappingURL=map.d.ts.map
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXhlZGRiL21hcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBR3pELE9BQU8sS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDakUsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDMUQsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRWpEOztHQUVHO0FBQ0gscUJBQWEsaUJBQWlCLENBQUMsQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDLFNBQVMsS0FBSyxDQUFFLFlBQVcsYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7O0lBQzNGLFNBQVMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ3ZCLFNBQVMsQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDO0lBSzVCLFlBQVksTUFBTSxFQUFFLFlBQVksQ0FBQyxjQUFjLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUloRTtJQUVELElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxlQUFlLENBQUMsY0FBYyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxHQUFHLFNBQVMsRUFFcEY7SUFFRCxJQUFJLEVBQUUsSUFBSSxlQUFlLENBQUMsY0FBYyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUV2RTtJQUVLLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBRzdDO0lBRUssUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUd2QztJQUVLLFNBQVMsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLENBSWpDO0lBRUssR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBU3ZDO0lBRUssT0FBTyxDQUFDLE9BQU8sRUFBRTtRQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFBQyxLQUFLLEVBQUUsQ0FBQyxDQUFBO0tBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FJNUQ7SUFFRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLFNBQVMsS0FBSyxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUUzRDtJQUVLLGNBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQU1yRDtJQUVLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFbEM7SUFFTSxZQUFZLENBQUMsS0FBSyxHQUFFLEtBQUssQ0FBQyxDQUFDLENBQU0sR0FBRyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQW1CdkU7SUFFTSxXQUFXLENBQUMsS0FBSyxHQUFFLEtBQUssQ0FBQyxDQUFDLENBQU0sR0FBRyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FJakU7SUFFTSxTQUFTLENBQUMsS0FBSyxHQUFFLEtBQUssQ0FBQyxDQUFDLENBQU0sR0FBRyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FJL0Q7SUFFRDs7OztPQUlHO0lBQ0gsU0FBUyxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FLbEM7SUFNRCxTQUFTLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsTUFBTSxHQUFHLFVBQVUsQ0FBQyxFQUFFLENBRS9EO0lBRUQsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEtBQUssR0FBRSxNQUFVLEdBQUcsTUFBTSxDQUVoRDtDQUNGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/indexeddb/map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAEzD,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;GAEG;AACH,qBAAa,iBAAiB,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,CAAE,YAAW,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC;;IAClF,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;gBAMX,MAAM,EAAE,YAAY,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,MAAM;IAMjE,IAAI,EAAE,CAAC,EAAE,EAAE,eAAe,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,GAAG,SAAS,EAEpF;IAED,IAAI,EAAE,IAAI,eAAe,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAEvE;IAEK,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAKvC,cAAc,CAAC,GAAG,EAAE,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC;IAajD,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAKlC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAaxC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,SAAS,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAQhD,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7B,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBzC,YAAY,CAAC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAkBjE,WAAW,CAAC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC;IAM3D,SAAS,CAAC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC;CAmBjE"}
1
+ {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/indexeddb/map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAGzD,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;GAEG;AACH,qBAAa,iBAAiB,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,KAAK,CAAE,YAAW,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;;IAC3F,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;IAK5B,YAAY,MAAM,EAAE,YAAY,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,MAAM,EAIhE;IAED,IAAI,EAAE,CAAC,EAAE,EAAE,eAAe,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,GAAG,SAAS,EAEpF;IAED,IAAI,EAAE,IAAI,eAAe,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAEvE;IAEK,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAG7C;IAEK,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAGvC;IAEK,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAIjC;IAEK,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CASvC;IAEK,OAAO,CAAC,OAAO,EAAE;QAAE,GAAG,EAAE,CAAC,CAAC;QAAC,KAAK,EAAE,CAAC,CAAA;KAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAI5D;IAED,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,SAAS,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3D;IAEK,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAMrD;IAEK,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAElC;IAEM,YAAY,CAAC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAmBvE;IAEM,WAAW,CAAC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAIjE;IAEM,SAAS,CAAC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAI/D;IAED;;;;OAIG;IACH,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAKlC;IAMD,SAAS,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC,EAAE,CAE/D;IAED,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,GAAE,MAAU,GAAG,MAAM,CAEhD;CACF"}
@@ -1,13 +1,14 @@
1
+ import { hash } from 'ohash';
1
2
  /**
2
3
  * A map backed by IndexedDB.
3
4
  */ export class IndexedDBAztecMap {
4
5
  name;
5
- #container;
6
+ container;
6
7
  #_db;
7
8
  #rootDB;
8
9
  constructor(rootDB, mapName){
9
10
  this.name = mapName;
10
- this.#container = `map:${mapName}`;
11
+ this.container = `map:${mapName}`;
11
12
  this.#rootDB = rootDB;
12
13
  }
13
14
  set db(db) {
@@ -17,44 +18,37 @@
17
18
  return this.#_db ? this.#_db : this.#rootDB.transaction('data', 'readwrite').store;
18
19
  }
19
20
  async getAsync(key) {
20
- const data = await this.db.get(this.#slot(key));
21
- return data?.value;
22
- }
23
- async *getValuesAsync(key) {
24
- const index = this.db.index('keyCount');
25
- const rangeQuery = IDBKeyRange.bound([
26
- this.#container,
27
- this.#normalizeKey(key),
28
- 0
29
- ], [
30
- this.#container,
31
- this.#normalizeKey(key),
32
- Number.MAX_SAFE_INTEGER
33
- ], false, false);
34
- for await (const cursor of index.iterate(rangeQuery)){
35
- yield cursor.value.value;
36
- }
21
+ const data = await this.db.get(this.slot(key));
22
+ return data ? this.restoreBuffers(data.value) : undefined;
37
23
  }
38
24
  async hasAsync(key) {
39
25
  const result = await this.getAsync(key) !== undefined;
40
26
  return result;
41
27
  }
42
- async set(key, val) {
43
- const count = await this.db.index('key').count(IDBKeyRange.bound([
44
- this.#container,
45
- this.#normalizeKey(key)
28
+ async sizeAsync() {
29
+ const index = this.db.index('key');
30
+ const rangeQuery = IDBKeyRange.bound([
31
+ this.container
46
32
  ], [
47
- this.#container,
48
- this.#normalizeKey(key)
49
- ]));
33
+ this.container + '\uffff'
34
+ ], true, true);
35
+ return await index.count(rangeQuery);
36
+ }
37
+ async set(key, val) {
50
38
  await this.db.put({
51
39
  value: val,
52
- container: this.#container,
53
- key: this.#normalizeKey(key),
54
- keyCount: count + 1,
55
- slot: this.#slot(key, count)
40
+ hash: hash(val),
41
+ container: this.container,
42
+ key: this.normalizeKey(key),
43
+ keyCount: 1,
44
+ slot: this.slot(key)
56
45
  });
57
46
  }
47
+ async setMany(entries) {
48
+ for (const { key, value } of entries){
49
+ await this.set(key, value);
50
+ }
51
+ }
58
52
  swap(_key, _fn) {
59
53
  throw new Error('Not implemented');
60
54
  }
@@ -66,34 +60,20 @@
66
60
  return false;
67
61
  }
68
62
  async delete(key) {
69
- await this.db.delete(this.#slot(key));
70
- }
71
- async deleteValue(key, val) {
72
- const index = this.db.index('keyCount');
73
- const rangeQuery = IDBKeyRange.bound([
74
- this.#container,
75
- this.#normalizeKey(key),
76
- 0
77
- ], [
78
- this.#container,
79
- this.#normalizeKey(key),
80
- Number.MAX_SAFE_INTEGER
81
- ], false, false);
82
- for await (const cursor of index.iterate(rangeQuery)){
83
- if (JSON.stringify(cursor.value.value) === JSON.stringify(val)) {
84
- await cursor.delete();
85
- return;
86
- }
87
- }
63
+ await this.db.delete(this.slot(key));
88
64
  }
89
65
  async *entriesAsync(range = {}) {
90
66
  const index = this.db.index('key');
67
+ const startKey = range.start ? this.normalizeKey(range.start) : [];
68
+ const endKey = range.end ? this.normalizeKey(range.end) : [
69
+ '\uffff'
70
+ ];
91
71
  const rangeQuery = IDBKeyRange.bound([
92
- this.#container,
93
- range.start ?? ''
72
+ this.container,
73
+ startKey
94
74
  ], [
95
- this.#container,
96
- range.end ?? '\uffff'
75
+ this.container,
76
+ endKey
97
77
  ], !!range.reverse, !range.reverse);
98
78
  let count = 0;
99
79
  for await (const cursor of index.iterate(rangeQuery, range.reverse ? 'prev' : 'next')){
@@ -101,8 +81,8 @@
101
81
  return;
102
82
  }
103
83
  yield [
104
- cursor.value.key,
105
- cursor.value.value
84
+ this.#denormalizeKey(cursor.value.key),
85
+ this.restoreBuffers(cursor.value.value)
106
86
  ];
107
87
  count++;
108
88
  }
@@ -114,20 +94,28 @@
114
94
  }
115
95
  async *keysAsync(range = {}) {
116
96
  for await (const [key, _] of this.entriesAsync(range)){
117
- yield this.#denormalizeKey(key);
97
+ yield key;
98
+ }
99
+ }
100
+ /**
101
+ * IndexedDB's structured clone downcasts Buffer (a Node.js subclass of Uint8Array) to plain Uint8Array.
102
+ * This breaks .toString() behavior: Buffer.toString() returns UTF-8, Uint8Array.toString() returns
103
+ * comma-separated decimal bytes. We restore Buffer identity on read so callers get consistent behavior.
104
+ */ restoreBuffers(val) {
105
+ if (val instanceof Uint8Array && !Buffer.isBuffer(val)) {
106
+ return Buffer.from(val);
118
107
  }
108
+ return val;
119
109
  }
120
110
  #denormalizeKey(key) {
121
- const denormalizedKey = key.split(',').map((part)=>isNaN(parseInt(part)) ? part : parseInt(part));
122
- return denormalizedKey.length > 1 ? denormalizedKey : key;
111
+ return key.length > 1 ? key : key[0];
123
112
  }
124
- #normalizeKey(key) {
125
- const arrayKey = Array.isArray(key) ? key : [
113
+ normalizeKey(key) {
114
+ return Array.isArray(key) ? key : [
126
115
  key
127
116
  ];
128
- return arrayKey.join(',');
129
117
  }
130
- #slot(key, index = 0) {
131
- return `map:${this.name}:slot:${this.#normalizeKey(key)}:${index}`;
118
+ slot(key, index = 0) {
119
+ return `map:${this.name}:slot:${this.normalizeKey(key)}:${index}`;
132
120
  }
133
121
  }
@@ -0,0 +1,14 @@
1
+ import type { Key, Value } from '../interfaces/common.js';
2
+ import type { AztecAsyncMultiMap } from '../interfaces/multi_map.js';
3
+ import { IndexedDBAztecMap } from './map.js';
4
+ /**
5
+ * A multi map backed by IndexedDB.
6
+ */
7
+ export declare class IndexedDBAztecMultiMap<K extends Key, V extends Value> extends IndexedDBAztecMap<K, V> implements AztecAsyncMultiMap<K, V> {
8
+ set(key: K, val: V): Promise<void>;
9
+ getValuesAsync(key: K): AsyncIterableIterator<V>;
10
+ getValueCountAsync(key: K): Promise<number>;
11
+ deleteValue(key: K, val: V): Promise<void>;
12
+ delete(key: K): Promise<void>;
13
+ }
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGlfbWFwLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXhlZGRiL211bHRpX21hcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDMUQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNyRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFN0M7O0dBRUc7QUFDSCxxQkFBYSxzQkFBc0IsQ0FBQyxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUMsU0FBUyxLQUFLLENBQ2hFLFNBQVEsaUJBQWlCLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FDOUIsWUFBVyxrQkFBa0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRXBCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQWtDaEQ7SUFFTSxjQUFjLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FZdEQ7SUFFRCxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FVMUM7SUFFSyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FjL0M7SUFFYyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBWTNDO0NBQ0YifQ==
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi_map.d.ts","sourceRoot":"","sources":["../../src/indexeddb/multi_map.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C;;GAEG;AACH,qBAAa,sBAAsB,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,KAAK,CAChE,SAAQ,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAC9B,YAAW,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC;IAEpB,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAkChD;IAEM,cAAc,CAAC,GAAG,EAAE,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAYtD;IAED,kBAAkB,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAU1C;IAEK,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAc/C;IAEc,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAY3C;CACF"}
@@ -0,0 +1,107 @@
1
+ import { hash } from 'ohash';
2
+ import { IndexedDBAztecMap } from './map.js';
3
+ /**
4
+ * A multi map backed by IndexedDB.
5
+ */ export class IndexedDBAztecMultiMap extends IndexedDBAztecMap {
6
+ async set(key, val) {
7
+ // Inserting repeated values is a no-op
8
+ const exists = !!await this.db.index('hash').get(IDBKeyRange.bound([
9
+ this.container,
10
+ this.normalizeKey(key),
11
+ hash(val)
12
+ ], [
13
+ this.container,
14
+ this.normalizeKey(key),
15
+ hash(val)
16
+ ]));
17
+ if (exists) {
18
+ return;
19
+ }
20
+ // Get the maximum keyCount for the given key
21
+ // In order to support sparse multimaps, we cannot rely
22
+ // on just counting the number of entries for the key, since we would repeat slots
23
+ // if we delete an entry
24
+ // set -> container:key:0 (keyCount = 1)
25
+ // set -> container:key:1 (keyCount = 2)
26
+ // delete -> container:key:0 (keyCount = 1)
27
+ // set -> container:key:1 <--- already exists!
28
+ // Instead, we iterate in reverse order to get the last inserted entry
29
+ const index = this.db.index('keyCount');
30
+ const rangeQuery = IDBKeyRange.upperBound([
31
+ this.container,
32
+ this.normalizeKey(key),
33
+ Number.MAX_SAFE_INTEGER
34
+ ]);
35
+ const maxEntry = (await index.iterate(rangeQuery, 'prevunique').next()).value;
36
+ const count = maxEntry?.value?.keyCount ?? 0;
37
+ await this.db.put({
38
+ value: val,
39
+ hash: hash(val),
40
+ container: this.container,
41
+ key: this.normalizeKey(key),
42
+ keyCount: count + 1,
43
+ slot: this.slot(key, count)
44
+ });
45
+ }
46
+ async *getValuesAsync(key) {
47
+ // Iterate over the whole range of keyCount for the given key
48
+ const index = this.db.index('keyCount');
49
+ const rangeQuery = IDBKeyRange.bound([
50
+ this.container,
51
+ this.normalizeKey(key),
52
+ 0
53
+ ], [
54
+ this.container,
55
+ this.normalizeKey(key),
56
+ Number.MAX_SAFE_INTEGER
57
+ ], false, false);
58
+ for await (const cursor of index.iterate(rangeQuery)){
59
+ yield this.restoreBuffers(cursor.value.value);
60
+ }
61
+ }
62
+ getValueCountAsync(key) {
63
+ // Count entries over the keyCount index range for this key
64
+ const index = this.db.index('keyCount');
65
+ const rangeQuery = IDBKeyRange.bound([
66
+ this.container,
67
+ this.normalizeKey(key),
68
+ 0
69
+ ], [
70
+ this.container,
71
+ this.normalizeKey(key),
72
+ Number.MAX_SAFE_INTEGER
73
+ ], false, false);
74
+ return index.count(rangeQuery);
75
+ }
76
+ async deleteValue(key, val) {
77
+ // Since we know the value, we can hash it and directly query the "hash" index
78
+ // to avoid having to iterate over all the values
79
+ const fullKey = await this.db.index('hash').getKey(IDBKeyRange.bound([
80
+ this.container,
81
+ this.normalizeKey(key),
82
+ hash(val)
83
+ ], [
84
+ this.container,
85
+ this.normalizeKey(key),
86
+ hash(val)
87
+ ]));
88
+ if (fullKey) {
89
+ await this.db.delete(fullKey);
90
+ }
91
+ }
92
+ async delete(key) {
93
+ const index = this.db.index('keyCount');
94
+ const rangeQuery = IDBKeyRange.bound([
95
+ this.container,
96
+ this.normalizeKey(key),
97
+ 0
98
+ ], [
99
+ this.container,
100
+ this.normalizeKey(key),
101
+ Number.MAX_SAFE_INTEGER
102
+ ], false, false);
103
+ for await (const cursor of index.iterate(rangeQuery)){
104
+ await cursor.delete();
105
+ }
106
+ }
107
+ }