diff --git a/.gitignore b/.gitignore index 88b65f8..b2dc31c 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ node_modules .node_repl_history dist +docs \ No newline at end of file diff --git a/package.json b/package.json index d4f423a..212eea9 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,12 @@ "test": "aegir-test", "test:node": "aegir-test node", "test:browser": "aegir-test browser", - "release": "aegir-release", - "release-minor": "aegir-release --type minor", - "release-major": "aegir-release --type major", + "release": "aegir-release --docs", + "release-minor": "aegir-release --type minor --docs", + "release-major": "aegir-release --type major --docs", "coverage": "aegir-coverage", - "coverage-publish": "aegir-coverage publish" + "coverage-publish": "aegir-coverage publish", + "docs": "aegir-docs" }, "pre-commit": [ "lint", @@ -36,13 +37,11 @@ }, "homepage": "https://github.com/ipfs/js-ipfs-block#readme", "devDependencies": { - "aegir": "^10.0.0", - "chai": "^3.5.0", - "multihashes": "~0.4.0" + "aegir": "^11.0.0", + "chai": "^3.5.0" }, "dependencies": { - "async": "^2.1.4", - "multihashing-async": "~0.4.2" + "cids": "^0.4.2" }, "engines": { "node": ">=4.0.0", @@ -58,4 +57,4 @@ "npmcdn-to-unpkg-bot ", "ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ " ] -} \ No newline at end of file +} diff --git a/src/index.js b/src/index.js index 3d987cf..c05d308 100644 --- a/src/index.js +++ b/src/index.js @@ -1,90 +1,66 @@ 'use strict' -const multihashing = require('multihashing-async') -const setImmediate = require('async/setImmediate') - -module.exports = Block +const CID = require('cids') /** - * Represents an immutable block of data that is uniquely referenced with a multihash key. + * Represents an immutable block of data that is uniquely referenced with a cid. * * @constructor - * @param {Buffer | string} data - The data to be stored in the block as a buffer or a UTF8 string. + * @param {Buffer} data - The data to be stored in the block as a buffer. + * @param {CID} cid - The cid of the data + * * @example - * const block = new Block('a012d83b20f9371...') + * const block = new Block(new Buffer('a012d83b20f9371...')) */ -function Block (data) { - if (!(this instanceof Block)) { - return new Block(data) - } +class Block { + constructor (data, cid) { + if (!data || !Buffer.isBuffer(data)) { + throw new Error('first argument must be a buffer') + } - if (!data) { - throw new Error('Block must be constructed with data') - } + if (!cid || !CID.isCID(cid)) { + throw new Error('second argument must be a CID') + } - if (!(typeof data === 'string' || Buffer.isBuffer(data))) { - throw new Error('data should be Buffer') + this._data = data + this._cid = cid } - if (!Buffer.isBuffer(data)) { - data = new Buffer(data) + /** + * The data of this block. + * + * @type {Buffer} + */ + get data () { + return this._data } - this._cache = {} - - data = ensureBuffer(data) - - Object.defineProperty(this, 'data', { - get () { - return data - }, - set () { - throw new Error('Tried to change an immutable block') - } - }) + set data (val) { + throw new Error('Tried to change an immutable block') + } /** - * Creates a unique multihash key of this block. - * - * @param {string} [hashFunc='sha2-256'] - The hash function to use. - * @param {function(Error, Multihash)} callback - The callback to execute on completion. - * @returns {void} - * @example - * block.key((multihash) => { - * console.log(multihash) - * }) - * // 'QmeoBGh5g5kHgK3xppJ1...' - **/ - this.key = (hashFunc, callback) => { - if (typeof hashFunc === 'function') { - callback = hashFunc - hashFunc = null - } - - if (!hashFunc) { - hashFunc = 'sha2-256' - } - - if (this._cache[hashFunc]) { - return setImmediate(() => { - callback(null, this._cache[hashFunc]) - }) - } - - multihashing(this.data, hashFunc, (err, multihash) => { - if (err) { - return callback(err) - } - this._cache[hashFunc] = multihash - callback(null, multihash) - }) + * The cid of the data this block represents. + * + * @type {CID} + */ + get cid () { + return this._cid } -} -function ensureBuffer (data) { - if (Buffer.isBuffer(data)) { - return data + set cid (val) { + throw new Error('Tried to change an immutable block') } - return new Buffer(data) + /** + * Check if the given value is a Block. + * + * @param {any} other + * @returns {bool} + */ + static isBlock (other) { + return other && other.constructor.name === 'Block' + } } + +module.exports = Block diff --git a/test/block.spec.js b/test/block.spec.js deleted file mode 100644 index 81cb700..0000000 --- a/test/block.spec.js +++ /dev/null @@ -1,88 +0,0 @@ -/* eslint-env mocha */ -'use strict' - -const expect = require('chai').expect -const parallel = require('async/parallel') -const series = require('async/series') -const mh = require('multihashes') - -const Block = require('../src') - -function expectKey (block, hashFn, expectedKey, callback) { - const cb = (err, key) => { - if (err) { - return callback(err) - } - expect(mh.toB58String(key)).to.be.eql(expectedKey) - callback() - } - - if (typeof expectedKey === 'function') { - callback = expectedKey - expectedKey = hashFn - block.key(cb) - } else { - block.key(hashFn, cb) - } -} - -describe('block', () => { - it('create', (done) => { - const b = new Block('random-data') - expect(b.data).to.exist - parallel([ - (cb) => expectKey(b, 'QmeoBGh5g5kHgK3xppJ1YPwB9xgH2GoqhMSuQVpzDdvtJG', cb), - (cb) => expectKey(b, 'sha1', '5dsvLgRV9RVj9eSgtxMrXQjbpfFeHY', cb) - ], done) - }) - - it('create /wo new', (done) => { - const b = Block('random-data') - expect(b.data).to.exist - parallel([ - (cb) => expectKey(b, 'QmeoBGh5g5kHgK3xppJ1YPwB9xgH2GoqhMSuQVpzDdvtJG', cb), - (cb) => expectKey(b, 'sha1', '5dsvLgRV9RVj9eSgtxMrXQjbpfFeHY', cb) - ], done) - }) - - it('fail to create an empty block', () => { - expect(() => new Block()).to.throw() - }) - - it('2 different blocks have different hashes', (done) => { - const b1 = new Block('random-data') - const b2 = new Block('more-random-data') - - parallel([ - (cb) => b1.key(cb), - (cb) => b2.key(cb) - ], (err, keys) => { - expect(err).to.not.exist - expect(keys[0]).to.not.deep.equal(keys[1]) - done() - }) - }) - - it('caches key calls', (done) => { - const b = new Block('random') - series([ - (cb) => b.key(cb), - (cb) => b.key(cb) - ], (err, res) => { - expect(err).to.not.exist - expect(b._cache['sha2-256']).to.be.eql(res[0]) - expect(res[0]).to.be.eql(res[1]) - done() - }) - }) - - it('block stays immutable', () => { - const block = new Block("Can't change this!") - - expect( - () => { block.data = 'fail' } - ).to.throw( - /immutable/ - ) - }) -}) diff --git a/test/index.spec.js b/test/index.spec.js new file mode 100644 index 0000000..7caf00a --- /dev/null +++ b/test/index.spec.js @@ -0,0 +1,45 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect +const CID = require('cids') + +const Block = require('../src') + +describe('block', () => { + it('create throws', () => { + expect( + () => new Block('string') + ).to.throw() + + expect( + () => new Block(new Buffer('hello'), 'cid') + ).to.throw() + + expect( + () => new Block('hello', new CID('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')) + ).to.throw() + }) + + it('create', () => { + const b = new Block(new Buffer('hello'), new CID('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')) + + expect(Block.isBlock(b)).to.eql(true) + }) + + it('block stays immutable', () => { + const b = new Block(new Buffer('hello'), new CID('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')) + + expect( + () => { b.data = 'fail' } + ).to.throw( + /immutable/ + ) + + expect( + () => { b.cid = 'fail' } + ).to.throw( + /immutable/ + ) + }) +})