@aztec/kv-store 0.0.0-test.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/README.md +10 -0
  2. package/dest/config.d.ts +17 -0
  3. package/dest/config.d.ts.map +1 -0
  4. package/dest/config.js +24 -0
  5. package/dest/indexeddb/array.d.ts +21 -0
  6. package/dest/indexeddb/array.d.ts.map +1 -0
  7. package/dest/indexeddb/array.js +104 -0
  8. package/dest/indexeddb/index.d.ts +7 -0
  9. package/dest/indexeddb/index.d.ts.map +1 -0
  10. package/dest/indexeddb/index.js +19 -0
  11. package/dest/indexeddb/map.d.ts +26 -0
  12. package/dest/indexeddb/map.d.ts.map +1 -0
  13. package/dest/indexeddb/map.js +133 -0
  14. package/dest/indexeddb/set.d.ts +17 -0
  15. package/dest/indexeddb/set.d.ts.map +1 -0
  16. package/dest/indexeddb/set.js +24 -0
  17. package/dest/indexeddb/singleton.d.ts +16 -0
  18. package/dest/indexeddb/singleton.d.ts.map +1 -0
  19. package/dest/indexeddb/singleton.js +37 -0
  20. package/dest/indexeddb/store.d.ts +97 -0
  21. package/dest/indexeddb/store.d.ts.map +1 -0
  22. package/dest/indexeddb/store.js +164 -0
  23. package/dest/interfaces/array.d.ts +80 -0
  24. package/dest/interfaces/array.d.ts.map +1 -0
  25. package/dest/interfaces/array.js +3 -0
  26. package/dest/interfaces/array_test_suite.d.ts +3 -0
  27. package/dest/interfaces/array_test_suite.d.ts.map +1 -0
  28. package/dest/interfaces/array_test_suite.js +104 -0
  29. package/dest/interfaces/common.d.ts +23 -0
  30. package/dest/interfaces/common.d.ts.map +1 -0
  31. package/dest/interfaces/common.js +3 -0
  32. package/dest/interfaces/counter.d.ts +59 -0
  33. package/dest/interfaces/counter.d.ts.map +1 -0
  34. package/dest/interfaces/counter.js +1 -0
  35. package/dest/interfaces/index.d.ts +8 -0
  36. package/dest/interfaces/index.d.ts.map +1 -0
  37. package/dest/interfaces/index.js +6 -0
  38. package/dest/interfaces/map.d.ts +134 -0
  39. package/dest/interfaces/map.d.ts.map +1 -0
  40. package/dest/interfaces/map.js +3 -0
  41. package/dest/interfaces/map_test_suite.d.ts +3 -0
  42. package/dest/interfaces/map_test_suite.d.ts.map +1 -0
  43. package/dest/interfaces/map_test_suite.js +151 -0
  44. package/dest/interfaces/set.d.ts +44 -0
  45. package/dest/interfaces/set.d.ts.map +1 -0
  46. package/dest/interfaces/set.js +1 -0
  47. package/dest/interfaces/set_test_suite.d.ts +3 -0
  48. package/dest/interfaces/set_test_suite.d.ts.map +1 -0
  49. package/dest/interfaces/set_test_suite.js +96 -0
  50. package/dest/interfaces/singleton.d.ts +29 -0
  51. package/dest/interfaces/singleton.d.ts.map +1 -0
  52. package/dest/interfaces/singleton.js +4 -0
  53. package/dest/interfaces/singleton_test_suite.d.ts +3 -0
  54. package/dest/interfaces/singleton_test_suite.d.ts.map +1 -0
  55. package/dest/interfaces/singleton_test_suite.js +30 -0
  56. package/dest/interfaces/store.d.ts +145 -0
  57. package/dest/interfaces/store.d.ts.map +1 -0
  58. package/dest/interfaces/store.js +1 -0
  59. package/dest/interfaces/store_test_suite.d.ts +3 -0
  60. package/dest/interfaces/store_test_suite.d.ts.map +1 -0
  61. package/dest/interfaces/store_test_suite.js +37 -0
  62. package/dest/interfaces/utils.d.ts +16 -0
  63. package/dest/interfaces/utils.d.ts.map +1 -0
  64. package/dest/interfaces/utils.js +16 -0
  65. package/dest/lmdb/array.d.ts +23 -0
  66. package/dest/lmdb/array.d.ts.map +1 -0
  67. package/dest/lmdb/array.js +117 -0
  68. package/dest/lmdb/counter.d.ts +19 -0
  69. package/dest/lmdb/counter.d.ts.map +1 -0
  70. package/dest/lmdb/counter.js +50 -0
  71. package/dest/lmdb/index.d.ts +12 -0
  72. package/dest/lmdb/index.d.ts.map +1 -0
  73. package/dest/lmdb/index.js +25 -0
  74. package/dest/lmdb/map.d.ts +52 -0
  75. package/dest/lmdb/map.d.ts.map +1 -0
  76. package/dest/lmdb/map.js +222 -0
  77. package/dest/lmdb/set.d.ts +18 -0
  78. package/dest/lmdb/set.d.ts.map +1 -0
  79. package/dest/lmdb/set.js +32 -0
  80. package/dest/lmdb/singleton.d.ts +14 -0
  81. package/dest/lmdb/singleton.d.ts.map +1 -0
  82. package/dest/lmdb/singleton.js +26 -0
  83. package/dest/lmdb/store.d.ts +110 -0
  84. package/dest/lmdb/store.d.ts.map +1 -0
  85. package/dest/lmdb/store.js +216 -0
  86. package/dest/lmdb-v2/array.d.ts +18 -0
  87. package/dest/lmdb-v2/array.d.ts.map +1 -0
  88. package/dest/lmdb-v2/array.js +101 -0
  89. package/dest/lmdb-v2/factory.d.ts +12 -0
  90. package/dest/lmdb-v2/factory.d.ts.map +1 -0
  91. package/dest/lmdb-v2/factory.js +60 -0
  92. package/dest/lmdb-v2/index.d.ts +3 -0
  93. package/dest/lmdb-v2/index.d.ts.map +1 -0
  94. package/dest/lmdb-v2/index.js +2 -0
  95. package/dest/lmdb-v2/map.d.ts +86 -0
  96. package/dest/lmdb-v2/map.d.ts.map +1 -0
  97. package/dest/lmdb-v2/map.js +193 -0
  98. package/dest/lmdb-v2/message.d.ts +112 -0
  99. package/dest/lmdb-v2/message.d.ts.map +1 -0
  100. package/dest/lmdb-v2/message.js +18 -0
  101. package/dest/lmdb-v2/read_transaction.d.ts +14 -0
  102. package/dest/lmdb-v2/read_transaction.d.ts.map +1 -0
  103. package/dest/lmdb-v2/read_transaction.js +101 -0
  104. package/dest/lmdb-v2/singleton.d.ts +12 -0
  105. package/dest/lmdb-v2/singleton.d.ts.map +1 -0
  106. package/dest/lmdb-v2/singleton.js +31 -0
  107. package/dest/lmdb-v2/store.d.ts +43 -0
  108. package/dest/lmdb-v2/store.d.ts.map +1 -0
  109. package/dest/lmdb-v2/store.js +181 -0
  110. package/dest/lmdb-v2/utils.d.ts +19 -0
  111. package/dest/lmdb-v2/utils.d.ts.map +1 -0
  112. package/dest/lmdb-v2/utils.js +126 -0
  113. package/dest/lmdb-v2/write_transaction.d.ts +19 -0
  114. package/dest/lmdb-v2/write_transaction.d.ts.map +1 -0
  115. package/dest/lmdb-v2/write_transaction.js +254 -0
  116. package/dest/stores/index.d.ts +2 -0
  117. package/dest/stores/index.d.ts.map +1 -0
  118. package/dest/stores/index.js +1 -0
  119. package/dest/stores/l2_tips_store.d.ts +13 -0
  120. package/dest/stores/l2_tips_store.d.ts.map +1 -0
  121. package/dest/stores/l2_tips_store.js +65 -0
  122. package/dest/utils.d.ts +12 -0
  123. package/dest/utils.d.ts.map +1 -0
  124. package/dest/utils.js +24 -0
  125. package/package.json +99 -0
  126. package/src/config.ts +34 -0
  127. package/src/indexeddb/array.ts +118 -0
  128. package/src/indexeddb/index.ts +29 -0
  129. package/src/indexeddb/map.ts +142 -0
  130. package/src/indexeddb/set.ts +37 -0
  131. package/src/indexeddb/singleton.ts +49 -0
  132. package/src/indexeddb/store.ts +197 -0
  133. package/src/interfaces/array.ts +90 -0
  134. package/src/interfaces/array_test_suite.ts +130 -0
  135. package/src/interfaces/common.ts +20 -0
  136. package/src/interfaces/counter.ts +65 -0
  137. package/src/interfaces/index.ts +7 -0
  138. package/src/interfaces/map.ts +151 -0
  139. package/src/interfaces/map_test_suite.ts +143 -0
  140. package/src/interfaces/set.ts +48 -0
  141. package/src/interfaces/set_test_suite.ts +81 -0
  142. package/src/interfaces/singleton.ts +29 -0
  143. package/src/interfaces/singleton_test_suite.ts +46 -0
  144. package/src/interfaces/store.ts +177 -0
  145. package/src/interfaces/store_test_suite.ts +56 -0
  146. package/src/interfaces/utils.ts +21 -0
  147. package/src/lmdb/array.ts +139 -0
  148. package/src/lmdb/counter.ts +67 -0
  149. package/src/lmdb/index.ts +37 -0
  150. package/src/lmdb/map.ts +248 -0
  151. package/src/lmdb/set.ts +45 -0
  152. package/src/lmdb/singleton.ts +35 -0
  153. package/src/lmdb/store.ts +263 -0
  154. package/src/lmdb-v2/array.ts +115 -0
  155. package/src/lmdb-v2/factory.ts +98 -0
  156. package/src/lmdb-v2/index.ts +2 -0
  157. package/src/lmdb-v2/map.ts +233 -0
  158. package/src/lmdb-v2/message.ts +146 -0
  159. package/src/lmdb-v2/read_transaction.ts +116 -0
  160. package/src/lmdb-v2/singleton.ts +34 -0
  161. package/src/lmdb-v2/store.ts +237 -0
  162. package/src/lmdb-v2/utils.ts +150 -0
  163. package/src/lmdb-v2/write_transaction.ts +314 -0
  164. package/src/stores/index.ts +1 -0
  165. package/src/stores/l2_tips_store.ts +70 -0
  166. package/src/utils.ts +40 -0
@@ -0,0 +1,117 @@
1
+ import { LmdbAztecSingleton } from './singleton.js';
2
+ /**
3
+ * An persistent array backed by LMDB.
4
+ */ export class LmdbAztecArray {
5
+ #db;
6
+ #name;
7
+ #length;
8
+ constructor(db, arrName){
9
+ this.#name = arrName;
10
+ this.#length = new LmdbAztecSingleton(db, `${arrName}:meta:length`);
11
+ this.#db = db;
12
+ }
13
+ get length() {
14
+ return this.#length.get() ?? 0;
15
+ }
16
+ lengthAsync() {
17
+ return Promise.resolve(this.length);
18
+ }
19
+ push(...vals) {
20
+ return this.#db.childTransaction(()=>{
21
+ let length = this.length;
22
+ for (const val of vals){
23
+ void this.#db.put(this.#slot(length), val);
24
+ length += 1;
25
+ }
26
+ void this.#length.set(length);
27
+ return length;
28
+ });
29
+ }
30
+ pop() {
31
+ return this.#db.childTransaction(()=>{
32
+ const length = this.length;
33
+ if (length === 0) {
34
+ return undefined;
35
+ }
36
+ const slot = this.#slot(length - 1);
37
+ const val = this.#db.get(slot);
38
+ void this.#db.remove(slot);
39
+ void this.#length.set(length - 1);
40
+ return val;
41
+ });
42
+ }
43
+ at(index) {
44
+ if (index < 0) {
45
+ index = this.length + index;
46
+ }
47
+ // the Array API only accepts indexes in the range [-this.length, this.length)
48
+ // so if after normalizing the index is still out of range, return undefined
49
+ if (index < 0 || index >= this.length) {
50
+ return undefined;
51
+ }
52
+ return this.#db.get(this.#slot(index));
53
+ }
54
+ atAsync(index) {
55
+ return Promise.resolve(this.at(index));
56
+ }
57
+ setAt(index, val) {
58
+ if (index < 0) {
59
+ index = this.length + index;
60
+ }
61
+ if (index < 0 || index >= this.length) {
62
+ return Promise.resolve(false);
63
+ }
64
+ return this.#db.put(this.#slot(index), val);
65
+ }
66
+ *entries() {
67
+ const transaction = this.#db.useReadTransaction();
68
+ try {
69
+ const values = this.#db.getRange({
70
+ start: this.#slot(0),
71
+ limit: this.length,
72
+ transaction
73
+ });
74
+ for (const { key, value } of values){
75
+ const index = key[3];
76
+ yield [
77
+ index,
78
+ value
79
+ ];
80
+ }
81
+ } finally{
82
+ transaction.done();
83
+ }
84
+ }
85
+ async *entriesAsync() {
86
+ for (const [key, value] of this.entries()){
87
+ yield [
88
+ key,
89
+ value
90
+ ];
91
+ }
92
+ }
93
+ *values() {
94
+ for (const [_, value] of this.entries()){
95
+ yield value;
96
+ }
97
+ }
98
+ async *valuesAsync() {
99
+ for (const [_, value] of this.entries()){
100
+ yield value;
101
+ }
102
+ }
103
+ [Symbol.iterator]() {
104
+ return this.values();
105
+ }
106
+ [Symbol.asyncIterator]() {
107
+ return this.valuesAsync();
108
+ }
109
+ #slot(index) {
110
+ return [
111
+ 'array',
112
+ this.#name,
113
+ 'slot',
114
+ index
115
+ ];
116
+ }
117
+ }
@@ -0,0 +1,19 @@
1
+ import type { Key as BaseKey, Database } from 'lmdb';
2
+ import type { Key, Range } from '../interfaces/common.js';
3
+ import type { AztecAsyncCounter, AztecCounter } from '../interfaces/counter.js';
4
+ /**
5
+ * A counter implementation backed by LMDB
6
+ */
7
+ export declare class LmdbAztecCounter<K extends Key> implements AztecCounter<K>, AztecAsyncCounter<K> {
8
+ #private;
9
+ constructor(db: Database<unknown, BaseKey>, name: string);
10
+ set(key: K, value: number): Promise<void>;
11
+ update(key: K, delta?: number): Promise<void>;
12
+ get(key: K): number;
13
+ getAsync(key: K): Promise<number>;
14
+ entries(range?: Range<K>): IterableIterator<[K, number]>;
15
+ entriesAsync(range?: Range<K>): AsyncIterableIterator<[K, number]>;
16
+ keys(range?: Range<K>): IterableIterator<K>;
17
+ keysAsync(range?: Range<K>): AsyncIterableIterator<K>;
18
+ }
19
+ //# sourceMappingURL=counter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"counter.d.ts","sourceRoot":"","sources":["../../src/lmdb/counter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,IAAI,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAErD,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGhF;;GAEG;AACH,qBAAa,gBAAgB,CAAC,CAAC,SAAS,GAAG,CAAE,YAAW,YAAY,CAAC,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC;;gBAK/E,EAAE,EAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM;IAMlD,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBxC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,MAAM;IAInB,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAIjC,OAAO,CAAC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAIrD,YAAY,CAAC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAI7E,IAAI,CAAC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC;IAIxC,SAAS,CAAC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC;CAGjE"}
@@ -0,0 +1,50 @@
1
+ import { LmdbAztecMap } from './map.js';
2
+ /**
3
+ * A counter implementation backed by LMDB
4
+ */ export class LmdbAztecCounter {
5
+ #db;
6
+ #name;
7
+ #map;
8
+ constructor(db, name){
9
+ this.#db = db;
10
+ this.#name = name;
11
+ this.#map = new LmdbAztecMap(db, name);
12
+ }
13
+ async set(key, value) {
14
+ await this.#map.set(key, value);
15
+ }
16
+ update(key, delta = 1) {
17
+ return this.#db.childTransaction(()=>{
18
+ const current = this.#map.get(key) ?? 0;
19
+ const next = current + delta;
20
+ if (next < 0) {
21
+ throw new Error(`Cannot update ${key} in counter ${this.#name} below zero`);
22
+ }
23
+ if (next === 0) {
24
+ void this.#map.delete(key);
25
+ } else {
26
+ // store the key inside the entry because LMDB might return an internal representation
27
+ // of the key when iterating over the database
28
+ void this.#map.set(key, next);
29
+ }
30
+ });
31
+ }
32
+ get(key) {
33
+ return this.#map.get(key) ?? 0;
34
+ }
35
+ getAsync(key) {
36
+ return Promise.resolve(this.get(key));
37
+ }
38
+ entries(range = {}) {
39
+ return this.#map.entries(range);
40
+ }
41
+ async *entriesAsync(range = {}) {
42
+ yield* this.entries(range);
43
+ }
44
+ keys(range = {}) {
45
+ return this.#map.keys(range);
46
+ }
47
+ async *keysAsync(range = {}) {
48
+ yield* this.keys(range);
49
+ }
50
+ }
@@ -0,0 +1,12 @@
1
+ import { type Logger } from '@aztec/foundation/log';
2
+ import type { DataStoreConfig } from '../config.js';
3
+ import { AztecLmdbStore } from './store.js';
4
+ export { AztecLmdbStore } from './store.js';
5
+ export declare function createStore(name: string, config: DataStoreConfig, log?: Logger): AztecLmdbStore | Promise<AztecLmdbStore>;
6
+ /**
7
+ * Opens a temporary store for testing purposes.
8
+ * @param ephemeral - true if the store should only exist in memory and not automatically be flushed to disk. Optional
9
+ * @returns A new store
10
+ */
11
+ export declare function openTmpStore(ephemeral?: boolean): AztecLmdbStore;
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lmdb/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAIlE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,GAAE,MAAiC,4CAiBxG;AACD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,GAAE,OAAe,GAAG,cAAc,CAGvE"}
@@ -0,0 +1,25 @@
1
+ import { createLogger } from '@aztec/foundation/log';
2
+ import { join } from 'path';
3
+ import { initStoreForRollup } from '../utils.js';
4
+ import { AztecLmdbStore } from './store.js';
5
+ export { AztecLmdbStore } from './store.js';
6
+ export function createStore(name, config, log = createLogger('kv-store')) {
7
+ let { dataDirectory } = config;
8
+ if (typeof dataDirectory !== 'undefined') {
9
+ dataDirectory = join(dataDirectory, name);
10
+ }
11
+ 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`);
12
+ const store = AztecLmdbStore.open(dataDirectory, config.dataStoreMapSizeKB, false);
13
+ if (config.l1Contracts?.rollupAddress) {
14
+ return initStoreForRollup(store, config.l1Contracts.rollupAddress, log);
15
+ }
16
+ return store;
17
+ }
18
+ /**
19
+ * Opens a temporary store for testing purposes.
20
+ * @param ephemeral - true if the store should only exist in memory and not automatically be flushed to disk. Optional
21
+ * @returns A new store
22
+ */ export function openTmpStore(ephemeral = false) {
23
+ const mapSize = 1024 * 1024 * 10; // 10 GB map size
24
+ return AztecLmdbStore.open(undefined, mapSize, ephemeral);
25
+ }
@@ -0,0 +1,52 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
3
+ import type { Database } from 'lmdb';
4
+ import type { Key, Range } from '../interfaces/common.js';
5
+ import type { AztecAsyncMultiMap, AztecMapWithSize, AztecMultiMap } from '../interfaces/map.js';
6
+ /** The slot where a key-value entry would be stored */
7
+ type MapValueSlot<K extends Key | Buffer> = ['map', string, 'slot', K];
8
+ /**
9
+ * A map backed by LMDB.
10
+ */
11
+ export declare class LmdbAztecMap<K extends Key, V> implements AztecMultiMap<K, V>, AztecAsyncMultiMap<K, V> {
12
+ protected db: Database<[K, V], MapValueSlot<K>>;
13
+ protected name: string;
14
+ protected startSentinel: MapValueSlot<Buffer>;
15
+ protected endSentinel: MapValueSlot<Buffer>;
16
+ constructor(rootDb: Database, mapName: string);
17
+ close(): Promise<void>;
18
+ get(key: K): V | undefined;
19
+ getAsync(key: K): Promise<V | undefined>;
20
+ getValues(key: K): IterableIterator<V>;
21
+ getValuesAsync(key: K): AsyncIterableIterator<V>;
22
+ has(key: K): boolean;
23
+ hasAsync(key: K): Promise<boolean>;
24
+ set(key: K, val: V): Promise<void>;
25
+ swap(key: K, fn: (val: V | undefined) => V): Promise<void>;
26
+ setIfNotExists(key: K, val: V): Promise<boolean>;
27
+ delete(key: K): Promise<void>;
28
+ deleteValue(key: K, val: V): Promise<void>;
29
+ entries(range?: Range<K>): IterableIterator<[K, V]>;
30
+ entriesAsync(range?: Range<K> | undefined): AsyncIterableIterator<[K, V]>;
31
+ values(range?: Range<K>): IterableIterator<V>;
32
+ valuesAsync(range?: Range<K>): AsyncIterableIterator<V>;
33
+ keys(range?: Range<K>): IterableIterator<K>;
34
+ keysAsync(range?: Range<K>): AsyncIterableIterator<K>;
35
+ protected slot(key: K): MapValueSlot<K>;
36
+ clear(): Promise<void>;
37
+ }
38
+ export declare class LmdbAztecMapWithSize<K extends Key, V> extends LmdbAztecMap<K, V> implements AztecMapWithSize<K, V>, AztecAsyncMultiMap<K, V> {
39
+ #private;
40
+ constructor(rootDb: Database, mapName: string);
41
+ set(key: K, val: V): Promise<void>;
42
+ delete(key: K): Promise<void>;
43
+ deleteValue(key: K, val: V): Promise<void>;
44
+ /**
45
+ * Gets the size of the map by counting entries.
46
+ * @returns The number of entries in the map
47
+ */
48
+ size(): number;
49
+ clearCache(): void;
50
+ }
51
+ export {};
52
+ //# sourceMappingURL=map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/lmdb/map.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,222 @@
1
+ /**
2
+ * A map backed by LMDB.
3
+ */ export class LmdbAztecMap {
4
+ db;
5
+ name;
6
+ startSentinel;
7
+ endSentinel;
8
+ constructor(rootDb, mapName){
9
+ this.name = mapName;
10
+ this.db = rootDb;
11
+ // sentinels are used to define the start and end of the map
12
+ // with LMDB's key encoding, no _primitive value_ can be "less than" an empty buffer or greater than Byte 255
13
+ // these will be used later to answer range queries
14
+ this.startSentinel = [
15
+ 'map',
16
+ this.name,
17
+ 'slot',
18
+ Buffer.from([])
19
+ ];
20
+ this.endSentinel = [
21
+ 'map',
22
+ this.name,
23
+ 'slot',
24
+ Buffer.from([
25
+ 255
26
+ ])
27
+ ];
28
+ }
29
+ close() {
30
+ return this.db.close();
31
+ }
32
+ get(key) {
33
+ return this.db.get(this.slot(key))?.[1];
34
+ }
35
+ getAsync(key) {
36
+ return Promise.resolve(this.get(key));
37
+ }
38
+ *getValues(key) {
39
+ const transaction = this.db.useReadTransaction();
40
+ try {
41
+ const values = this.db.getValues(this.slot(key), {
42
+ transaction
43
+ });
44
+ for (const value of values){
45
+ yield value?.[1];
46
+ }
47
+ } finally{
48
+ transaction.done();
49
+ }
50
+ }
51
+ async *getValuesAsync(key) {
52
+ for (const value of this.getValues(key)){
53
+ yield value;
54
+ }
55
+ }
56
+ has(key) {
57
+ return this.db.doesExist(this.slot(key));
58
+ }
59
+ hasAsync(key) {
60
+ return Promise.resolve(this.has(key));
61
+ }
62
+ async set(key, val) {
63
+ await this.db.put(this.slot(key), [
64
+ key,
65
+ val
66
+ ]);
67
+ }
68
+ swap(key, fn) {
69
+ return this.db.childTransaction(()=>{
70
+ const slot = this.slot(key);
71
+ const entry = this.db.get(slot);
72
+ void this.db.put(slot, [
73
+ key,
74
+ fn(entry?.[1])
75
+ ]);
76
+ });
77
+ }
78
+ setIfNotExists(key, val) {
79
+ const slot = this.slot(key);
80
+ return this.db.ifNoExists(slot, ()=>{
81
+ void this.db.put(slot, [
82
+ key,
83
+ val
84
+ ]);
85
+ });
86
+ }
87
+ async delete(key) {
88
+ await this.db.remove(this.slot(key));
89
+ }
90
+ async deleteValue(key, val) {
91
+ await this.db.remove(this.slot(key), [
92
+ key,
93
+ val
94
+ ]);
95
+ }
96
+ *entries(range = {}) {
97
+ const transaction = this.db.useReadTransaction();
98
+ try {
99
+ const { reverse = false, limit } = range;
100
+ // LMDB has a quirk where it expects start > end when reverse=true
101
+ // in that case, we need to swap the start and end sentinels
102
+ const start = reverse ? range.end ? this.slot(range.end) : this.endSentinel : range.start ? this.slot(range.start) : this.startSentinel;
103
+ const end = reverse ? range.start ? this.slot(range.start) : this.startSentinel : range.end ? this.slot(range.end) : this.endSentinel;
104
+ const lmdbRange = {
105
+ start,
106
+ end,
107
+ reverse,
108
+ limit,
109
+ transaction
110
+ };
111
+ const iterator = this.db.getRange(lmdbRange);
112
+ for (const { value: [key, value] } of iterator){
113
+ yield [
114
+ key,
115
+ value
116
+ ];
117
+ }
118
+ } finally{
119
+ transaction.done();
120
+ }
121
+ }
122
+ async *entriesAsync(range) {
123
+ for (const entry of this.entries(range)){
124
+ yield entry;
125
+ }
126
+ }
127
+ *values(range = {}) {
128
+ for (const [_, value] of this.entries(range)){
129
+ yield value;
130
+ }
131
+ }
132
+ async *valuesAsync(range = {}) {
133
+ for await (const [_, value] of this.entriesAsync(range)){
134
+ yield value;
135
+ }
136
+ }
137
+ *keys(range = {}) {
138
+ for (const [key, _] of this.entries(range)){
139
+ yield key;
140
+ }
141
+ }
142
+ async *keysAsync(range = {}) {
143
+ for await (const [key, _] of this.entriesAsync(range)){
144
+ yield key;
145
+ }
146
+ }
147
+ slot(key) {
148
+ return [
149
+ 'map',
150
+ this.name,
151
+ 'slot',
152
+ key
153
+ ];
154
+ }
155
+ async clear() {
156
+ const lmdbRange = {
157
+ start: this.startSentinel,
158
+ end: this.endSentinel
159
+ };
160
+ const iterator = this.db.getRange(lmdbRange);
161
+ for (const { key } of iterator){
162
+ await this.db.remove(key);
163
+ }
164
+ }
165
+ }
166
+ export class LmdbAztecMapWithSize extends LmdbAztecMap {
167
+ #sizeCache;
168
+ constructor(rootDb, mapName){
169
+ super(rootDb, mapName);
170
+ }
171
+ async set(key, val) {
172
+ await this.db.childTransaction(()=>{
173
+ const exists = this.db.doesExist(this.slot(key));
174
+ this.db.putSync(this.slot(key), [
175
+ key,
176
+ val
177
+ ], {
178
+ appendDup: true
179
+ });
180
+ if (!exists) {
181
+ this.#sizeCache = undefined; // Invalidate cache
182
+ }
183
+ });
184
+ }
185
+ async delete(key) {
186
+ await this.db.childTransaction(async ()=>{
187
+ const exists = this.db.doesExist(this.slot(key));
188
+ if (exists) {
189
+ await this.db.remove(this.slot(key));
190
+ this.#sizeCache = undefined; // Invalidate cache
191
+ }
192
+ });
193
+ }
194
+ async deleteValue(key, val) {
195
+ await this.db.childTransaction(async ()=>{
196
+ const exists = this.db.doesExist(this.slot(key));
197
+ if (exists) {
198
+ await this.db.remove(this.slot(key), [
199
+ key,
200
+ val
201
+ ]);
202
+ this.#sizeCache = undefined; // Invalidate cache
203
+ }
204
+ });
205
+ }
206
+ /**
207
+ * Gets the size of the map by counting entries.
208
+ * @returns The number of entries in the map
209
+ */ size() {
210
+ if (this.#sizeCache === undefined) {
211
+ this.#sizeCache = this.db.getCount({
212
+ start: this.startSentinel,
213
+ end: this.endSentinel
214
+ });
215
+ }
216
+ return this.#sizeCache;
217
+ }
218
+ // Reset cache on clear/drop operations
219
+ clearCache() {
220
+ this.#sizeCache = undefined;
221
+ }
222
+ }
@@ -0,0 +1,18 @@
1
+ import type { Database } from 'lmdb';
2
+ import type { Key, Range } from '../interfaces/common.js';
3
+ import type { AztecAsyncSet, AztecSet } from '../interfaces/set.js';
4
+ /**
5
+ * A set backed by LMDB.
6
+ */
7
+ export declare class LmdbAztecSet<K extends Key> implements AztecSet<K>, AztecAsyncSet<K> {
8
+ private map;
9
+ constructor(rootDb: Database, mapName: string);
10
+ close(): Promise<void>;
11
+ has(key: K): boolean;
12
+ hasAsync(key: K): Promise<boolean>;
13
+ add(key: K): Promise<void>;
14
+ delete(key: K): Promise<void>;
15
+ entries(range?: Range<K>): IterableIterator<K>;
16
+ entriesAsync(range?: Range<K>): AsyncIterableIterator<K>;
17
+ }
18
+ //# sourceMappingURL=set.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../src/lmdb/set.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAErC,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGpE;;GAEG;AACH,qBAAa,YAAY,CAAC,CAAC,SAAS,GAAG,CAAE,YAAW,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC;IAC/E,OAAO,CAAC,GAAG,CAA2B;gBAC1B,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM;IAI7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAIpB,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1B,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7B,OAAO,CAAC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC;IAI3C,YAAY,CAAC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC;CAKpE"}
@@ -0,0 +1,32 @@
1
+ import { LmdbAztecMap } from './map.js';
2
+ /**
3
+ * A set backed by LMDB.
4
+ */ export class LmdbAztecSet {
5
+ map;
6
+ constructor(rootDb, mapName){
7
+ this.map = new LmdbAztecMap(rootDb, mapName);
8
+ }
9
+ close() {
10
+ return this.map.close();
11
+ }
12
+ has(key) {
13
+ return this.map.has(key);
14
+ }
15
+ hasAsync(key) {
16
+ return Promise.resolve(this.has(key));
17
+ }
18
+ add(key) {
19
+ return this.map.set(key, true);
20
+ }
21
+ delete(key) {
22
+ return this.map.delete(key);
23
+ }
24
+ entries(range = {}) {
25
+ return this.map.keys(range);
26
+ }
27
+ async *entriesAsync(range = {}) {
28
+ for await (const key of this.map.keysAsync(range)){
29
+ yield key;
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,14 @@
1
+ import type { Database, Key } from 'lmdb';
2
+ import type { AztecAsyncSingleton, AztecSingleton } from '../interfaces/singleton.js';
3
+ /**
4
+ * Stores a single value in LMDB.
5
+ */
6
+ export declare class LmdbAztecSingleton<T> implements AztecSingleton<T>, AztecAsyncSingleton<T> {
7
+ #private;
8
+ constructor(db: Database<unknown, Key>, name: string);
9
+ get(): T | undefined;
10
+ getAsync(): Promise<T | undefined>;
11
+ set(val: T): Promise<boolean>;
12
+ delete(): Promise<boolean>;
13
+ }
14
+ //# sourceMappingURL=singleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singleton.d.ts","sourceRoot":"","sources":["../../src/lmdb/singleton.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAKtF;;GAEG;AACH,qBAAa,kBAAkB,CAAC,CAAC,CAAE,YAAW,cAAc,CAAC,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC;;gBAIzE,EAAE,EAAE,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM;IAKpD,GAAG,IAAI,CAAC,GAAG,SAAS;IAIpB,QAAQ,IAAI,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAIlC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAI7B,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;CAG3B"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Stores a single value in LMDB.
3
+ */ export class LmdbAztecSingleton {
4
+ #db;
5
+ #slot;
6
+ constructor(db, name){
7
+ this.#db = db;
8
+ this.#slot = [
9
+ 'singleton',
10
+ name,
11
+ 'value'
12
+ ];
13
+ }
14
+ get() {
15
+ return this.#db.get(this.#slot);
16
+ }
17
+ getAsync() {
18
+ return Promise.resolve(this.get());
19
+ }
20
+ set(val) {
21
+ return this.#db.put(this.#slot, val);
22
+ }
23
+ delete() {
24
+ return this.#db.remove(this.#slot);
25
+ }
26
+ }