diff --git a/package-lock.json b/package-lock.json index a653c178..ce76bed3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -868,6 +868,12 @@ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true }, + "@types/abstract-leveldown": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-5.0.2.tgz", + "integrity": "sha512-+jA1XXF3jsz+Z7FcuiNqgK53hTa/luglT2TyTpKPqoYbxVY+mCPF22Rm+q3KPBrMHJwNXFrTViHszBOfU4vftQ==", + "dev": true + }, "@types/babel__core": { "version": "7.1.15", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", @@ -909,6 +915,16 @@ "@babel/types": "^7.3.0" } }, + "@types/encoding-down": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/encoding-down/-/encoding-down-5.0.0.tgz", + "integrity": "sha512-G0MlS/+/U2RIQLcSEhhAcoMrXw3hXUCFSKbhbeEljoKMra2kq+NPX6tfOveSWQLX2hJXBo+YrvKgAGe+tFL1Aw==", + "dev": true, + "requires": { + "@types/abstract-leveldown": "*", + "@types/level-codec": "*" + } + }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -958,6 +974,40 @@ "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, + "@types/level": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/level/-/level-6.0.0.tgz", + "integrity": "sha512-NjaUpukKfCvnV4Wk0jUaodFi2/66HxgpYghc2aV8iP+zk2NMt/9ps1eVlifqOU/+eLzMlDIY69NWkbPaAstukQ==", + "dev": true, + "requires": { + "@types/abstract-leveldown": "*", + "@types/encoding-down": "*", + "@types/levelup": "*" + } + }, + "@types/level-codec": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@types/level-codec/-/level-codec-9.0.1.tgz", + "integrity": "sha512-6z7DSlBsmbax3I/bV1Q6jT1nKquDjFl95LURVThdKtwILkRawLYtXdINW19xM95N5kqN2detWb2iGrbUlPwNyw==", + "dev": true + }, + "@types/level-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", + "integrity": "sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ==", + "dev": true + }, + "@types/levelup": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz", + "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==", + "dev": true, + "requires": { + "@types/abstract-leveldown": "*", + "@types/level-errors": "*", + "@types/node": "*" + } + }, "@types/node": { "version": "14.17.17", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.17.tgz", @@ -991,6 +1041,17 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "@types/subleveldown": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@types/subleveldown/-/subleveldown-4.1.1.tgz", + "integrity": "sha512-cnup7ibJZjwHIwDATB9hdtvfM3j6hkRquBz/Ld/PJC50r1u7V+bXhm+tof665A2D56shExosPqybbET770GBEg==", + "dev": true, + "requires": { + "@types/abstract-leveldown": "*", + "@types/level-codec": "*", + "@types/levelup": "*" + } + }, "@types/yargs": { "version": "15.0.14", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", @@ -1826,6 +1887,11 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, + "deep-access": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/deep-access/-/deep-access-0.1.1.tgz", + "integrity": "sha1-y0EtFc1t22kCLOCGeiqwBLpfpYI=" + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -2422,6 +2488,11 @@ } } }, + "existy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/existy/-/existy-1.0.1.tgz", + "integrity": "sha1-Ma4qED5ljAAa7WjwnPNGjcxtgeU=" + }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -3937,6 +4008,17 @@ "leveldown": "^5.4.0" } }, + "level-auto-index": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/level-auto-index/-/level-auto-index-2.0.0.tgz", + "integrity": "sha512-sed5xe+hTI0uktAF2OvqpPJuz7JUIJ7NturXzMHDvb72WG2nId6KpB5/fzSj3ZcctHK7gB9xqbzVM6ZjpnKnlg==", + "requires": { + "existy": "^1.0.1", + "level-hookdown": "^3.0.0", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + } + }, "level-codec": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", @@ -3969,6 +4051,88 @@ "errno": "~0.1.1" } }, + "level-hookdown": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/level-hookdown/-/level-hookdown-3.1.2.tgz", + "integrity": "sha512-oYR+Q/72ai+XMiM+KmM2rFUdq0yzW8sqwEwnvBvTUW+03hXkYv3zq3Cqa9aIbVyxsyG/VmYjB6hSoLz6Gg6INg==", + "requires": { + "run-parallel": "^1.1.9", + "run-parallel-limit": "^1.0.5", + "run-series": "^1.1.8", + "xtend": "^4.0.2" + } + }, + "level-idx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/level-idx/-/level-idx-2.0.0.tgz", + "integrity": "sha512-ldnKPuUXwqffYy9eKJn+Od+NQWcoVDfm9Z46WlhQ44EAWr3pmPSwuGAygsKNf6HEGP4p6u10KDl5snH40tjihg==", + "requires": { + "deep-access": "^0.1.1", + "level-auto-index": "^2.0.0", + "subleveldown": "^4.1.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", + "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "level-concat-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==" + }, + "level-supports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", + "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "requires": { + "xtend": "^4.0.2" + } + }, + "levelup": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", + "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "requires": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "subleveldown": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/subleveldown/-/subleveldown-4.1.4.tgz", + "integrity": "sha512-njpSBP/Bxh7EahraG6IhR6goOH2ffMTMVt7Ud+k/OhNFHrrmuvK+XYfauI8KnjCm0w381cUF43pejlWeJMZChA==", + "requires": { + "abstract-leveldown": "^6.1.1", + "encoding-down": "^6.2.0", + "inherits": "^2.0.3", + "level-option-wrap": "^1.1.0", + "levelup": "^4.3.1", + "reachdown": "^1.0.0" + } + } + } + }, "level-iterator-stream": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", @@ -4407,6 +4571,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "multiformats": { + "version": "9.4.9", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.4.9.tgz", + "integrity": "sha512-zA84TTJcRfRMpjvYqy63piBbSEdqlIGqNNSpP6kspqtougqjo60PRhIFo+oAxrjkof14WMCImvr7acK6rPpXLw==" + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -5068,11 +5237,23 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "requires": { "queue-microtask": "^1.2.2" } }, + "run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "run-series": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz", + "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==" + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", diff --git a/package.json b/package.json index 263eddfe..db5905b4 100644 --- a/package.json +++ b/package.json @@ -25,16 +25,23 @@ "abstract-leveldown": "^7.0.0", "async-mutex": "^0.3.1", "level": "^6.0.1", + "level-auto-index": "^2.0.0", + "level-hookdown": "^3.1.2", + "level-idx": "^2.0.0", "levelup": "^5.0.1", + "multiformats": "^9.4.9", "sublevel-prefixer": "^1.0.0", "subleveldown": "^5.0.1", "threads": "^1.6.5", "ts-custom-error": "^3.2.0" }, "devDependencies": { + "@types/abstract-leveldown": "^5.0.2", "@types/jest": "^26.0.20", + "@types/level": "^6.0.0", "@types/node": "^14.14.35", "@types/node-forge": "^0.10.4", + "@types/subleveldown": "^4.1.1", "@typescript-eslint/eslint-plugin": "^4.12.0", "@typescript-eslint/parser": "^4.12.0", "benny": "^3.6.15", diff --git a/src/DB.ts b/src/DB.ts index 853fb757..748e099d 100644 --- a/src/DB.ts +++ b/src/DB.ts @@ -85,7 +85,7 @@ class DB { this.fs = fs; } - get db(): LevelDB { + get db(): LevelDB { return this._db; } diff --git a/test-encoding.ts b/test-encoding.ts new file mode 100644 index 00000000..a4bb9200 --- /dev/null +++ b/test-encoding.ts @@ -0,0 +1,90 @@ +import type { Codec } from 'multiformats/bases/base'; + +import crypto from 'crypto'; +import { bases } from 'multiformats/basics'; + +function randomBytes(size: number): Uint8Array { + return crypto.randomBytes(size); +} + +type MultibaseFormats = keyof typeof bases; + +const basesByPrefix: Record> = {}; +for (const k in bases) { + const codec = bases[k]; + basesByPrefix[codec.prefix] = codec; +} + +function toMultibase(id: Uint8Array, format: MultibaseFormats): string { + const codec = bases[format]; + return codec.encode(id); +} + +function fromMultibase(idString: string): Uint8Array | undefined { + const prefix = idString[0]; + const codec = basesByPrefix[prefix]; + if (codec == null) { + return; + } + const buffer = codec.decode(idString); + return buffer; +} + +const originalList: Array = []; + +const total = 100000; + +let count = total; +while (count) { + originalList.push(randomBytes(16)); + count--; +} + +originalList.sort(Buffer.compare); +const encodedList = originalList.map( + (bs) => toMultibase(bs, 'base64') +); + +console.log(encodedList); + +// const encodedList_ = encodedList.slice(); +// encodedList_.sort(); + +// // encodedList is the same order as originalList +// // if base58btc preserves lexicographic-order +// // then encodedList_ would be the same order + +// const l = encodedList[0].length; +// console.log(l); +// for (let i = 0; i < total; i++) { + +// if (encodedList[i].length !== l) { +// console.log('new length', encodedList[i].length); +// } + +// if (encodedList[i] !== encodedList_[i]) { +// console.log('Does not match on:', i); +// console.log('original order', encodedList[i]); +// console.log('encoded order', encodedList_[i]); +// break; +// } +// } + +// const decodedList = encodedList.map(fromMultibase); +// for (let i = 0; i < total; i++) { +// // @ts-ignore +// if (!originalList[i].equals(Buffer.from(decodedList[i]))) { +// console.log('bug in the code'); +// break; +// } +// } + + +// // 36 characters became 59 characters + +// console.log(encodedList); + +// // need to watch the integration testing more +// // so that concurrent testing works better +// // establish promise conventions +// // and then get on the code properly diff --git a/test-hooks.ts b/test-hooks.ts new file mode 100644 index 00000000..cd186ac1 --- /dev/null +++ b/test-hooks.ts @@ -0,0 +1,120 @@ +import type { LevelDB } from 'level'; +import type { AbstractLevelDOWN, AbstractIterator, AbstractBatch, AbstractOptions } from 'abstract-leveldown'; + +import level from 'level'; +import hookdown from 'level-hookdown'; +import subleveldown from 'subleveldown'; +import AutoIndex from 'level-auto-index'; +import Index from 'level-idx'; +import sublevelprefixer from 'sublevel-prefixer'; + +const prefixer = sublevelprefixer('!'); + +type Callback

= [], R = any, E extends Error = Error> = { + (e: E, ...params: Partial

): R; + (e?: null | undefined, ...params: P): R; +}; + +type HookOp = { + type: 'put'; + key: K; + value: V; + opts: AbstractOptions; +} | { + type: 'del'; + key: K; + opts: AbstractOptions; +} | { + type: 'batch', + array: Array>; + opts: AbstractOptions; +}; + +interface LevelDBHooked extends LevelDB { + prehooks: Array<(op: HookOp, cb: Callback) => void>; + posthooks: Array<(op: HookOp, cb: Callback) => void>; +} + +async function main () { + + // all buffers are Uint8Arrays and all Uint8Arrays are ArrayBuffer + + const db = await new Promise>((resolve, reject) => { + const db = level( + './tmp/db', + { + keyEncoding: 'binary', + valueEncoding: 'binary' + }, + (e) => { + if (e) { + reject(e); + } else { + resolve(db); + } + } + ); + }); + + // db.put('abc', 'blah', { + + // }); + + // so there's a problem + // can these hooks change the operation? + // like the `op` is an object + + const hookdb = hookdown(db) as LevelDBHooked; + + // console.log(hookdb); + + const prehook1 = (op: HookOp, cb: Callback) => { + console.log('pre1', op); + if (op.type == 'put') { + op.key = Buffer.from('changed'); + op.value = Buffer.from('changed'); + } + cb(); + }; + + const prehook2 = (op: HookOp, cb: Callback) => { + console.log('pre2', op); + cb(); + }; + + const posthook1 = (op: HookOp, cb: Callback) => { + console.log('post1', op); + cb(); + }; + + const posthook2 = (op: HookOp, cb: Callback) => { + console.log('post2', op); + cb(); + }; + + hookdb.prehooks.push(prehook1); + hookdb.prehooks.push(prehook2); + + hookdb.posthooks.push(posthook1); + hookdb.posthooks.push(posthook2); + + await db.put(Buffer.from('beep'), Buffer.from('boop')); + + console.log(await db.get(Buffer.from('changed'))); + + // await db.del('beep'); + // await db.batch([ + // { type: 'put', key: 'fatehr', value: 'gloop' }, + // { type: 'put', key: 'omther', value: 'what' } + // ]); + + // TEST if you can mutate the operation + // if you can't you cannot use this to do encryption + // if you can, then this is precisely what you need to use for an "encryption layer" + // also how do other level systems work? I guess they wrap the db module as well + // but these hooks only work against put, del, batch, not get + // that's dumb, without a get hook, that can mutate things how can you use this as a generic wrapper + +} + +main(); diff --git a/test-indexes.ts b/test-indexes.ts new file mode 100644 index 00000000..b6482545 --- /dev/null +++ b/test-indexes.ts @@ -0,0 +1,151 @@ +// how does multi-value indexing work normally? +// let's see if it works in existing system +// our 2 choices is move encryption to a lower level, and reuse the same indexing system +// or build indexing on top + +import type { LevelUp } from 'levelup'; +import type { LevelDB } from 'level'; +import type { AbstractLevelDOWN, AbstractIterator, AbstractBatch, AbstractOptions } from 'abstract-leveldown'; + +import level from 'level'; +import hookdown from 'level-hookdown'; +import subleveldown from 'subleveldown'; +import AutoIndex from 'level-auto-index'; +import Index from 'level-idx'; +import sublevelprefixer from 'sublevel-prefixer'; + +async function main () { + + const db = await new Promise>((resolve, reject) => { + const db = level( + './tmp/db', + { + keyEncoding: 'binary', + }, + (e) => { + if (e) { + reject(e); + } else { + resolve(db); + } + } + ); + }); + + const posts = await new Promise((resolve) => { + const dbLevelNew = subleveldown( + db, + 'posts', + { + keyEncoding: 'binary', + valueEncoding: 'json', + open: (cb) => { + cb(undefined); + resolve(dbLevelNew); + } + } + ); + }); + + const idx = await new Promise((resolve) => { + const dbLevelNew = subleveldown( + db, + 'idx', + { + keyEncoding: 'binary', + open: (cb) => { + cb(undefined); + resolve(dbLevelNew); + } + } + ); + }); + + // ok if we need to base encode all the things + + // right now the indexes don't work + // cause it tries to acquire the value straight away + // the only way would be do a compound index, where you get 1!a title 2!a title + // but that doesn't seem to allow us to know how many there is + // so it has to be a sublevel + // a title is a sublevel -> pointing to indices + // but we will need to base encode to avoid the problem of using values there + // hex encoding is always lexicographic preserving + + // if you're hashing you won't need to base encode at the end + // and therefore the sort order doesn't matter + // IdDeterministic can be used for that, as it is just hashing + // but if you are doing a base encoding + // then it would just be hex encoding + + const another = await new Promise((resolve) => { + const dbLevelNew = subleveldown( + db, + 'Ti!!tle', + { + keyEncoding: 'binary', + valueEncoding: 'binary', + open: (cb) => { + cb(undefined); + resolve(dbLevelNew); + } + } + ); + }); + + // if we were to create sublevels for each kind of key? + // if the sublevels had names like this + + + // // each Name here is a another sublevel under idx + // // the accessors tell us how to construct the index + // // compound indexes are just joined with `!` + // // it only works with uniqueness in this case + // Index(posts, idx) + // .by('Ti!!tle', 'title') + // .by('Length', ['body.length', 'title']) + // .by('Author', ['author', 'title']); + + // const post = { + // title: 'my title', + // body: 'lorem ipsum', + // author: 'julian' + // }; + + + // // the only thing is to not use `!!` in our sublevel prefixes + + // await posts.put(Buffer.from('some !key'), post); + + + // // @ts-ignore + // posts['byTi!!tle'].get(Buffer.from('my title'), (e, o) => { + // console.log('GOT IT', o); + // }); + + // // console.log(await db.get('!idx!!Title!my title')); + + // console.log('STARTING STREAM'); + // const s = db.createReadStream(); + // for await (const o of s) { + // // @ts-ignore + // console.log('KEY', o.key.toString(), o.value); + // // @ts-ignore + // console.log('VALUE', o.value); + // } + + + // // @ts-ignore + // console.log('PROMISE', await posts.byTitle.get(Buffer.from('my title'))); + // console.log(await db.get('!posts!some key')); + + // there a thinking that `!` would never be used for our keys? + +} + +main(); + +// seems like level-idx doesn't use the same version of subleveldown as we do +// this means it has an older subleveldown that doesn't seem the throw the error +// "subleveldown": "^4.1.0" doesn't appear to throw that error how funny +// we are using "subleveldown": "^5.0.1", which does throw that errorte diff --git a/test.ts b/test.ts new file mode 100644 index 00000000..d4ba6553 --- /dev/null +++ b/test.ts @@ -0,0 +1,61 @@ +// try and get a proper index going + +import level from 'level'; +import AutoIndex from 'level-auto-index'; +import subleveldown from 'subleveldown'; + +async function main () { + + const db = await new Promise((resolve, reject) => { + const db = level( + './tmp/db', + { + keyEncoding: 'binary', + valueEncoding: 'binary' + }, + (e) => { + if (e) { + reject(e); + } else { + resolve(db); + } + } + ); + }); + + // this is the level + // but it can also be the root right? + const dbLevel = await new Promise((resolve) => { + const dbLevelNew = subleveldown( + db, + 'vaults', + { + keyEncoding: 'binary', + valueEncoding: 'binary', + open: (cb) => { + cb(undefined); + resolve(dbLevelNew); + } + } + ); + }); + + // the level-idx uses a single + // index db, instead of auto index + // which uses multiple sublevels + // but this can be a problem sort of + // basically the keys and value encoding of the index db + // has to be buffers + // cause our keys can string or Buffer + // but i reckon it makes sense to store the index keys always as string + // cause even if we get a string + // the key is "utf-8" encoded + // thus we always have binary keys + + + + + +} + +main();