Skip to content

Commit 85f60ad

Browse files
dirkmczcstarr
authored andcommitted
fix: several bug fixes
1 parent bd99272 commit 85f60ad

14 files changed

+221
-176
lines changed

README.md

+41-60
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,9 @@ Example:
107107
const Repo = require('ipfs-repo')
108108
const repo = new Repo('/tmp/ipfs-repo')
109109

110-
repo.init({ cool: 'config' }, (err) => {
111-
if (err) {
112-
throw err
113-
}
114-
115-
repo.open((err) => {
116-
if (err) {
117-
throw err
118-
}
119-
120-
console.log('repo is ready')
121-
})
122-
})
110+
await repo.init({ cool: 'config' })
111+
await repo.open()
112+
console.log('repo is ready')
123113
```
124114

125115
This now has created the following structure, either on disk or as an in memory representation:
@@ -157,63 +147,61 @@ Arguments:
157147
const repo = new Repo('path/to/repo')
158148
```
159149

160-
#### `repo.init (callback)`
150+
#### `Promise repo.init ()`
161151

162152
Creates the necessary folder structure inside the repo.
163153

164-
#### `repo.open (callback)`
154+
#### `Promise repo.open ()`
165155

166156
[Locks](https://en.wikipedia.org/wiki/Record_locking) the repo to prevent conflicts arising from simultaneous access.
167157

168-
#### `repo.close (callback)`
158+
#### `Promise repo.close ()`
169159

170160
Unlocks the repo.
171161

172-
#### `repo.exists (callback)`
162+
#### `Promise<boolean> repo.exists ()`
173163

174-
Tells whether this repo exists or not. Calls back with `(err, bool)`.
164+
Tells whether this repo exists or not. Returns a boolean.
175165

176166
### Repos
177167

178168
Root repo:
179169

180-
#### `repo.put (key, value:Buffer, callback)`
170+
#### `Promise repo.put (key, value:Buffer)`
181171

182172
Put a value at the root of the repo.
183173

184174
* `key` can be a buffer, a string or a [Key](https://github.com/ipfs/interface-datastore#keys).
185175

186-
#### `repo.get (key, callback)`
176+
#### `Promise<value> repo.get (key)`
187177

188178
Get a value at the root of the repo.
189179

190180
* `key` can be a buffer, a string or a [Key](https://github.com/ipfs/interface-datastore#keys).
191-
* `callback` is a callback function `function (err, result:Buffer)`
192181

193182
[Blocks](https://github.com/ipfs/js-ipfs-block#readme):
194183

195-
#### `repo.blocks.put (block:Block, callback)`
184+
#### `Promise repo.blocks.put (block:Block)`
196185

197186
* `block` should be of type [Block](https://github.com/ipfs/js-ipfs-block#readme).
198187

199-
#### `repo.blocks.putMany (blocks, callback)`
188+
#### `Promise repo.blocks.putMany (blocks)`
200189

201190
Put many blocks.
202191

203192
* `block` should be an array of type [Block](https://github.com/ipfs/js-ipfs-block#readme).
204193

205-
#### `repo.blocks.get (cid, callback)`
194+
#### `Promise<Buffer> repo.blocks.get (cid)`
206195

207196
Get block.
208197

209198
* `cid` is the content id of [type CID](https://github.com/ipld/js-cid#readme).
210-
* `callback` is a callback function `function (err, result:Buffer)`
211199

212200
Datastore:
213201

214202
#### `repo.datastore`
215203

216-
This is contains a full implementation of [the `interface-datastore` API](https://github.com/ipfs/interface-datastore#api).
204+
This contains a full implementation of [the `interface-datastore` API](https://github.com/ipfs/interface-datastore#api).
217205

218206

219207
### Utils
@@ -222,77 +210,70 @@ This is contains a full implementation of [the `interface-datastore` API](https:
222210

223211
Instead of using `repo.set('config')` this exposes an API that allows you to set and get a decoded config object, as well as, in a safe manner, change any of the config values individually.
224212

225-
##### `repo.config.set(key:string, value, callback)`
213+
##### `Promise repo.config.set(key:string, value)`
226214

227215
Set a config value. `value` can be any object that is serializable to JSON.
228216

229217
* `key` is a string specifying the object path. Example:
230218

231219
```js
232-
repo.config.set('a.b.c', 'c value', (err) => {
233-
if (err) { throw err }
234-
repo.config.get((err, config) => {
235-
if (err) { throw err }
236-
assert.equal(config.a.b.c, 'c value')
237-
})
238-
})
220+
await repo.config.set('a.b.c', 'c value')
221+
const config = await repo.config.get()
222+
assert.equal(config.a.b.c, 'c value')
239223
```
240224

241-
##### `repo.config.get(value, callback)`
225+
##### `Promise repo.config.set(value)`
242226

243227
Set the whole config value. `value` can be any object that is serializable to JSON.
244228

245-
##### `repo.config.get(key:string, callback)`
229+
##### `Promise<string> repo.config.get(key:string)`
246230

247-
Get a config value. `callback` is a function with the signature: `function (err, value)`, wehre the `
248-
value` is of the same type that was set before.
231+
Get a config value. Returns the same type that was set before.
249232

250233
* `key` is a string specifying the object path. Example:
251234

252235
```js
253-
repo.config.get('a.b.c', (err, value) => {
254-
if (err) { throw err }
255-
console.log('config.a.b.c = ', value)
256-
})
236+
const value = await repo.config.get('a.b.c')
237+
console.log('config.a.b.c = ', value)
257238
```
258239

259-
##### `repo.config.get(callback)`
240+
##### `Promise<Object> repo.config.get()`
260241

261-
Get the entire config value. `callback` is a function with the signature: `function (err, configValue:Object)`.
242+
Get the entire config value.
262243

263-
#### `repo.config.exists(callback)`
244+
#### `Promise<boolean> repo.config.exists()`
264245

265-
Whether the config sub-repo exists. Calls back with `(err, bool)`.
246+
Whether the config sub-repo exists.
266247

267248
#### `repo.version`
268249

269-
##### `repo.version.get (callback)`
250+
##### `Promise<number> repo.version.get ()`
270251

271-
Gets the repo version.
252+
Gets the repo version (an integer).
272253

273-
##### `repo.version.set (version:number, callback)`
254+
##### `Promise repo.version.set (version:number)`
274255

275256
Sets the repo version
276257

277258
#### `repo.apiAddr`
278259

279-
#### `repo.apiAddr.get (callback)`
260+
#### `Promise<string> repo.apiAddr.get ()`
280261

281262
Gets the API address.
282263

283-
#### `repo.apiAddr.set (value, callback)`
264+
#### `Promise repo.apiAddr.set (value)`
284265

285266
Sets the API address.
286267

287268
* `value` should be a [Multiaddr](https://github.com/multiformats/js-multiaddr) or a String representing a valid one.
288269

289-
### `repo.stat ([options], callback)`
270+
### `Promise<Object> repo.stat ([options])`
290271

291272
Gets the repo status.
292273

293274
`options` is an object which might contain the key `human`, which is a boolean indicating whether or not the `repoSize` should be displayed in MiB or not.
294275

295-
`callback` is a function with the signature `function (err, stats)`, where `stats` is an Object with the following keys:
276+
Returns an Object with the following keys:
296277

297278
- `numObjects`
298279
- `repoPath`
@@ -311,27 +292,27 @@ const memoryLock = require('ipfs-repo/src/lock-memory') // Default in browser
311292

312293
You can also provide your own custom Lock. It must be an object with the following interface:
313294

314-
#### `lock.lock (dir, callback)`
295+
#### `Promise lock.lock (dir)`
315296

316-
Sets the lock if one does not already exist. If a lock already exists, `callback` should be called with an error.
297+
Sets the lock if one does not already exist. If a lock already exists, should throw an error.
317298

318299
`dir` is a string to the directory the lock should be created at. The repo typically creates the lock at its root.
319300

320-
`callback` is a function with the signature `function (err, closer)`, where `closer` has a `close` method for removing the lock.
301+
Returns `closer`, where `closer` has a `close` method for removing the lock.
321302

322-
##### `closer.close (callback)`
303+
##### `Promise closer.close ()`
323304

324305
Closes the lock created by `lock.open`
325306

326-
`callback` is a function with the signature `function (err)`. If no error was returned, the lock was successfully removed.
307+
If no error was thrown, the lock was successfully removed.
327308

328-
#### `lock.locked (dir, callback)`
309+
#### `Promise<boolean> lock.locked (dir)`
329310

330311
Checks the existence of the lock.
331312

332313
`dir` is a string to the directory to check for the lock. The repo typically checks for the lock at its root.
333314

334-
`callback` is a function with the signature `function (err, boolean)`, where `boolean` indicates the existence of the lock.
315+
Returns a `boolean` indicating the existence of the lock.
335316

336317
## Notes
337318

example.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
'use strict'
22

3-
const Repo = require('ipfs-repo')
4-
const repo = new Repo('/Users/awesome/.jsipfs')
3+
const Repo = require('ipfs-repo');
54

6-
repo.init({ my: 'config' })
7-
.then(repo.open)
8-
.then(() => console.log('repo is ready'))
5+
(async () => {
6+
const repo = new Repo('/Users/awesome/.jsipfs')
7+
8+
await repo.init({ my: 'config' })
9+
await repo.open()
10+
console.log('repo is ready')
11+
})()

package.json

+7-4
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,19 @@
4444
"lodash": "^4.17.11",
4545
"memdown": "^3.0.0",
4646
"multihashes": "~0.4.14",
47-
"multihashing-async": "~0.5.1",
47+
"multihashing-async": "multiformats/js-multihashing-async#feat/async-iterators",
4848
"ncp": "^2.0.0",
4949
"rimraf": "^2.6.2"
5050
},
5151
"dependencies": {
5252
"base32.js": "~0.1.0",
5353
"bignumber.js": "^8.0.2",
5454
"cids": "~0.5.7",
55-
"datastore-core": "~0.6.0",
56-
"datastore-fs": "~0.7.0",
55+
"datastore-core": "git://github.com/zcstarr/js-datastore-core.git",
56+
"datastore-fs": "git://github.com/zcstarr/js-datastore-fs.git",
5757
"datastore-level": "git://github.com/ipfs/js-datastore-level.git#refactor/async-iterators",
5858
"debug": "^4.1.0",
59+
"err-code": "^1.1.2",
5960
"interface-datastore": "git://github.com/ipfs/interface-datastore.git#refactor/async-iterators",
6061
"ipfs-block": "~0.8.0",
6162
"lodash.get": "^4.4.2",
@@ -64,7 +65,9 @@
6465
"multiaddr": "^6.0.0",
6566
"proper-lockfile": "^3.2.0",
6667
"pull-stream": "^3.6.9",
67-
"sort-keys": "^2.0.0"
68+
"p-queue": "^3.1.0",
69+
"sort-keys": "^2.0.0",
70+
"streaming-iterables": "^4.0.2"
6871
},
6972
"license": "MIT",
7073
"contributors": [

src/api-addr.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module.exports = (store) => {
1010
/**
1111
* Get the current configuration from the repo.
1212
*
13-
* @returns {Promise<Object>}
13+
* @returns {Promise<string>}
1414
*/
1515
async get () {
1616
const value = await store.get(apiFile)

src/blockstore.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ function createBaseStore (store) {
153153
*
154154
* @returns {Promise<void>}
155155
*/
156-
async close () {
156+
close () {
157157
return store.close()
158158
}
159159
}

src/config.js

+23-19
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict'
22

33
const Key = require('interface-datastore').Key
4-
const queue = require('async/queue')
4+
const Queue = require('p-queue')
55
const _get = require('lodash.get')
66
const _set = require('lodash.set')
77
const _has = require('lodash.has')
@@ -10,8 +10,7 @@ const Buffer = require('safe-buffer').Buffer
1010
const configKey = new Key('config')
1111

1212
module.exports = (store) => {
13-
const setQueue = queue(_doSet, 1)
14-
setQueue.error = (err) => { throw err }
13+
const setQueue = new Queue({ concurrency: 1 })
1514

1615
const configStore = {
1716
/**
@@ -24,16 +23,17 @@ module.exports = (store) => {
2423
if (!key) {
2524
key = undefined
2625
}
27-
return store.get(configKey)
28-
.then((encodedValue) => {
29-
const config = JSON.parse(encodedValue.toString())
30-
if (key !== undefined && !_has(config, key)) {
31-
throw new Error(`Key ${key} does not exist in config`)
32-
}
33-
const value = key !== undefined ? _get(config, key) : config
34-
return value
35-
})
26+
27+
const encodedValue = await store.get(configKey)
28+
const config = JSON.parse(encodedValue.toString())
29+
if (key !== undefined && !_has(config, key)) {
30+
throw new Error(`Key ${key} does not exist in config`)
31+
}
32+
33+
const value = key !== undefined ? _get(config, key) : config
34+
return value
3635
},
36+
3737
/**
3838
* Set the current configuration for this repo.
3939
*
@@ -42,26 +42,29 @@ module.exports = (store) => {
4242
* @returns {void}
4343
*/
4444
set (key, value) {
45-
if (!key || typeof key !== 'string') {
46-
throw new Error('Invalid key type')
45+
if (arguments.length === 1) {
46+
value = key
47+
key = undefined
48+
} else if (!key || typeof key !== 'string') {
49+
throw new Error('Invalid key type: ' + typeof key)
4750
}
4851

4952
if (value === undefined || Buffer.isBuffer(value)) {
50-
throw new Error('Invalid value type')
53+
throw new Error('Invalid value type: ' + typeof value)
5154
}
5255

53-
setQueue.push({
56+
return setQueue.add(() => _doSet({
5457
key: key,
5558
value: value
56-
})
59+
}))
5760
},
5861

5962
/**
6063
* Check if a config file exists.
6164
*
6265
* @returns {Promise<bool>}
6366
*/
64-
async exists () {
67+
exists () {
6568
return store.has(configKey)
6669
}
6770
}
@@ -74,8 +77,9 @@ module.exports = (store) => {
7477
if (key) {
7578
const config = await configStore.get()
7679
_set(config, key, value)
77-
await _saveAll(config)
80+
return _saveAll(config)
7881
}
82+
return _saveAll(value)
7983
}
8084

8185
function _saveAll (config) {

src/errors/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
'use strict'
22

33
exports.ERR_REPO_NOT_INITIALIZED = 'ERR_REPO_NOT_INITIALIZED'
4+
exports.ERR_REPO_ALREADY_OPEN = 'ERR_REPO_ALREADY_OPEN'
5+
exports.ERR_REPO_ALREADY_CLOSED = 'ERR_REPO_ALREADY_CLOSED'

0 commit comments

Comments
 (0)