1- import { Key } from 'interface-datastore'
1+ import { Batch , Key , KeyQuery , Pair , Query } from 'interface-datastore'
22import { BaseDatastore , Errors } from 'datastore-core'
33import filter from 'it-filter'
44import map from 'it-map'
55import take from 'it-take'
66import sort from 'it-sort'
77import { Level } from 'level'
8+ import type { DatabaseOptions , OpenOptions , IteratorOptions } from 'level'
89
9- /**
10- * @typedef {import('interface-datastore').Datastore } Datastore
11- * @typedef {import('interface-datastore').Pair } Pair
12- * @typedef {import('interface-datastore').Batch } Batch
13- * @typedef {import('interface-datastore').Query } Query
14- * @typedef {import('interface-datastore').KeyQuery } KeyQuery
15- * @typedef {import('interface-datastore').Options } QueryOptions
16- * @typedef {import('abstract-level').AbstractLevel<any, string, Uint8Array> } LevelDb
17- */
10+ interface BatchPut {
11+ type : 'put'
12+ key : string
13+ value : Uint8Array
14+ }
15+
16+ interface BatchDel {
17+ type : 'del'
18+ key : string
19+ }
20+
21+ type BatchOp = BatchPut | BatchDel
1822
1923/**
2024 * A datastore backed by leveldb
2125 */
2226export class LevelDatastore extends BaseDatastore {
23- /**
24- * @param {string | LevelDb } path
25- * @param {import('level').DatabaseOptions<string, Uint8Array> & import('level').OpenOptions } [opts]
26- */
27- constructor ( path , opts = { } ) {
27+ public db : Level < string , Uint8Array >
28+ private readonly opts : OpenOptions
29+
30+ constructor ( path : string | Level < string , Uint8Array > , opts : DatabaseOptions < string , Uint8Array > & OpenOptions = { } ) {
2831 super ( )
2932
30- /** @type {LevelDb } */
3133 this . db = typeof path === 'string'
3234 ? new Level ( path , {
3335 ...opts ,
@@ -36,91 +38,77 @@ export class LevelDatastore extends BaseDatastore {
3638 } )
3739 : path
3840
39- /** @type {import('level').OpenOptions } */
4041 this . opts = {
4142 createIfMissing : true ,
4243 compression : false , // same default as go
4344 ...opts
4445 }
4546 }
4647
47- async open ( ) {
48+ async open ( ) : Promise < void > {
4849 try {
4950 await this . db . open ( this . opts )
50- } catch ( /** @type { any } */ err ) {
51+ } catch ( err : any ) {
5152 throw Errors . dbOpenFailedError ( err )
5253 }
5354 }
5455
55- /**
56- * @param {Key } key
57- * @param {Uint8Array } value
58- */
59- async put ( key , value ) {
56+ async put ( key : Key , value : Uint8Array ) : Promise < void > {
6057 try {
6158 await this . db . put ( key . toString ( ) , value )
62- } catch ( /** @type { any } */ err ) {
59+ } catch ( err : any ) {
6360 throw Errors . dbWriteFailedError ( err )
6461 }
6562 }
6663
67- /**
68- * @param {Key } key
69- * @returns {Promise<Uint8Array> }
70- */
71- async get ( key ) {
64+ async get ( key : Key ) : Promise < Uint8Array > {
7265 let data
7366 try {
7467 data = await this . db . get ( key . toString ( ) )
75- } catch ( /** @type {any } */ err ) {
76- if ( err . notFound ) throw Errors . notFoundError ( err )
68+ } catch ( err : any ) {
69+ if ( err . notFound != null ) {
70+ throw Errors . notFoundError ( err )
71+ }
72+
7773 throw Errors . dbWriteFailedError ( err )
7874 }
7975 return data
8076 }
8177
82- /**
83- * @param {Key } key
84- * @returns {Promise<boolean> }
85- */
86- async has ( key ) {
78+ async has ( key : Key ) : Promise < boolean > {
8779 try {
8880 await this . db . get ( key . toString ( ) )
89- } catch ( /** @type {any } */ err ) {
90- if ( err . notFound ) return false
81+ } catch ( err : any ) {
82+ if ( err . notFound != null ) {
83+ return false
84+ }
85+
9186 throw err
9287 }
9388 return true
9489 }
9590
96- /**
97- * @param {Key } key
98- * @returns {Promise<void> }
99- */
100- async delete ( key ) {
91+ async delete ( key : Key ) : Promise < void > {
10192 try {
10293 await this . db . del ( key . toString ( ) )
103- } catch ( /** @type { any } */ err ) {
94+ } catch ( err : any ) {
10495 throw Errors . dbDeleteFailedError ( err )
10596 }
10697 }
10798
108- close ( ) {
109- return this . db && this . db . close ( )
99+ async close ( ) : Promise < void > {
100+ await this . db . close ( )
110101 }
111102
112- /**
113- * @returns {Batch }
114- */
115- batch ( ) {
116- /** @type {Array<{ type: 'put', key: string, value: Uint8Array; } | { type: 'del', key: string }> } */
117- const ops = [ ]
103+ batch ( ) : Batch {
104+ const ops : BatchOp [ ] = [ ]
105+
118106 return {
119107 put : ( key , value ) => {
120108 ops . push ( {
121109 type : 'put' ,
122110 key : key . toString ( ) ,
123- value : value
111+ value
124112 } )
125113 } ,
126114 delete : ( key ) => {
@@ -129,16 +117,17 @@ export class LevelDatastore extends BaseDatastore {
129117 key : key . toString ( )
130118 } )
131119 } ,
132- commit : ( ) => {
133- return this . db . batch ( ops )
120+ commit : async ( ) => {
121+ if ( this . db . batch == null ) {
122+ throw new Error ( 'Batch operations unsupported by underlying Level' )
123+ }
124+
125+ await this . db . batch ( ops )
134126 }
135127 }
136128 }
137129
138- /**
139- * @param {Query } q
140- */
141- query ( q ) {
130+ query ( q : Query ) : AsyncIterable < Pair > {
142131 let it = this . _query ( {
143132 values : true ,
144133 prefix : q . prefix
@@ -153,22 +142,19 @@ export class LevelDatastore extends BaseDatastore {
153142 }
154143
155144 const { offset, limit } = q
156- if ( offset ) {
145+ if ( offset != null ) {
157146 let i = 0
158147 it = filter ( it , ( ) => i ++ >= offset )
159148 }
160149
161- if ( limit ) {
150+ if ( limit != null ) {
162151 it = take ( it , limit )
163152 }
164153
165154 return it
166155 }
167156
168- /**
169- * @param {KeyQuery } q
170- */
171- queryKeys ( q ) {
157+ queryKeys ( q : KeyQuery ) : AsyncIterable < Key > {
172158 let it = map ( this . _query ( {
173159 values : false ,
174160 prefix : q . prefix
@@ -183,27 +169,20 @@ export class LevelDatastore extends BaseDatastore {
183169 }
184170
185171 const { offset, limit } = q
186- if ( offset ) {
172+ if ( offset != null ) {
187173 let i = 0
188174 it = filter ( it , ( ) => i ++ >= offset )
189175 }
190176
191- if ( limit ) {
177+ if ( limit != null ) {
192178 it = take ( it , limit )
193179 }
194180
195181 return it
196182 }
197183
198- /**
199- * @param {object } opts
200- * @param {boolean } opts.values
201- * @param {string } [opts.prefix]
202- * @returns {AsyncIterable<Pair> }
203- */
204- _query ( opts ) {
205- /** @type {import('level').IteratorOptions<string, Uint8Array> } */
206- const iteratorOpts = {
184+ _query ( opts : { values : boolean , prefix ?: string } ) : AsyncIterable < Pair > {
185+ const iteratorOpts : IteratorOptions < string , Uint8Array > = {
207186 keys : true ,
208187 keyEncoding : 'buffer' ,
209188 values : opts . values
@@ -220,7 +199,7 @@ export class LevelDatastore extends BaseDatastore {
220199
221200 const iterator = this . db . iterator ( iteratorOpts )
222201
223- if ( iterator [ Symbol . asyncIterator ] ) {
202+ if ( iterator [ Symbol . asyncIterator ] != null ) {
224203 return levelIteratorToIterator ( iterator )
225204 }
226205
@@ -234,47 +213,45 @@ export class LevelDatastore extends BaseDatastore {
234213 }
235214}
236215
237- /**
238- * @param {import('level').Iterator<LevelDb, string, Uint8Array> } li - Level iterator
239- * @returns {AsyncIterable<Pair> }
240- */
241- async function * levelIteratorToIterator ( li ) {
216+ async function * levelIteratorToIterator ( li : AsyncIterable < [ string , Uint8Array ] > & { close : ( ) => Promise < void > } ) : AsyncIterable < Pair > {
242217 for await ( const [ key , value ] of li ) {
243218 yield { key : new Key ( key , false ) , value }
244219 }
245220
246221 await li . close ( )
247222}
248223
249- /**
250- * @typedef {object } LevelIterator
251- * @property {(cb: (err: Error, key: string | Uint8Array | null, value: any)=> void)=>void } next
252- * @property {(cb: (err: Error) => void) => void } end
253- */
224+ interface OldLevelIterator {
225+ next : ( cb : ( err : Error , key : string | Uint8Array | null , value : any ) => void ) => void
226+ end : ( cb : ( err : Error ) => void ) => void
227+ }
254228
255- /**
256- * @param {LevelIterator } li - Level iterator
257- * @returns {AsyncIterable<Pair> }
258- */
259- function oldLevelIteratorToIterator ( li ) {
229+ function oldLevelIteratorToIterator ( li : OldLevelIterator ) : AsyncIterable < Pair > {
260230 return {
261231 [ Symbol . asyncIterator ] ( ) {
262232 return {
263- next : ( ) => new Promise ( ( resolve , reject ) => {
233+ next : async ( ) => await new Promise ( ( resolve , reject ) => {
264234 li . next ( ( err , key , value ) => {
265- if ( err ) return reject ( err )
235+ if ( err != null ) {
236+ reject ( err ) ; return
237+ }
266238 if ( key == null ) {
267- return li . end ( err => {
268- if ( err ) return reject ( err )
239+ li . end ( err => {
240+ if ( err != null ) {
241+ reject ( err )
242+ return
243+ }
269244 resolve ( { done : true , value : undefined } )
270- } )
245+ } ) ; return
271246 }
272247 resolve ( { done : false , value : { key : new Key ( key , false ) , value } } )
273248 } )
274249 } ) ,
275- return : ( ) => new Promise ( ( resolve , reject ) => {
250+ return : async ( ) => await new Promise ( ( resolve , reject ) => {
276251 li . end ( err => {
277- if ( err ) return reject ( err )
252+ if ( err != null ) {
253+ reject ( err ) ; return
254+ }
278255 resolve ( { done : true , value : undefined } )
279256 } )
280257 } )
0 commit comments