Skip to content
This repository was archived by the owner on Sep 9, 2021. It is now read-only.

Commit ab2f2b9

Browse files
Alan Shawdaviddias
Alan Shaw
authored andcommitted
feat: refactor to async iterators (#25)
* refactor: async iterators Here's a proposal for the datastore interface that uses async/await and async iterators. See ipfs/js-ipfs#1670 for context. License: MIT Signed-off-by: Alan Shaw <alan.shaw@protocol.ai> * chore: use node.js 10 in CI License: MIT Signed-off-by: Alan Shaw <alan.shaw@protocol.ai> * chore: appease linter License: MIT Signed-off-by: Alan Shaw <alan.shaw@protocol.ai> * fix: remove unnecessary assertion License: MIT Signed-off-by: Alan Shaw <alan.shaw@protocol.ai>
1 parent c833535 commit ab2f2b9

File tree

11 files changed

+323
-522
lines changed

11 files changed

+323
-522
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ logs
1010
*.log
1111

1212
coverage
13+
.nyc_output
1314

1415
# Runtime data
1516
pids

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ lib-cov
1212

1313
# Coverage directory used by tools like istanbul
1414
coverage
15+
.nyc_output
1516

1617
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
1718
.grunt

.travis.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,8 @@ language: node_js
33

44
matrix:
55
include:
6-
- node_js: 6
6+
- node_js: 10
77
env: CXX=g++-4.8
8-
- node_js: 8
9-
env: CXX=g++-4.8
10-
# - node_js: stable
11-
# env: CXX=g++-4.8
128

139
script:
1410
- npm run lint

README.md

Lines changed: 39 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ const ShardingStore = require('datastore-core').ShardingDatatstore
4747
const NextToLast = require('datastore-core').shard.NextToLast
4848

4949
const fs = new FsStore('path/to/store')
50-
ShardingStore.createOrOpen(fs, new NextToLast(2), (err, flatfs) => {
51-
// flatfs now works like go-flatfs
52-
})
50+
51+
// flatfs now works like go-flatfs
52+
const flatfs = await ShardingStore.createOrOpen(fs, new NextToLast(2))
5353
```
5454

5555
## Install
5656

57-
```
57+
```sh
5858
$ npm install interface-datastore
5959
```
6060

@@ -67,22 +67,21 @@ const MemoryStore = require('interface-datastore').MemoryDatastore
6767
const MountStore = require('datastore-core').MountDatastore
6868
const Key = require('interface-datastore').Key
6969

70-
const store = new MountStore({prefix: new Key('/a'), datastore: new MemoryStore()})
70+
const store = new MountStore({ prefix: new Key('/a'), datastore: new MemoryStore() })
7171
```
7272

73-
### Testsuite
73+
### Test suite
7474

7575
Available under [`src/tests.js`](src/tests.js)
7676

7777
```js
7878
describe('mystore', () => {
7979
require('interface-datastore/src/tests')({
80-
setup (callback) {
81-
callback(null, instanceOfMyStore)
80+
async setup () {
81+
return instanceOfMyStore
8282
},
83-
teardown (callback) {
83+
async teardown () {
8484
// cleanup resources
85-
callback()
8685
}
8786
})
8887
})
@@ -99,12 +98,12 @@ const a = new Key('a')
9998
const b = new Key(new Buffer('hello'))
10099
```
101100

102-
The key scheme is inspired by file systems and Google App Engine key model. Keys are meant to be unique across a system. They are typical hierarchical, incorporating more and more specific namespaces. Thus keys can be deemed 'children' or 'ancestors' of other keys:
101+
The key scheme is inspired by file systems and Google App Engine key model. Keys are meant to be unique across a system. They are typically hierarchical, incorporating more and more specific namespaces. Thus keys can be deemed 'children' or 'ancestors' of other keys:
103102

104103
- `new Key('/Comedy')`
105104
- `new Key('/Comedy/MontyPython')`
106105

107-
Also, every namespace can be parametrized to embed relevant object information. For example, the Key `name` (most specific namespace) could include the object type:
106+
Also, every namespace can be parameterized to embed relevant object information. For example, the Key `name` (most specific namespace) could include the object type:
108107

109108
- `new Key('/Comedy/MontyPython/Actor:JohnCleese')`
110109
- `new Key('/Comedy/MontyPython/Sketch:CheeseShop')`
@@ -117,90 +116,65 @@ Also, every namespace can be parametrized to embed relevant object information.
117116
118117
These methods will be present on every datastore. `Key` always means an instance of the above mentioned Key type. Every datastore is generic over the `Value` type, though currently all backing implementations are implemented only for [`Buffer`](https://nodejs.org/docs/latest/api/buffer.html).
119118

120-
### `has(key, callback)`
119+
### `has(key)` -> `Promise<Boolean>`
121120

122121
- `key: Key`
123-
- `callback: function(Error, bool)`
124122

125123
Check for the existence of a given key
126124

127125
```js
128-
store.has(new Key('awesome'), (err, exists) => {
129-
if (err) {
130-
throw err
131-
}
132-
console.log('is it there', exists)
133-
})
126+
const exists = await store.has(new Key('awesome'))
127+
console.log('is it there', exists)
134128
```
135129

136-
### `put(key, value, callback)`
130+
### `put(key, value)` -> `Promise`
137131

138132
- `key: Key`
139133
- `value: Value`
140-
- `callback: function(Error)`
141134

142135
Store a value with the given key.
143136

144137
```js
145-
store.put(new Key('awesome'), new Buffer('datastores'), (err) => {
146-
if (err) {
147-
throw err
148-
}
149-
console.log('put content')
150-
})
138+
await store.put(new Key('awesome'), new Buffer('datastores'))
139+
console.log('put content')
151140
```
152141

153-
### `get(key, callback)`
142+
### `get(key)` -> `Promise<Value>`
154143

155144
- `key: Key`
156-
- `callback: function(Error, Value)`
157145

158146
Retrieve the value stored under the given key.
159147

160148
```js
161-
store.get(new Key('awesome'), (err, value) => {
162-
if (err) {
163-
throw err
164-
}
165-
console.log('got content: %s', value.toString())
166-
// => got content: datastore
167-
})
149+
const value = await store.get(new Key('awesome'))
150+
console.log('got content: %s', value.toString())
151+
// => got content: datastore
168152
```
169153

170-
### `delete(key, callback)`
154+
### `delete(key)` -> `Promise`
171155

172156
- `key: Key`
173-
- `callback: function(Error)`
174157

175158
Delete the content stored under the given key.
176159

177160
```js
178-
store.delete(new Key('awesome'), (err) => {
179-
if (err) {
180-
throw err
181-
}
182-
console.log('deleted awesome content :(')
183-
})
161+
await store.delete(new Key('awesome'))
162+
console.log('deleted awesome content :(')
184163
```
185164

186-
### `query(query)`
165+
### `query(query)` -> `Iterable`
187166

188167
- `query: Query` see below for possible values
189-
- Returns: `pull-stream source`
190168

191-
Search the store for some values. Returns a [pull-stream](https://pull-stream.github.io/) with each item being a `Value`.
169+
Search the store for some values. Returns an [Iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) with each item being a `Value`.
192170

193171
```js
194172
// retrieve __all__ values from the store
195-
pull(
196-
store.query({}),
197-
pull.collect((err, list) => {
198-
if (err) {
199-
console.error(err)
200-
}
201-
console.log('ALL THE VALUES', list)
202-
})
203-
)
173+
let list = []
174+
for await (const value of store.query({})) {
175+
list.push(value)
176+
}
177+
console.log('ALL THE VALUES', list)
204178
```
205179

206180
#### `Query`
@@ -210,9 +184,9 @@ Object in the form with the following optional properties
210184
- `prefix: string` (optional) - only return values where the key starts with this prefix
211185
- `filters: Array<Filter<Value>>` (optional) - filter the results according to the these functions
212186
- `orders: Array<Order<Value>>` (optional) - order the results according to these functions
213-
- `limit: number` (optional) - only return this many records
214-
- `offset: number` (optional) - skip this many records at the beginning
215-
- `keysOnly: bool` (optional) - Only return keys, no values.
187+
- `limit: Number` (optional) - only return this many records
188+
- `offset: Number` (optional) - skip this many records at the beginning
189+
- `keysOnly: Boolean` (optional) - Only return keys, no values.
216190

217191
### `batch()`
218192

@@ -225,13 +199,8 @@ for (let i = 0; i < 100; i++) {
225199
b.put(new Key(`hello${i}`), new Buffer(`hello world ${i}`))
226200
}
227201

228-
b.commit((err) => {
229-
if (err) {
230-
throw err
231-
}
232-
console.log('put 100 values')
233-
})
234-
202+
await b.commit()
203+
console.log('put 100 values')
235204
```
236205

237206
#### `put(key, value)`
@@ -247,21 +216,15 @@ Queue a put operation to the store.
247216

248217
Queue a delete operation to the store.
249218

250-
#### `commit(callback)`
251-
252-
- `callback: function(Error)`
219+
#### `commit()` -> `Promise`
253220

254221
Write all queued operations to the underyling store. The batch object should not be used after calling this.
255222

256-
### `open(callback)`
257-
258-
- `callback: function(Error)`
223+
### `open()` -> `Promise`
259224

260225
Opens the datastore, this is only needed if the store was closed before, otherwise this is taken care of by the constructor.
261226

262-
### `close(callback)`
263-
264-
- `callback: function(Error)`
227+
### `close()` -> `Promise`
265228

266229
Close the datastore, this should always be called to ensure resources are cleaned up.
267230

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: "{build}"
22

33
environment:
44
matrix:
5-
- nodejs_version: "6"
5+
- nodejs_version: "10"
66

77
matrix:
88
fast_finish: true

package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,14 @@
3434
},
3535
"homepage": "https://github.com/ipfs/interface-datastore#readme",
3636
"devDependencies": {
37-
"aegir": "^15.1.0",
37+
"aegir": "^17.1.1",
3838
"chai": "^4.1.2",
3939
"dirty-chai": "^2.0.1",
4040
"flow-bin": "~0.83.0"
4141
},
4242
"dependencies": {
43-
"async": "^2.6.1",
4443
"class-is": "^1.1.0",
4544
"err-code": "^1.1.2",
46-
"pull-defer": "~0.2.3",
47-
"pull-stream": "^3.6.9",
4845
"uuid": "^3.2.2"
4946
},
5047
"engines": {

0 commit comments

Comments
 (0)