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

Commit 72fdc8c

Browse files
author
Alan Shaw
authored
refactor: convert block API to async await (#1153)
* refactor: convert block API to async/await depends on: * [ ] #1150 License: MIT Signed-off-by: Alan Shaw <alan.shaw@protocol.ai> * feat: support the version param License: MIT Signed-off-by: Alan Shaw <alan.shaw@protocol.ai> * refactor: convert DAG API to async/await License: MIT Signed-off-by: Alan Shaw <alan.shaw@protocol.ai> * fix: add util to convert a single buffer to a form data object License: MIT Signed-off-by: Alan Shaw <alan.shaw@protocol.ai> * fix: exported function
1 parent 559a97d commit 72fdc8c

12 files changed

+220
-265
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"stream": "readable-stream",
2121
"ky-universal": "ky/umd",
2222
"./src/add/form-data.js": "./src/add/form-data.browser.js",
23-
"./src/add-from-fs/index.js": "./src/add-from-fs/index.browser.js"
23+
"./src/add-from-fs/index.js": "./src/add-from-fs/index.browser.js",
24+
"./src/lib/buffer-to-form-data.js": "./src/lib/buffer-to-form-data.browser.js"
2425
},
2526
"repository": "github:ipfs/js-ipfs-http-client",
2627
"scripts": {

src/block/get.js

+17-54
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,25 @@
11
'use strict'
22

3-
const promisify = require('promisify-es6')
43
const Block = require('ipfs-block')
54
const CID = require('cids')
6-
const streamToValue = require('../utils/stream-to-value')
5+
const { Buffer } = require('buffer')
6+
const configure = require('../lib/configure')
77

8-
module.exports = (send) => {
9-
return promisify((args, opts, callback) => {
10-
if (typeof opts === 'function') {
11-
callback = opts
12-
opts = {}
13-
}
8+
module.exports = configure(({ ky }) => {
9+
return async (cid, options) => {
10+
cid = new CID(cid)
11+
options = options || {}
1412

15-
// TODO this needs to be adjusted with the new go-ipfs http-api
16-
let cid
17-
try {
18-
if (CID.isCID(args)) {
19-
cid = args
20-
args = cid.toBaseEncodedString()
21-
} else if (Buffer.isBuffer(args)) {
22-
cid = new CID(args)
23-
args = cid.toBaseEncodedString()
24-
} else if (typeof args === 'string') {
25-
cid = new CID(args)
26-
} else {
27-
return callback(new Error('invalid argument'))
28-
}
29-
} catch (err) {
30-
return callback(err)
31-
}
13+
const searchParams = new URLSearchParams(options.searchParams)
14+
searchParams.set('arg', `${cid}`)
3215

33-
// Transform the response from Buffer or a Stream to a Block
34-
const transform = (res, callback) => {
35-
if (Buffer.isBuffer(res)) {
36-
callback(null, new Block(res, cid))
37-
// For empty blocks, concat-stream can't infer the encoding so we are
38-
// passed back an empty array
39-
} else if (Array.isArray(res) && res.length === 0) {
40-
callback(null, new Block(Buffer.alloc(0), cid))
41-
} else {
42-
streamToValue(res, (err, data) => {
43-
if (err) {
44-
return callback(err)
45-
}
46-
// For empty blocks, concat-stream can't infer the encoding so we are
47-
// passed back an empty array
48-
if (!data.length) data = Buffer.alloc(0)
49-
callback(null, new Block(data, cid))
50-
})
51-
}
52-
}
16+
const data = await ky.get('block/get', {
17+
timeout: options.timeout,
18+
signal: options.signal,
19+
headers: options.headers,
20+
searchParams
21+
}).arrayBuffer()
5322

54-
const request = {
55-
path: 'block/get',
56-
args: args,
57-
qs: opts
58-
}
59-
60-
send.andTransform(request, transform, callback)
61-
})
62-
}
23+
return new Block(Buffer.from(data), cid)
24+
}
25+
})

src/block/index.js

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

33
const nodeify = require('promise-nodeify')
4-
const moduleConfig = require('../utils/module-config')
4+
const callbackify = require('callbackify')
55
const { collectify } = require('../lib/converters')
66

7-
module.exports = (arg, config) => {
8-
const send = moduleConfig(arg)
7+
module.exports = config => {
98
const rm = require('./rm-async-iterator')(config)
109

1110
return {
12-
get: require('./get')(send),
13-
stat: require('./stat')(send),
14-
put: require('./put')(send),
11+
get: callbackify.variadic(require('./get')(config)),
12+
stat: callbackify.variadic(require('./stat')(config)),
13+
put: callbackify.variadic(require('./put')(config)),
1514
rm: (input, options, callback) => {
1615
if (typeof options === 'function') {
1716
callback = options

src/block/put.js

+52-58
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,68 @@
11
'use strict'
22

3-
const promisify = require('promisify-es6')
43
const Block = require('ipfs-block')
54
const CID = require('cids')
65
const multihash = require('multihashes')
7-
const SendOneFile = require('../utils/send-one-file')
8-
9-
module.exports = (send) => {
10-
const sendOneFile = SendOneFile(send, 'block/put')
11-
12-
return promisify((block, options, callback) => {
13-
if (typeof options === 'function') {
14-
callback = options
15-
options = {}
16-
}
6+
const configure = require('../lib/configure')
7+
const toFormData = require('../lib/buffer-to-form-data')
178

9+
module.exports = configure(({ ky }) => {
10+
async function put (data, options) {
1811
options = options || {}
1912

20-
if (Array.isArray(block)) {
21-
return callback(new Error('block.put accepts only one block'))
22-
}
23-
24-
if (Buffer.isBuffer(block)) {
25-
block = { data: block }
26-
}
27-
28-
if (!block || !block.data) {
29-
return callback(new Error('invalid block arg'))
13+
if (Block.isBlock(data)) {
14+
const { name, length } = multihash.decode(data.cid.multihash)
15+
options = {
16+
...options,
17+
format: data.cid.codec,
18+
mhtype: name,
19+
mhlen: length,
20+
version: data.cid.version
21+
}
22+
data = data.data
23+
} else if (options.cid) {
24+
const cid = new CID(options.cid)
25+
const { name, length } = multihash.decode(cid.multihash)
26+
options = {
27+
...options,
28+
format: cid.codec,
29+
mhtype: name,
30+
mhlen: length,
31+
version: cid.version
32+
}
33+
delete options.cid
3034
}
3135

32-
const qs = {}
36+
const searchParams = new URLSearchParams(options.searchParams)
37+
if (options.format) searchParams.set('format', options.format)
38+
if (options.mhtype) searchParams.set('mhtype', options.mhtype)
39+
if (options.mhlen) searchParams.set('mhlen', options.mhlen)
40+
if (options.pin != null) searchParams.set('pin', options.pin)
41+
if (options.version != null) searchParams.set('version', options.version)
3342

34-
if (block.cid || options.cid) {
35-
let cid
36-
37-
try {
38-
cid = new CID(block.cid || options.cid)
39-
} catch (err) {
40-
return callback(err)
43+
let res
44+
try {
45+
res = await ky.post('block/put', {
46+
timeout: options.timeout,
47+
signal: options.signal,
48+
headers: options.headers,
49+
searchParams,
50+
body: toFormData(data)
51+
}).json()
52+
} catch (err) {
53+
// Retry with "protobuf"/"cbor" format for go-ipfs
54+
// TODO: remove when https://github.com/ipfs/go-cid/issues/75 resolved
55+
if (options.format === 'dag-pb') {
56+
return put(data, { ...options, format: 'protobuf' })
57+
} else if (options.format === 'dag-cbor') {
58+
return put(data, { ...options, format: 'cbor' })
4159
}
4260

43-
const { name, length } = multihash.decode(cid.multihash)
44-
45-
qs.format = cid.codec
46-
qs.mhtype = name
47-
qs.mhlen = length
48-
qs.version = cid.version
49-
} else {
50-
if (options.format) qs.format = options.format
51-
if (options.mhtype) qs.mhtype = options.mhtype
52-
if (options.mhlen) qs.mhlen = options.mhlen
53-
if (options.version != null) qs.version = options.version
61+
throw err
5462
}
5563

56-
sendOneFile(block.data, { qs }, (err, result) => {
57-
if (err) {
58-
// Retry with "protobuf"/"cbor" format for go-ipfs
59-
// TODO: remove when https://github.com/ipfs/go-cid/issues/75 resolved
60-
if (qs.format === 'dag-pb' || qs.format === 'dag-cbor') {
61-
qs.format = qs.format === 'dag-pb' ? 'protobuf' : 'cbor'
62-
return sendOneFile(block.data, { qs }, (err, result) => {
63-
if (err) return callback(err)
64-
callback(null, new Block(block.data, new CID(result.Key)))
65-
})
66-
}
67-
68-
return callback(err)
69-
}
64+
return new Block(data, new CID(res.Key))
65+
}
7066

71-
callback(null, new Block(block.data, new CID(result.Key)))
72-
})
73-
})
74-
}
67+
return put
68+
})

src/block/stat.js

+19-26
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,28 @@
11
'use strict'
22

3-
const promisify = require('promisify-es6')
43
const CID = require('cids')
5-
const multihash = require('multihashes')
4+
const { Buffer } = require('buffer')
5+
const configure = require('../lib/configure')
6+
const toCamel = require('../lib/object-to-camel')
67

7-
module.exports = (send) => {
8-
return promisify((args, opts, callback) => {
9-
// TODO this needs to be adjusted with the new go-ipfs http-api
10-
if (args && CID.isCID(args)) {
11-
args = multihash.toB58String(args.multihash)
12-
}
8+
module.exports = configure(({ ky }) => {
9+
return async (cid, options) => {
10+
options = options || {}
1311

14-
if (typeof (opts) === 'function') {
15-
callback = opts
16-
opts = {}
12+
if (Buffer.isBuffer(cid)) {
13+
cid = new CID(cid)
1714
}
1815

19-
const request = {
20-
path: 'block/stat',
21-
args: args,
22-
qs: opts
23-
}
16+
const searchParams = new URLSearchParams(options.searchParams)
17+
searchParams.set('arg', `${cid}`)
2418

25-
// Transform the response from { Key, Size } objects to { key, size } objects
26-
const transform = (stats, callback) => {
27-
callback(null, {
28-
key: stats.Key,
29-
size: stats.Size
30-
})
31-
}
19+
const res = await ky.get('block/stat', {
20+
timeout: options.timeout,
21+
signal: options.signal,
22+
headers: options.headers,
23+
searchParams
24+
}).json()
3225

33-
send.andTransform(request, transform, callback)
34-
})
35-
}
26+
return toCamel(res)
27+
}
28+
})

src/dag/get.js

+23-51
Original file line numberDiff line numberDiff line change
@@ -3,67 +3,39 @@
33
const dagPB = require('ipld-dag-pb')
44
const dagCBOR = require('ipld-dag-cbor')
55
const raw = require('ipld-raw')
6-
const promisify = require('promisify-es6')
7-
const CID = require('cids')
8-
const waterfall = require('async/waterfall')
9-
const block = require('../block')
6+
const configure = require('../lib/configure')
107

118
const resolvers = {
129
'dag-cbor': dagCBOR.resolver,
1310
'dag-pb': dagPB.resolver,
1411
raw: raw.resolver
1512
}
1613

17-
module.exports = (send) => {
18-
return promisify((cid, path, options, callback) => {
19-
if (typeof path === 'function') {
20-
callback = path
21-
path = undefined
22-
}
23-
24-
if (typeof options === 'function') {
25-
callback = options
26-
options = {}
27-
}
14+
module.exports = config => {
15+
const getBlock = require('../block/get')(config)
16+
const dagResolve = require('./resolve')(config)
2817

29-
options = options || {}
30-
path = path || ''
31-
32-
if (CID.isCID(cid)) {
33-
cid = cid.toBaseEncodedString()
34-
}
35-
36-
waterfall([
37-
cb => {
38-
send({
39-
path: 'dag/resolve',
40-
args: cid + '/' + path,
41-
qs: options
42-
}, cb)
43-
},
44-
(resolved, cb) => {
45-
block(send).get(new CID(resolved.Cid['/']), (err, ipfsBlock) => {
46-
cb(err, ipfsBlock, resolved.RemPath)
47-
})
48-
},
49-
(ipfsBlock, path, cb) => {
50-
const dagResolver = resolvers[ipfsBlock.cid.codec]
18+
return configure(({ ky }) => {
19+
return async (cid, path, options) => {
20+
if (typeof path === 'object') {
21+
options = path
22+
path = null
23+
}
5124

52-
if (!dagResolver) {
53-
const error = new Error(`Missing IPLD format "${ipfsBlock.cid.codec}"`)
54-
error.missingMulticodec = ipfsBlock.cid.codec
55-
return cb(error)
56-
}
25+
options = options || {}
5726

58-
let res
59-
try {
60-
res = dagResolver.resolve(ipfsBlock.data, path)
61-
} catch (err) {
62-
return cb(err)
63-
}
27+
const resolved = await dagResolve(cid, path, options)
28+
const block = await getBlock(resolved.cid, options)
29+
const dagResolver = resolvers[block.cid.codec]
6430

65-
cb(null, res)
31+
if (!dagResolver) {
32+
throw Object.assign(
33+
new Error(`Missing IPLD format "${block.cid.codec}"`),
34+
{ missingMulticodec: cid.codec }
35+
)
6636
}
67-
], callback)
68-
})
37+
38+
return dagResolver.resolve(block.data, resolved.remPath)
39+
}
40+
})(config)
6941
}

0 commit comments

Comments
 (0)