Skip to content

Commit dc5c04a

Browse files
committed
Breaking: upgrade to abstract-level 2.0.0
See https://github.com/Level/abstract-level/blob/v2.0.0/UPGRADING.md
1 parent c94f9a4 commit dc5c04a

File tree

9 files changed

+69
-99
lines changed

9 files changed

+69
-99
lines changed

.github/workflows/sauce.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
- name: Set up node
1313
uses: actions/setup-node@v3
1414
with:
15-
node-version: 14
15+
node-version: 16
1616
- name: Install
1717
run: npm install
1818
env:

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
runs-on: ubuntu-latest
88
strategy:
99
matrix:
10-
node: [12, 14, 16]
10+
node: [16, 18, 20]
1111
name: Node ${{ matrix.node }}
1212
steps:
1313
- name: Checkout

README.md

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,6 @@ for await (const [key, value] of db.iterator({ gt: 'a' })) {
3838
}
3939
```
4040

41-
With callbacks:
42-
43-
```js
44-
db.put('example', { hello: 'world' }, (err) => {
45-
if (err) throw err
46-
47-
db.get('example', (err, value) => {
48-
if (err) throw err
49-
console.log(value) // { hello: 'world' }
50-
})
51-
})
52-
```
53-
5441
<!-- ## Browser support
5542
5643
[![Sauce Test Status](https://app.saucelabs.com/browser-matrix/level-ci.svg)](https://app.saucelabs.com/u/level-ci) -->

UPGRADING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
This document describes breaking changes and how to upgrade. For a complete list of changes including minor and patch releases, please refer to the [`CHANGELOG`](CHANGELOG.md).
44

5+
## 2.0.0
6+
7+
This release upgrades to `abstract-level` 2.0.0 which adds [hooks](https://github.com/Level/abstract-level#hooks) and drops callbacks, not-found errors and support of Node.js < 16. Please refer to the [upgrade guide of `abstract-level`](https://github.com/Level/abstract-level/blob/v2.0.0/UPGRADING.md).
8+
59
## 1.0.0
610

711
**Introducing `memory-level`: a fork of [`memdown`](https://github.com/Level/memdown) that removes the need for [`level-mem`](https://github.com/Level/mem), [`levelup`](https://github.com/Level/levelup) and more. It implements the [`abstract-level`](https://github.com/Level/abstract-level) interface instead of [`abstract-leveldown`](https://github.com/Level/abstract-leveldown) and thus has the same API as `level-mem` and `levelup` including encodings, promises and events. In addition, you can now choose to use Uint8Array instead of Buffer. Sublevels are builtin.**

index.d.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import {
22
AbstractLevel,
33
AbstractDatabaseOptions,
4-
AbstractOpenOptions,
5-
NodeCallback
4+
AbstractOpenOptions
65
} from 'abstract-level'
76

87
/**
@@ -22,8 +21,6 @@ export class MemoryLevel<KDefault = string, VDefault = string>
2221

2322
open (): Promise<void>
2423
open (options: OpenOptions): Promise<void>
25-
open (callback: NodeCallback<void>): void
26-
open (options: OpenOptions, callback: NodeCallback<void>): void
2724
}
2825

2926
/**

index.js

Lines changed: 48 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -56,25 +56,26 @@ function lte (value) {
5656
return compare(value, this[kUpperBound]) <= 0
5757
}
5858

59+
// TODO (v2): support signal
5960
class MemoryIterator extends AbstractIterator {
6061
constructor (db, options) {
6162
super(db, options)
6263
this[kInit](db[kTree], options)
6364
}
6465

65-
_next (callback) {
66-
if (!this[kIterator].valid) return this.nextTick(callback)
66+
async _next () {
67+
if (!this[kIterator].valid) return undefined
6768

6869
const key = this[kIterator].key
6970
const value = this[kIterator].value
7071

71-
if (!this[kTest](key)) return this.nextTick(callback)
72+
if (!this[kTest](key)) return undefined
7273

7374
this[kIterator][this[kAdvance]]()
74-
this.nextTick(callback, null, key, value)
75+
return [key, value]
7576
}
7677

77-
_nextv (size, options, callback) {
78+
async _nextv (size, options) {
7879
const it = this[kIterator]
7980
const entries = []
8081

@@ -83,10 +84,10 @@ class MemoryIterator extends AbstractIterator {
8384
it[this[kAdvance]]()
8485
}
8586

86-
this.nextTick(callback, null, entries)
87+
return entries
8788
}
8889

89-
_all (options, callback) {
90+
async _all (options) {
9091
const size = this.limit - this.count
9192
const it = this[kIterator]
9293
const entries = []
@@ -96,7 +97,7 @@ class MemoryIterator extends AbstractIterator {
9697
it[this[kAdvance]]()
9798
}
9899

99-
this.nextTick(callback, null, entries)
100+
return entries
100101
}
101102
}
102103

@@ -106,17 +107,17 @@ class MemoryKeyIterator extends AbstractKeyIterator {
106107
this[kInit](db[kTree], options)
107108
}
108109

109-
_next (callback) {
110-
if (!this[kIterator].valid) return this.nextTick(callback)
110+
async _next () {
111+
if (!this[kIterator].valid) return undefined
111112

112113
const key = this[kIterator].key
113-
if (!this[kTest](key)) return this.nextTick(callback)
114+
if (!this[kTest](key)) return undefined
114115

115116
this[kIterator][this[kAdvance]]()
116-
this.nextTick(callback, null, key)
117+
return key
117118
}
118119

119-
_nextv (size, options, callback) {
120+
async _nextv (size, options) {
120121
const it = this[kIterator]
121122
const keys = []
122123

@@ -125,10 +126,10 @@ class MemoryKeyIterator extends AbstractKeyIterator {
125126
it[this[kAdvance]]()
126127
}
127128

128-
this.nextTick(callback, null, keys)
129+
return keys
129130
}
130131

131-
_all (options, callback) {
132+
async _all (options) {
132133
const size = this.limit - this.count
133134
const it = this[kIterator]
134135
const keys = []
@@ -138,7 +139,7 @@ class MemoryKeyIterator extends AbstractKeyIterator {
138139
it[this[kAdvance]]()
139140
}
140141

141-
this.nextTick(callback, null, keys)
142+
return keys
142143
}
143144
}
144145

@@ -148,19 +149,19 @@ class MemoryValueIterator extends AbstractValueIterator {
148149
this[kInit](db[kTree], options)
149150
}
150151

151-
_next (callback) {
152-
if (!this[kIterator].valid) return this.nextTick(callback)
152+
async _next (options) {
153+
if (!this[kIterator].valid) return undefined
153154

154155
const key = this[kIterator].key
155156
const value = this[kIterator].value
156157

157-
if (!this[kTest](key)) return this.nextTick(callback)
158+
if (!this[kTest](key)) return undefined
158159

159160
this[kIterator][this[kAdvance]]()
160-
this.nextTick(callback, null, value)
161+
return value
161162
}
162163

163-
_nextv (size, options, callback) {
164+
async _nextv (size, options) {
164165
const it = this[kIterator]
165166
const values = []
166167

@@ -169,10 +170,10 @@ class MemoryValueIterator extends AbstractValueIterator {
169170
it[this[kAdvance]]()
170171
}
171172

172-
this.nextTick(callback, null, values)
173+
return values
173174
}
174175

175-
_all (options, callback) {
176+
async _all (options) {
176177
const size = this.limit - this.count
177178
const it = this[kIterator]
178179
const values = []
@@ -182,7 +183,7 @@ class MemoryValueIterator extends AbstractValueIterator {
182183
it[this[kAdvance]]()
183184
}
184185

185-
this.nextTick(callback, null, values)
186+
return values
186187
}
187188
}
188189

@@ -270,6 +271,7 @@ class MemoryLevel extends AbstractLevel {
270271
}
271272

272273
// To help migrating from level-mem to abstract-level
274+
// TODO (v2): remove
273275
if (typeof location === 'function' || typeof options === 'function' || typeof _ === 'function') {
274276
throw new ModuleError('The levelup-style callback argument has been removed', {
275277
code: 'LEVEL_LEGACY'
@@ -297,39 +299,30 @@ class MemoryLevel extends AbstractLevel {
297299
this[kTree] = createRBT(compare)
298300
}
299301

300-
_put (key, value, options, callback) {
302+
async _put (key, value, options) {
301303
const it = this[kTree].find(key)
302304

303305
if (it.valid) {
304306
this[kTree] = it.update(value)
305307
} else {
306308
this[kTree] = this[kTree].insert(key, value)
307309
}
308-
309-
this.nextTick(callback)
310310
}
311311

312-
_get (key, options, callback) {
313-
const value = this[kTree].get(key)
314-
315-
if (typeof value === 'undefined') {
316-
// TODO: use error code (not urgent, abstract-level normalizes this)
317-
return this.nextTick(callback, new Error('NotFound'))
318-
}
319-
320-
this.nextTick(callback, null, value)
312+
async _get (key, options) {
313+
// Is undefined if not found
314+
return this[kTree].get(key)
321315
}
322316

323-
_getMany (keys, options, callback) {
324-
this.nextTick(callback, null, keys.map(key => this[kTree].get(key)))
317+
async _getMany (keys, options) {
318+
return keys.map(key => this[kTree].get(key))
325319
}
326320

327-
_del (key, options, callback) {
321+
async _del (key, options) {
328322
this[kTree] = this[kTree].remove(key)
329-
this.nextTick(callback)
330323
}
331324

332-
_batch (operations, options, callback) {
325+
async _batch (operations, options) {
333326
let tree = this[kTree]
334327

335328
for (const op of operations) {
@@ -344,38 +337,35 @@ class MemoryLevel extends AbstractLevel {
344337
}
345338

346339
this[kTree] = tree
347-
this.nextTick(callback)
348340
}
349341

350-
_clear (options, callback) {
342+
async _clear (options) {
351343
if (options.limit === -1 && !Object.keys(options).some(isRangeOption)) {
352344
// Delete everything by creating a new empty tree.
353345
this[kTree] = createRBT(compare)
354-
return this.nextTick(callback)
346+
return
355347
}
356348

357349
const iterator = this._keys({ ...options })
358350
const limit = iterator.limit
359351

360352
let count = 0
361353

362-
const loop = () => {
354+
while (true) {
363355
// TODO: add option to control "batch size"
364356
for (let i = 0; i < 500; i++) {
365-
if (++count > limit) return callback()
366-
if (!iterator[kIterator].valid) return callback()
367-
if (!iterator[kTest](iterator[kIterator].key)) return callback()
357+
if (++count > limit) return
358+
if (!iterator[kIterator].valid) return
359+
if (!iterator[kTest](iterator[kIterator].key)) return
368360

369361
// Must also include changes made in parallel to clear()
370362
this[kTree] = this[kTree].remove(iterator[kIterator].key)
371363
iterator[kIterator][iterator[kAdvance]]()
372364
}
373365

374366
// Some time to breathe
375-
this.nextTick(loop)
367+
await breathe()
376368
}
377-
378-
this.nextTick(loop)
379369
}
380370

381371
_iterator (options) {
@@ -393,18 +383,17 @@ class MemoryLevel extends AbstractLevel {
393383

394384
exports.MemoryLevel = MemoryLevel
395385

396-
// Use setImmediate() in Node.js to allow IO in between our callbacks
386+
let breathe
387+
388+
// Use setImmediate() in Node.js to allow IO in between work
397389
if (typeof process !== 'undefined' && !process.browser && typeof global !== 'undefined' && typeof global.setImmediate === 'function') {
398390
const setImmediate = global.setImmediate
399391

400-
// Automatically applies to iterators, sublevels and chained batches as well
401-
MemoryLevel.prototype.nextTick = function (fn, ...args) {
402-
if (args.length === 0) {
403-
setImmediate(fn)
404-
} else {
405-
setImmediate(() => fn(...args))
406-
}
392+
breathe = function () {
393+
return new Promise(setImmediate)
407394
}
395+
} else {
396+
breathe = async function () {}
408397
}
409398

410399
function isRangeOption (k) {

package.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"main": "index.js",
88
"types": "./index.d.ts",
99
"scripts": {
10-
"test": "standard && hallmark && (nyc -s node test.js | faucet) && nyc report",
10+
"test": "standard && hallmark && (nyc -s node test.js | tap-arc) && nyc report",
11+
"test-pessimistic": "node test.js | tap-arc -pv",
1112
"test-browsers": "airtap --coverage --verbose test.js",
1213
"test-browsers-local": "airtap --coverage -p local test.js",
1314
"coverage": "nyc report -r lcovonly"
@@ -19,22 +20,22 @@
1920
"CHANGELOG.md"
2021
],
2122
"dependencies": {
22-
"abstract-level": "^1.0.0",
23+
"abstract-level": "^2.0.0",
2324
"functional-red-black-tree": "^1.0.1",
2425
"module-error": "^1.0.1"
2526
},
2627
"devDependencies": {
27-
"@voxpelli/tsconfig": "^4.0.0",
28+
"@voxpelli/tsconfig": "^15.0.0",
2829
"airtap": "^4.0.3",
2930
"airtap-playwright": "^1.0.1",
3031
"airtap-sauce": "^1.1.0",
3132
"buffer": "^6.0.3",
32-
"faucet": "^0.0.3",
3333
"hallmark": "^4.0.0",
3434
"nyc": "^15.1.0",
3535
"standard": "^17.0.0",
36+
"tap-arc": "^0.3.5",
3637
"tape": "^5.0.1",
37-
"typescript": "^4.5.5"
38+
"typescript": "^5.6.3"
3839
},
3940
"repository": {
4041
"type": "git",
@@ -49,6 +50,6 @@
4950
"memory"
5051
],
5152
"engines": {
52-
"node": ">=12"
53+
"node": ">=16"
5354
}
5455
}

0 commit comments

Comments
 (0)