1 | // eslint-disable-next-line implicit-dependencies/no-implicit
|
2 | import type { LevelUp } from 'levelup'
|
3 | const level = require('level-mem')
|
4 |
|
5 | export const ENCODING_OPTS = { keyEncoding: 'binary', valueEncoding: 'binary' }
|
6 |
|
7 | export type BatchDBOp = PutBatch | DelBatch
|
8 | export interface PutBatch {
|
9 | type: 'put'
|
10 | key: Buffer
|
11 | value: Buffer
|
12 | }
|
13 | export interface DelBatch {
|
14 | type: 'del'
|
15 | key: Buffer
|
16 | }
|
17 |
|
18 | /**
|
19 | * DB is a thin wrapper around the underlying levelup db,
|
20 | * which validates inputs and sets encoding type.
|
21 | */
|
22 | export class DB {
|
23 | _leveldb: LevelUp
|
24 |
|
25 | /**
|
26 | * Initialize a DB instance. If `leveldb` is not provided, DB
|
27 | * defaults to an [in-memory store](https://github.com/Level/memdown).
|
28 | * @param leveldb - An abstract-leveldown compliant store
|
29 | */
|
30 | constructor(leveldb?: LevelUp) {
|
31 | this._leveldb = leveldb ?? level()
|
32 | }
|
33 |
|
34 | /**
|
35 | * Retrieves a raw value from leveldb.
|
36 | * @param key
|
37 | * @returns A Promise that resolves to `Buffer` if a value is found or `null` if no value is found.
|
38 | */
|
39 | async get(key: Buffer): Promise<Buffer | null> {
|
40 | let value = null
|
41 | try {
|
42 | value = await this._leveldb.get(key, ENCODING_OPTS)
|
43 | } catch (error: any) {
|
44 | if (error.notFound) {
|
45 | // not found, returning null
|
46 | } else {
|
47 | throw error
|
48 | }
|
49 | }
|
50 | return value
|
51 | }
|
52 |
|
53 | /**
|
54 | * Writes a value directly to leveldb.
|
55 | * @param key The key as a `Buffer`
|
56 | * @param value The value to be stored
|
57 | */
|
58 | async put(key: Buffer, val: Buffer): Promise<void> {
|
59 | await this._leveldb.put(key, val, ENCODING_OPTS)
|
60 | }
|
61 |
|
62 | /**
|
63 | * Removes a raw value in the underlying leveldb.
|
64 | * @param keys
|
65 | */
|
66 | async del(key: Buffer): Promise<void> {
|
67 | await this._leveldb.del(key, ENCODING_OPTS)
|
68 | }
|
69 |
|
70 | /**
|
71 | * Performs a batch operation on db.
|
72 | * @param opStack A stack of levelup operations
|
73 | */
|
74 | async batch(opStack: BatchDBOp[]): Promise<void> {
|
75 | await this._leveldb.batch(opStack, ENCODING_OPTS)
|
76 | }
|
77 |
|
78 | /**
|
79 | * Returns a copy of the DB instance, with a reference
|
80 | * to the **same** underlying leveldb instance.
|
81 | */
|
82 | copy(): DB {
|
83 | return new DB(this._leveldb)
|
84 | }
|
85 | }
|