@@ -22,7 +22,7 @@ import { Level } from 'level'
22
22
export class LevelDatastore extends BaseDatastore {
23
23
/**
24
24
* @param {string | LevelDb } path
25
- * @param {import('level').DatabaseOptions<string, Uint8Array> } [opts]
25
+ * @param {import('level').DatabaseOptions<string, Uint8Array> & import('level').OpenOptions } [opts]
26
26
*/
27
27
constructor ( path , opts = { } ) {
28
28
super ( )
@@ -35,11 +35,18 @@ export class LevelDatastore extends BaseDatastore {
35
35
valueEncoding : 'view'
36
36
} )
37
37
: path
38
+
39
+ /** @type {import('level').OpenOptions } */
40
+ this . opts = {
41
+ createIfMissing : true ,
42
+ compression : false , // same default as go
43
+ ...opts
44
+ }
38
45
}
39
46
40
47
async open ( ) {
41
48
try {
42
- await this . db . open ( )
49
+ await this . db . open ( this . opts )
43
50
} catch ( /** @type {any } */ err ) {
44
51
throw Errors . dbOpenFailedError ( err )
45
52
}
@@ -211,7 +218,19 @@ export class LevelDatastore extends BaseDatastore {
211
218
iteratorOpts . lt = prefix + '\xFF'
212
219
}
213
220
214
- return levelIteratorToIterator ( this . db . iterator ( iteratorOpts ) )
221
+ const iterator = this . db . iterator ( iteratorOpts )
222
+
223
+ if ( iterator [ Symbol . asyncIterator ] ) {
224
+ return levelIteratorToIterator ( iterator )
225
+ }
226
+
227
+ // @ts -expect-error support older level
228
+ if ( iterator . next != null && iterator . end != null ) {
229
+ // @ts -expect-error support older level
230
+ return oldLevelIteratorToIterator ( iterator )
231
+ }
232
+
233
+ throw new Error ( 'Level returned incompatible iterator' )
215
234
}
216
235
}
217
236
@@ -226,3 +245,40 @@ async function * levelIteratorToIterator (li) {
226
245
227
246
await li . close ( )
228
247
}
248
+
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
+ */
254
+
255
+ /**
256
+ * @param {LevelIterator } li - Level iterator
257
+ * @returns {AsyncIterable<Pair> }
258
+ */
259
+ function oldLevelIteratorToIterator ( li ) {
260
+ return {
261
+ [ Symbol . asyncIterator ] ( ) {
262
+ return {
263
+ next : ( ) => new Promise ( ( resolve , reject ) => {
264
+ li . next ( ( err , key , value ) => {
265
+ if ( err ) return reject ( err )
266
+ if ( key == null ) {
267
+ return li . end ( err => {
268
+ if ( err ) return reject ( err )
269
+ resolve ( { done : true , value : undefined } )
270
+ } )
271
+ }
272
+ resolve ( { done : false , value : { key : new Key ( key , false ) , value } } )
273
+ } )
274
+ } ) ,
275
+ return : ( ) => new Promise ( ( resolve , reject ) => {
276
+ li . end ( err => {
277
+ if ( err ) return reject ( err )
278
+ resolve ( { done : true , value : undefined } )
279
+ } )
280
+ } )
281
+ }
282
+ }
283
+ }
284
+ }
0 commit comments