Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

Commit 75bb627

Browse files
committed
Merge pull request #200 from ipfs/promise
feat: Add promise based api
2 parents 3675e5f + 9b74841 commit 75bb627

23 files changed

+473
-35
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ node_js:
44
- '5'
55
- stable
66

7+
addons:
8+
firefox: 'latest'
9+
710
before_script:
811
- export DISPLAY=:99.0
912
- sh -e /etc/init.d/xvfb start

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ If you omit the host and port, the api will parse `window.host`, and use this in
4949
var ipfs = window.ipfsAPI()
5050
```
5151

52+
### Using Promises
53+
54+
If you do not pass in a callback all api functions will return a `Promise`, for example
55+
56+
```js
57+
ipfs.id()
58+
.then(function (id) {
59+
console.log('my id is: ', id)
60+
})
61+
```
62+
63+
This relies on a global `Promise` object. If you are in an environemnt where that is not
64+
yet available you need to bring your own polyfill.
65+
5266
#### Gotchas
5367

5468
When using the api from script tag for things that require buffers (`ipfs.add`, for example), you will have to use either the exposed `ipfs.Buffer`, that works just like a node buffer, or use this [browser buffer](https://github.com/feross/buffer).

src/api/dht.js

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,38 @@ module.exports = send => {
1111
opts = null
1212
}
1313

14-
return send('dht/get', key, opts, null, (err, res) => {
15-
if (err) return cb(err)
16-
if (!res) return cb(new Error('empty response'))
17-
if (res.length === 0) return cb(new Error('no value returned for key'))
14+
const handleResult = (done, err, res) => {
15+
if (err) return done(err)
16+
if (!res) return done(new Error('empty response'))
17+
if (res.length === 0) return done(new Error('no value returned for key'))
1818

1919
// Inconsistent return values in the browser vs node
2020
if (Array.isArray(res)) {
2121
res = res[0]
2222
}
2323

2424
if (res.Type === 5) {
25-
cb(null, res.Extra)
25+
done(null, res.Extra)
2626
} else {
2727
let error = new Error('key was not found (type 6)')
28-
cb(error)
28+
done(error)
2929
}
30-
})
30+
}
31+
32+
if (typeof cb !== 'function' && typeof Promise !== 'undefined') {
33+
const done = (err, res) => {
34+
if (err) throw err
35+
return res
36+
}
37+
38+
return send('dht/get', key, opts)
39+
.then(
40+
res => handleResult(done, null, res),
41+
err => handleResult(done, err)
42+
)
43+
}
44+
45+
return send('dht/get', key, opts, null, handleResult.bind(null, cb))
3146
},
3247
put (key, value, opts, cb) {
3348
if (typeof (opts) === 'function' && !cb) {

src/api/log.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ const ndjson = require('ndjson')
55
module.exports = send => {
66
return {
77
tail (cb) {
8+
if (typeof cb !== 'function' && typeof Promise !== 'undefined') {
9+
return send('log/tail', null, {}, null, false)
10+
.then(res => res.pipe(ndjson.parse()))
11+
}
12+
813
return send('log/tail', null, {}, null, false, (err, res) => {
914
if (err) return cb(err)
1015
cb(null, res.pipe(ndjson.parse()))

src/api/ping.js

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

33
module.exports = send => {
44
return function ping (id, cb) {
5+
if (typeof cb !== 'function' && typeof Promise !== 'undefined') {
6+
return send('ping', id, {n: 1}, null)
7+
.then(res => res[1])
8+
}
9+
510
return send('ping', id, { n: 1 }, null, function (err, res) {
611
if (err) return cb(err, null)
712
cb(null, res[1])

src/request-api.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,6 @@ function requestAPI (config, path, args, qs, files, buffer, cb) {
6363
if (args) qs.arg = args
6464
if (files && !Array.isArray(files)) files = [files]
6565

66-
if (typeof buffer === 'function') {
67-
cb = buffer
68-
buffer = false
69-
}
70-
7166
if (qs.r) {
7267
qs.recursive = qs.r
7368
delete qs.r // From IPFS 0.4.0, it throw an error when both r and recursive are passed
@@ -116,5 +111,21 @@ function requestAPI (config, path, args, qs, files, buffer, cb) {
116111
// -- Interface
117112

118113
exports = module.exports = function getRequestAPI (config) {
119-
return requestAPI.bind(null, config)
114+
return function (path, args, qs, files, buffer, cb) {
115+
if (typeof buffer === 'function') {
116+
cb = buffer
117+
buffer = false
118+
}
119+
120+
if (typeof cb !== 'function' && typeof Promise !== 'undefined') {
121+
return new Promise(function (resolve, reject) {
122+
requestAPI(config, path, args, qs, files, buffer, function (err, res) {
123+
if (err) return reject(err)
124+
resolve(res)
125+
})
126+
})
127+
}
128+
129+
return requestAPI(config, path, args, qs, files, buffer, cb)
130+
}
120131
}

test/api/add.spec.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,15 @@ describe('.add', () => {
118118
done()
119119
})
120120
})
121+
122+
describe('promise', () => {
123+
it('add buffer', () => {
124+
let buf = new Buffer(testfile)
125+
return apiClients['a'].add(buf)
126+
.then(res => {
127+
expect(res).to.have.length(1)
128+
expect(res[0]).to.have.property('Hash', 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
129+
})
130+
})
131+
})
121132
})

test/api/block.spec.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,34 @@ describe('.block', () => {
3434
done()
3535
})
3636
})
37+
38+
describe('promise', () => {
39+
it('block.put', () => {
40+
return apiClients['a'].block.put(blorb)
41+
.then(res => {
42+
expect(res).to.have.a.property('Key', 'QmPv52ekjS75L4JmHpXVeuJ5uX2ecSfSZo88NSyxwA3rAQ')
43+
})
44+
})
45+
46+
it('block.get', done => {
47+
return apiClients['a'].block.get(blorbKey)
48+
.then(res => {
49+
let buf = ''
50+
res
51+
.on('data', function (data) { buf += data })
52+
.on('end', function () {
53+
expect(buf).to.be.equal('blorb')
54+
done()
55+
})
56+
})
57+
})
58+
59+
it('block.stat', () => {
60+
return apiClients['a'].block.stat(blorbKey)
61+
.then(res => {
62+
expect(res).to.have.property('Key')
63+
expect(res).to.have.property('Size')
64+
})
65+
})
66+
})
3767
})

test/api/cat.spec.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,20 @@ describe('.cat', () => {
4646
})
4747
})
4848
})
49+
50+
describe('promise', () => {
51+
it('cat', done => {
52+
return apiClients['a'].cat('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
53+
.then(res => {
54+
let buf = ''
55+
res
56+
.on('error', err => { throw err })
57+
.on('data', data => buf += data)
58+
.on('end', () => {
59+
expect(buf).to.be.equal(testfile.toString())
60+
done()
61+
})
62+
})
63+
})
64+
})
4965
})

test/api/commands.spec.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,13 @@ describe('.commands', () => {
88
done()
99
})
1010
})
11+
12+
describe('promise', () => {
13+
it('lists commands', () => {
14+
return apiClients['a'].commands()
15+
.then(res => {
16+
expect(res).to.exist
17+
})
18+
})
19+
})
1120
})

0 commit comments

Comments
 (0)