diff --git a/README.md b/README.md index 03d881e..abe2349 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ - [`node.size`](#nodesize) - [`node.toJSON()`](#nodetojson) - [`node.toString()`](#nodetostring) + - [`node.toDAGLink(options)`](#nodetodaglinkoptions) - [DAGLink functions](#daglink-functions) - [DAGLink constructor](#daglink-constructor) - [DAGLink instance methods and properties](#daglink-instance-methods-and-properties) @@ -93,7 +94,7 @@ const link = { Tsize: 42 } -await DAGNode.addLink(node, link) +DAGNode.addLink(node, link) console.log('with link', node.toJSON()) DAGNode.rmLink(nodeA, 'I am a link') @@ -154,7 +155,7 @@ const link = { Hash: // can be a String CID, CID buffer or CID object } -await DAGNode.addLink(node, link) +DAGNode.addLink(node, link) ``` #### rmLink(node, nameOrCid) @@ -187,6 +188,19 @@ Size of the node, in bytes #### `node.toString()` +#### `node.toDAGLink()` + +- `options` - (optional) type: Object. Currently the only option is `name` to specify a named link. + +Converts a `DAGNode` into a `DAGLink`. + +```JavaScript +const node = new DAGNode('some data') +const link = node.toDAGLink() +// Named link +const link = node.toDAGLink({ name: 'name-of-the-link' }) +``` + ### DAGLink functions diff --git a/src/dag-node/addLink.js b/src/dag-node/addLink.js index a39235a..d44d948 100644 --- a/src/dag-node/addLink.js +++ b/src/dag-node/addLink.js @@ -1,13 +1,10 @@ 'use strict' const sortLinks = require('./sortLinks') -const toDAGLink = require('./toDagLink') const DAGLink = require('../dag-link') const DAGNode = require('./index') -// Intentionally keeping the `async` to signal that it may return a promise -// eslint-disable-next-line require-await -const asDAGLink = async (link) => { +const asDAGLink = (link) => { if (DAGLink.isDAGLink(link)) { // It's a DAGLink instance // no need to do anything @@ -15,17 +12,15 @@ const asDAGLink = async (link) => { } if (DAGNode.isDAGNode(link)) { - // It's a DAGNode instance - // convert to link - return toDAGLink(link, {}) + throw new Error('Link must be a DAGLink or DAGLink-like. Convert the DAGNode into a DAGLink via `node.toDAGLink()`.') } // It's a Object with name, multihash/hash/cid and size return new DAGLink(link.Name || link.name, link.Tsize || link.size, link.Hash || link.multihash || link.hash || link.cid) } -const addLink = async (node, link) => { - const dagLink = await asDAGLink(link) +const addLink = (node, link) => { + const dagLink = asDAGLink(link) node._links.push(dagLink) node._links = sortLinks(node._links) } diff --git a/src/dag-node/dagNode.js b/src/dag-node/dagNode.js index 168e044..e76ed96 100644 --- a/src/dag-node/dagNode.js +++ b/src/dag-node/dagNode.js @@ -5,6 +5,7 @@ const sortLinks = require('./sortLinks') const visibility = require('../visibility') const DAGLink = require('../dag-link/dagLink') const { serializeDAGNode } = require('../serialize.js') +const toDAGLink = require('./toDagLink') class DAGNode { constructor (data, links = [], serializedSize = 0) { @@ -57,6 +58,11 @@ class DAGNode { return `DAGNode ` } + // @returns {Promise.} + toDAGLink (options) { + return toDAGLink(this, options) + } + get size () { if (this._size === undefined) { this._size = this._links.reduce((sum, l) => sum + l.Tsize, this._serializedSize) diff --git a/src/dag-node/toDagLink.js b/src/dag-node/toDagLink.js index a9ef33d..cc8f781 100644 --- a/src/dag-node/toDagLink.js +++ b/src/dag-node/toDagLink.js @@ -1,14 +1,15 @@ 'use strict' -const DAGLink = require('./../dag-link/dagLink') -const { cid, serialize } = require('../util') +const DAGLink = require('../dag-link/dagLink') +const { serializeDAGNode } = require('../serialize') +const genCid = require('../genCid') /* * toDAGLink converts a DAGNode to a DAGLink */ const toDAGLink = async (node, options = {}) => { - const serialized = serialize(node) - const nodeCid = await cid(serialized) + const serialized = serializeDAGNode(node) + const nodeCid = await genCid.cid(serialized) return new DAGLink(options.name || '', serialized.length, nodeCid) } diff --git a/src/genCid.js b/src/genCid.js new file mode 100644 index 0000000..0180e69 --- /dev/null +++ b/src/genCid.js @@ -0,0 +1,32 @@ +'use strict' + +const CID = require('cids') +const multicodec = require('multicodec') +const multihashing = require('multihashing-async') + +exports = module.exports + +exports.codec = multicodec.DAG_PB +exports.defaultHashAlg = multicodec.SHA2_256 + +/** + * Calculate the CID of the binary blob. + * + * @param {Object} binaryBlob - Encoded IPLD Node + * @param {Object} [userOptions] - Options to create the CID + * @param {number} [userOptions.cidVersion=1] - CID version number + * @param {string} [UserOptions.hashAlg] - Defaults to the defaultHashAlg of the format + * @returns {Promise.} + */ +const cid = async (binaryBlob, userOptions) => { + const defaultOptions = { cidVersion: 1, hashAlg: exports.defaultHashAlg } + const options = Object.assign(defaultOptions, userOptions) + + const multihash = await multihashing(binaryBlob, options.hashAlg) + const codecName = multicodec.print[exports.codec] + const cid = new CID(options.cidVersion, codecName, multihash) + + return cid +} + +exports.cid = cid diff --git a/src/util.js b/src/util.js index 9dfeec5..015f291 100644 --- a/src/util.js +++ b/src/util.js @@ -1,18 +1,16 @@ 'use strict' -const CID = require('cids') const protons = require('protons') const proto = protons(require('./dag.proto')) const DAGLink = require('./dag-link/dagLink') const DAGNode = require('./dag-node/dagNode') -const multicodec = require('multicodec') -const multihashing = require('multihashing-async') const { serializeDAGNode, serializeDAGNodeLike } = require('./serialize') +const genCid = require('./genCid') exports = module.exports -exports.codec = multicodec.DAG_PB -exports.defaultHashAlg = multicodec.SHA2_256 +exports.codec = genCid.codec +exports.defaultHashAlg = genCid.defaultHashAlg /** * Calculate the CID of the binary blob. @@ -23,15 +21,8 @@ exports.defaultHashAlg = multicodec.SHA2_256 * @param {string} [UserOptions.hashAlg] - Defaults to the defaultHashAlg of the format * @returns {Promise.} */ -const cid = async (binaryBlob, userOptions) => { - const defaultOptions = { cidVersion: 1, hashAlg: exports.defaultHashAlg } - const options = Object.assign(defaultOptions, userOptions) - - const multihash = await multihashing(binaryBlob, options.hashAlg) - const codecName = multicodec.print[exports.codec] - const cid = new CID(options.cidVersion, codecName, multihash) - - return cid +const cid = (binaryBlob, userOptions) => { + return genCid.cid(binaryBlob, userOptions) } /** diff --git a/test/dag-node-test.js b/test/dag-node-test.js index 5d4548a..02c1f34 100644 --- a/test/dag-node-test.js +++ b/test/dag-node-test.js @@ -9,7 +9,6 @@ chai.use(dirtyChai) const dagPB = require('../src') const DAGLink = dagPB.DAGLink const DAGNode = dagPB.DAGNode -const toDAGLink = require('../src/dag-node/toDagLink') const isNode = require('detect-node') const multihash = require('multihashes') const multicodec = require('multicodec') @@ -126,7 +125,7 @@ module.exports = (repo) => { it('addLink by DAGNode', async () => { const node1 = new DAGNode(Buffer.from('1')) const node2 = new DAGNode(Buffer.from('2')) - await DAGNode.addLink(node1, node2) + DAGNode.addLink(node1, await node2.toDAGLink()) expect(node1.Links.length).to.equal(1) expect(node1.Links[0].Tsize).to.eql(node2.size) expect(node1.Links[0].Name).to.be.eql('') @@ -135,8 +134,8 @@ module.exports = (repo) => { it('addLink by DAGLink', async () => { const node1 = new DAGNode(Buffer.from('1')) const node2 = new DAGNode(Buffer.from('2')) - const link = await toDAGLink(node2) - await DAGNode.addLink(node1, link) + const link = await node2.toDAGLink() + DAGNode.addLink(node1, link) expect(node1.Links.length).to.equal(1) expect(node1.Links[0].Tsize).to.eql(node2.size) expect(node1.Links[0].Name).to.be.eql('') @@ -145,9 +144,9 @@ module.exports = (repo) => { it('addLink by object', async () => { const node1 = new DAGNode(Buffer.from('1')) const node2 = new DAGNode(Buffer.from('2')) - const link = await toDAGLink(node2) + const link = await node2.toDAGLink() const linkObject = link.toJSON() - await DAGNode.addLink(node1, linkObject) + DAGNode.addLink(node1, linkObject) expect(node1.Links.length).to.equal(1) expect(node1.Links[0].Tsize).to.eql(node2.size) expect(node1.Links[0].Name).to.be.eql('') @@ -156,9 +155,9 @@ module.exports = (repo) => { it('addLink by name', async () => { const node1 = new DAGNode(Buffer.from('1')) const node2 = new DAGNode(Buffer.from('2')) - const link = await toDAGLink(node2, { name: 'banana' }) + const link = await node2.toDAGLink({ name: 'banana' }) expect(node1.Links.length).to.equal(0) - await DAGNode.addLink(node1, link) + DAGNode.addLink(node1, link) expect(node1.Links.length).to.equal(1) expect(node1.Links[0].Tsize).to.eql(node2.size) expect(node1.Links[0].Name).to.eql('banana') @@ -169,11 +168,11 @@ module.exports = (repo) => { expect(node1.Links.length).to.equal(0) const node2 = new DAGNode(Buffer.from('2')) - await DAGNode.addLink(node1, node2) + DAGNode.addLink(node1, await node2.toDAGLink()) expect(node1.Links.length).to.equal(1) const node3 = new DAGNode(Buffer.from('3')) - await DAGNode.addLink(node1, node3) + DAGNode.addLink(node1, await node3.toDAGLink()) expect(node1.Links.length).to.equal(2) }) @@ -181,17 +180,15 @@ module.exports = (repo) => { const linkName = 'link-name' const remote = new DAGNode(Buffer.from('2')) const source = new DAGNode(Buffer.from('1')) - await DAGNode.addLink( + DAGNode.addLink( source, - await toDAGLink(remote, { - name: linkName - }) + await remote.toDAGLink({ name: linkName }) ) expect(source.Links.length).to.equal(1) const target = new DAGNode(null, [], 0) - await DAGNode.addLink(target, source.Links[0]) + DAGNode.addLink(target, source.Links[0]) expect(target.Links.length).to.equal(1) expect(target.Links[0].Tsize).to.eql(remote.size) @@ -204,9 +201,9 @@ module.exports = (repo) => { const withoutLink = node1.toJSON() const node2 = new DAGNode(Buffer.from('2')) - const link = await toDAGLink(node2, { name: 'banana' }) + const link = await node2.toDAGLink({ name: 'banana' }) - await DAGNode.addLink(node1, link) + DAGNode.addLink(node1, link) expect(node1.Links.length).to.eql(1) DAGNode.rmLink(node1, 'banana') expect(node1.Links.length).to.eql(0) @@ -219,9 +216,9 @@ module.exports = (repo) => { const withoutLink = node1.toJSON() const node2 = new DAGNode(Buffer.from('2')) - const link = await toDAGLink(node2, { name: 'banana' }) + const link = await node2.toDAGLink({ name: 'banana' }) - await DAGNode.addLink(node1, link) + DAGNode.addLink(node1, link) expect(node1.Links.length).to.eql(1) DAGNode.rmLink(node1, node1.Links[0].Hash) expect(node1.Links.length).to.eql(0)