diff --git a/CHANGELOG.md b/CHANGELOG.md
index 671f9572..2639184f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,23 @@
+
+# [0.68.0](https://github.com/ipfs/interface-ipfs-core/compare/v0.67.0...v0.68.0) (2018-06-18)
+
+
+### Bug Fixes
+
+* improve bitswap wantlist and unwant docs ([7737546](https://github.com/ipfs/interface-ipfs-core/commit/7737546))
+* linting errors ([fcc834c](https://github.com/ipfs/interface-ipfs-core/commit/fcc834c))
+* removes duplicated TOC for pubsub ([a358cf7](https://github.com/ipfs/interface-ipfs-core/commit/a358cf7))
+
+
+### Features
+
+* add bitswap.unwant javascript spec ([df4e677](https://github.com/ipfs/interface-ipfs-core/commit/df4e677))
+* add bitswap.unwant javascript spec ([d75a361](https://github.com/ipfs/interface-ipfs-core/commit/d75a361))
+* add bitswap.unwant javascript spec ([c291ca9](https://github.com/ipfs/interface-ipfs-core/commit/c291ca9))
+* add peerId param to bitswap.wantlist ([9f81bcb](https://github.com/ipfs/interface-ipfs-core/commit/9f81bcb))
+
+
+
# [0.67.0](https://github.com/ipfs/interface-ipfs-core/compare/v0.66.4...v0.67.0) (2018-06-04)
diff --git a/SPEC/BITSWAP.md b/SPEC/BITSWAP.md
index 00bc5fc1..28949c00 100644
--- a/SPEC/BITSWAP.md
+++ b/SPEC/BITSWAP.md
@@ -4,13 +4,58 @@
* [bitswap.unwant](#bitswapunwant)
* [bitswap.stat](#bitswapstat)
-#### `bitswap.wantlist`
+#### `bitswap.unwant`
-(not spec'ed yet)
+> Removes a given block from your wantlist
-#### `bitswap.unwant`
+##### `Go` **WIP**
+
+##### `JavaScript` - ipfs.bitswap.unwant(cid, [callback])
+
+`cid` is a [cid][cid] which can be passed as:
+
+- CID, a CID instance
+- String, the base58 encoded version of the multihash
+
+`callback` must follow `function (err) {}` signature, where `err` is an error if the operation was not successful.
+
+ **Example:**
+
+ ```JavaScript
+ ipfs.bitswap.unwant('QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu', (err) => {
+ if (err) throw err
+ console.log('Done')
+ })
+ ```
+
+##### `Go` **WIP**
+
+### `bitswap.wantlist`
+
+> Returns the wantlist, optionally filtered by peer ID
-(not spec'ed yet)
+#### `Go` **WIP**
+
+#### `JavaScript` - ipfs.bitswap.wantlist([peerId], [callback])
+
+`callback` must follow `function (err, list) {}` signature, where `err` is an error if the operation was not successful. `list` is an Object containing the following keys:
+
+- `Keys` An array of objects containing the following keys:
+ - `/` A string multihash
+
+If no `callback` is passed, a promise is returned.
+
+**Example:**
+
+```JavaScript
+ipfs.bitswap.wantlist((err, list) => console.log(list))
+
+// { Keys: [{ '/': 'QmHash' }] }
+
+ipfs.bitswap.wantlist(peerId, (err, list) => console.log(list))
+
+// { Keys: [{ '/': 'QmHash' }] }
+```
#### `bitswap.stat`
diff --git a/SPEC/FILES.md b/SPEC/FILES.md
index c1308df2..7427701d 100644
--- a/SPEC/FILES.md
+++ b/SPEC/FILES.md
@@ -56,6 +56,7 @@ If no `content` is passed, then the path is treated as an empty directory
- hashAlg || hash (string): multihash hashing algorithm to use.
- wrapWithDirectory (boolean): adds a wrapping node around the content.
- onlyHash (boolean): doesn't actually add the file to IPFS, but rather calculates its hash.
+- pin (boolean, default true): pin this object when adding.
`callback` must follow `function (err, res) {}` signature, where `err` is an error if the operation was not successful. `res` will be an array of:
@@ -109,6 +110,7 @@ Returns a Readable Stream of class Duplex, where objects can be written of the f
- progress (function): a function that will be called with the byte length of chunks as a file is added to ipfs.
- hashAlg || hash (string): multihash hashing algorithm to use
- wrapWithDirectory (boolean): adds a wrapping node around the content
+- pin (boolean, default true): pin this object when adding.
**Example:**
@@ -158,6 +160,7 @@ Returns a Pull Stream, where objects can be written of the forms
- progress (function): a function that will be called with the byte length of chunks as a file is added to ipfs.
- hashAlg || hash (string): multihash hashing algorithm to use
- wrapWithDirectory (boolean): adds a wrapping node around the content
+- pin (boolean, default true): pin this object when adding.
**Example:**
@@ -590,28 +593,56 @@ A great source of [examples][] can be found in the tests for this API.
The Mutable File System (MFS) is a virtual file system on top of IPFS that exposes a Unix like API over a virtual directory. It enables users to write and read from paths without having to worry about updating the graph. It enables things like [ipfs-blob-store](https://github.com/ipfs/ipfs-blob-store) to exist.
-
#### `files.cp`
> Copy files.
##### `Go` **WIP**
-##### `JavaScript` - ipfs.files.cp([from, to], [callback])
+##### `JavaScript` - ipfs.files.cp(...from, to, [options], [callback])
Where:
-- `from` is the path of the source file to copy.
-- `to` is the path of the destination file to copy to.
+- `from` is the path(s) of the source to copy. It might be:
+ - An existing MFS path to a file or a directory (e.g. `/my-dir/my-file.txt`)
+ - An IPFS path (e.g. `/ipfs/QmWGeRAEgtsHW3ec7U4qW2CyVy7eA2mFRVbk1nb24jFyks`)
+- `to` is the path of the destination to copy to
+- `options` is an optional Object that might contain the following keys:
+ - `parents` is a Boolean value to decide whether or not to make the parent directories if they don't exist (default: false)
+ - `format` is what type of nodes to write any newly created directories as (default: `dag-pb`)
+ - `hashAlg` is which algorithm to use when creating CIDs for newly created directories (default: `sha2-256`)
+ - `flush` is a Boolean value to decide whether or not to immediately flush MFS changes to disk (default: true)
+- `callback` is an optional function with the signature `function (error) {}`, where `error` may be an Error that occured if the operation was not successful
+
+If `from` has multiple values then `to` must be a directory.
-`callback` must follow the `function (err) {}` signature, where `err` is an Error if the operation was not successful.
+If `from` has a single value and `to` exists and is a directory, `from` will be copied into `to`.
+
+If `from` has a single value and `to` exists and is a file, `from` must be a file and the contents of `to` will be replaced with the contents of `from` otherwise an error will be returned.
+
+If `from` is an IPFS path, and an MFS path exists with the same name, the IPFS path will be chosen.
If no `callback` is passed, a promise is returned.
**Example:**
```JavaScript
-ipfs.files.cp(['/src-file', '/dst-file'], (err) => {
+// To copy a file
+ipfs.files.cp('/src-file', '/dst-file', (err) => {
+ if (err) {
+ console.error(err)
+ }
+})
+
+// To copy a directory
+ipfs.files.cp('/src-dir', '/dst-dir', (err) => {
+ if (err) {
+ console.error(err)
+ }
+})
+
+// To copy multiple files to a directory
+ipfs.files.cp('/src-file1', '/src-file2', '/dst-dir', (err) => {
if (err) {
console.error(err)
}
@@ -624,15 +655,17 @@ ipfs.files.cp(['/src-file', '/dst-file'], (err) => {
##### `Go` **WIP**
-##### `JavaScript` - ipfs.files.mkdir(path, [options, callback])
+##### `JavaScript` - ipfs.files.mkdir(path, [options], [callback])
Where:
-- `path` is the path to the directory to make.
+- `path` is the path to the directory to make
- `options` is an optional Object that might contain the following keys:
- - `parents` is a Boolean value to decide whether or not to make the parent directories if they don't exist.
-
-`callback` must follow the `function (err) {}` signature, where `err` is an Error if the operation was not successful.
+ - `parents` is a Boolean value to decide whether or not to make the parent directories if they don't exist (default: false)
+ - `format` is what type of nodes to write any newly created directories as (default: `dag-pb`)
+ - `hashAlg` is which algorithm to use when creating CIDs for newly created directories (default: `sha2-256`)
+ - `flush` is a Boolean value to decide whether or not to immediately flush MFS changes to disk (default: true)
+- `callback` is an optional function with the signature `function (error) {}`, where `error` may be an Error that occured if the operation was not successful
If no `callback` is passed, a promise is returned.
@@ -652,27 +685,25 @@ ipfs.files.mkdir('/my/beautiful/directory', (err) => {
##### `Go` **WIP**
-##### `JavaScript` - ipfs.files.stat(path, [options, callback])
+##### `JavaScript` - ipfs.files.stat(path, [options], [callback])
Where:
-- `path` is the path to the directory to stat.
+- `path` is the path to the file or directory to stat
- `options` is an optional Object that might contain the following keys:
- - `hash` is a Boolean value to return only the hash.
- - `size` is a Boolean value to return only the size.
- - `withLocal` is a Boolean value to compute the amount of the dag that is local, and if possible the total size.
-
-`callback` must follow the `function (err, stat) {}` signature, where `err` is an Error if the operation was not successful and `stat` is an Object with the following keys:
-
-- `hash` is a string with the hash.
-- `size` is an integer with the size in Bytes.
-- `cumulativeSize` is an integer with the cumulative size in Bytes.
-- `blocks` is an integer indicating the number of blocks.
-- `type` is a string that can be either `directory` or `file`.
-- `withLocality` is a boolean to indicate if locality information are present.
-- `local` is a boolean to indicate if the queried dag is fully present locally.
-- `sizeLocal` is an integer indicating the cumulative size of the data present locally.
-
+ - `hash` is a Boolean value to return only the hash (default: false)
+ - `size` is a Boolean value to return only the size (default: false)
+ - `withLocal` is a Boolean value to compute the amount of the dag that is local, and if possible the total size (default: false)
+- `callback` is an optional function with the signature `function (error, stats) {}`, where `error` may be an Error that occured if the operation was not successful and `stats` is an Object with the following keys:
+
+- `hash` is a string with the hash
+- `size` is an integer with the file size in Bytes
+- `cumulativeSize` is an integer with the size of the DAGNodes making up the file in Bytes
+- `type` is a string that can be either `directory` or `file`
+- `blocks` if `type` is `directory`, this is the number of files in the directory. If it is `file` it is the number of blocks that make up the file
+- `withLocality` is a boolean to indicate if locality information are present
+- `local` is a boolean to indicate if the queried dag is fully present locally
+- `sizeLocal` is an integer indicating the cumulative size of the data present locally
If no `callback` is passed, a promise is returned.
@@ -698,15 +729,14 @@ ipfs.files.stat('/file.txt', (err, stats) => {
##### `Go` **WIP**
-##### `JavaScript` - ipfs.files.rm(path, [options, callback])
+##### `JavaScript` - ipfs.files.rm(...paths, [options], [callback])
Where:
-- `path` is the path of the file to remove.
+- `paths` are one or more paths to remove
- `options` is an optional Object that might contain the following keys:
- - `recursive` is a Boolean value to decide whether or not to remove directories recursively.
-
-`callback` must follow the `function (err) {}` signature, where `err` is an Error if the operation was not successful.
+ - `recursive` is a Boolean value to decide whether or not to remove directories recursively (default: false)
+- `callback` is an optional function with the signature `function (error) {}`, where `error` may be an Error that occured if the operation was not successful
If no `callback` is passed, a promise is returned.
@@ -720,6 +750,13 @@ ipfs.files.rm('/my/beautiful/file.txt', (err) => {
}
})
+// To remove multiple files
+ipfs.files.rm('/my/beautiful/file.txt', '/my/other/file.txt', (err) => {
+ if (err) {
+ console.error(err)
+ }
+})
+
// To remove a directory
ipfs.files.rm('/my/beautiful/directory', { recursive: true }, (err) => {
if (err) {
@@ -738,19 +775,20 @@ ipfs.files.rm('/my/beautiful/directory', { recursive: true }, (err) => {
Where:
-- `path` is the path of the file to read.
+- `path` is the path of the file to read and must point to a file (and not a directory)
- `options` is an optional Object that might contain the following keys:
- - `offset` is an Integer with the byte offset to begin reading from.
- - `count` is an Integer with the maximum number of bytes to read.
-
-`callback` must follow the `function (err, buf) {}` signature, where `err` is an Error if the operation was not successful and `buf` is a [`Buffer`][b] with the contents of `path`.
+ - `offset` is an Integer with the byte offset to begin reading from (default: 0)
+ - `length` is an Integer with the maximum number of bytes to read (default: Read to end of stream)
+- `callback` is an optional function with the signature `function (error, buffer) {}`, where `error` may be an Error that occured if the operation was not successful and `buffer` is a [`Buffer`][b] with the contents of `path`
If no `callback` is passed, a promise is returned.
+N.b. this method is likely to result in high memory usage, you should use [files.readReadableStream](#filesreadreadablestream) or [files.readPullStream](#filesreadpullstream) instead where possible.
+
**Example:**
```JavaScript
-ipfs.files.read('/hello-world', (err, buf) => {
+ipfs.files.read('/hello-world', (error, buf) => {
console.log(buf.toString('utf8'))
})
@@ -767,10 +805,10 @@ ipfs.files.read('/hello-world', (err, buf) => {
Where:
-- `path` is the path of the file to read.
+- `path` is the path of the file to read and must point to a file (and not a directory)
- `options` is an optional Object that might contain the following keys:
- - `offset` is an Integer with the byte offset to begin reading from.
- - `count` is an Integer with the maximum number of bytes to read.
+ - `offset` is an Integer with the byte offset to begin reading from (default: 0)
+ - `length` is an Integer with the maximum number of bytes to read (default: Read to end of stream)
Returns a [`ReadableStream`][rs] with the contents of `path`.
@@ -793,10 +831,10 @@ stream.on('data', (buf) => console.log(buf.toString('utf8')))
Where:
-- `path` is the path of the file to read.
+- `path` is the path of the file to read and must point to a file (and not a directory)
- `options` is an optional Object that might contain the following keys:
- - `offset` is an Integer with the byte offset to begin reading from.
- - `count` is an Integer with the maximum number of bytes to read.
+ - `offset` is an Integer with the byte offset to begin reading from (default: 0)
+ - `length` is an Integer with the maximum number of bytes to read (default: Read to end of stream)
Returns a [`PullStream`][ps] with the contents of `path`.
@@ -818,11 +856,11 @@ pull(
##### `Go` **WIP**
-##### `JavaScript` - ipfs.files.write(path, content, [options, callback])
+##### `JavaScript` - ipfs.files.write(path, content, [options], [callback])
Where:
-- `path` is the path of the file to write.
+- `path` is the path of the file to write
- `content` can be:
- a [`Buffer`][b]
- a [`PullStream`][ps]
@@ -830,12 +868,11 @@ Where:
- a [`Blob`][blob] (caveat: will only work in the browser)
- a string path to a file (caveat: will only work in Node.js)
- `options` is an optional Object that might contain the following keys:
- - `offset` is an Integer with the byte offset to begin writing at.
- - `create` is a Boolean to indicate to create the file if it doesn't exist.
- - `truncate` is a Boolean to indicate if the file should be truncated to size 0 before writing.
- - `count` is an Integer with the maximum number of bytes to read.
-
-`callback` must follow the `function (err) {}` signature, where `err` is an Error if the operation was not successful.
+ - `offset` is an Integer with the byte offset to begin writing at (default: 0)
+ - `create` is a Boolean to indicate to create the file if it doesn't exist (default: false)
+ - `truncate` is a Boolean to indicate if the file should be truncated after writing all the bytes from `content` (default: false)
+ - `length` is an Integer with the maximum number of bytes to read (default: Read all bytes from `content`)
+- `callback` is an optional function with the signature `function (error) {}`, where `error` may be an Error that occured if the operation was not successful
If no `callback` is passed, a promise is returned.
@@ -853,21 +890,47 @@ ipfs.files.write('/hello-world', Buffer.from('Hello, world!'), (err) => {
##### `Go` **WIP**
-##### `JavaScript` - ipfs.files.mv([from, to], [callback])
+##### `JavaScript` - ipfs.files.mv(...from, to, [options], [callback])
Where:
-- `from` is the path of the source file to move.
-- `to` is the path of the destination file to move to.
+- `from` is the path(s) of the source to move
+- `to` is the path of the destination to move to
+- `options` is an optional Object that might contain the following keys:
+ - `parents` is a Boolean value to decide whether or not to make the parent directories if they don't exist (default: false)
+ - `format` is what type of nodes to write any newly created directories as (default: `dag-pb`)
+ - `hashAlg` is which algorithm to use when creating CIDs for newly created directories (default: `sha2-256`)
+ - `flush` is a Boolean value to decide whether or not to immediately flush MFS changes to disk (default: true)
+- `callback` is an optional function with the signature `function (error) {}`, where `error` may be an Error that occured if the operation was not successful
+
+If `from` has multiple values then `to` must be a directory.
+
+If `from` has a single value and `to` exists and is a directory, `from` will be moved into `to`.
+
+If `from` has a single value and `to` exists and is a file, `from` must be a file and the contents of `to` will be replaced with the contents of `from` otherwise an error will be returned.
-`callback` must follow the `function (err) {}` signature, where `err` is an Error if the operation was not successful.
+If `from` is an IPFS path, and an MFS path exists with the same name, the IPFS path will be chosen.
+
+All values of `from` will be removed after the operation is complete, unless they are an IPFS path.
If no `callback` is passed, a promise is returned.
**Example:**
```JavaScript
-ipfs.files.mv(['/src-file', '/dst-file'], (err) => {
+ipfs.files.mv('/src-file', '/dst-file', (err) => {
+ if (err) {
+ console.error(err)
+ }
+})
+
+ipfs.files.mv('/src-dir', '/dst-dir', (err) => {
+ if (err) {
+ console.error(err)
+ }
+})
+
+ipfs.files.mv('/src-file1', '/src-file2', '/dst-dir', (err) => {
if (err) {
console.error(err)
}
@@ -880,13 +943,12 @@ ipfs.files.mv(['/src-file', '/dst-file'], (err) => {
##### `Go` **WIP**
-##### `JavaScript` - ipfs.files.flush([path, callback])
+##### `JavaScript` - ipfs.files.flush([...paths], [callback])
Where:
-- `path` is the path to flush. Default is `/`.
-
-`callback` must follow the `function (err) {}` signature, where `err` is an Error if the operation was not successful.
+- `paths` are an optional string paths to flush (default: `/`)
+- `callback` is an optional function with the signature `function (error) {}`, where `error` may be an Error that occured if the operation was not successful
If no `callback` is passed, a promise is returned.
@@ -906,20 +968,17 @@ ipfs.files.flush('/', (err) => {
##### `Go` **WIP**
-##### `JavaScript` - ipfs.files.ls([path, options, callback])
+##### `JavaScript` - ipfs.files.ls([path], [callback])
Where:
-- `path` is the path to show listing for. Defaults to `/`.
-- `options` is an optional Object that might contain the following keys:
- - `l` is a Boolean value o use long listing format.
-
-`callback` must follow `function (err, files) {}` signature, where `err` is an error if the operation was not successful. `files` is an array containing Objects that contain the following keys:
+- `path` is an optional string to show listing for (default: `/`)
+- `callback` is an optional function with the signature `function (error, files) {}`, where `error` may be an Error that occured if the operation was not successful and `files` is an array containing Objects that contain the following keys:
-- `name` which is the file's name.
-- `type` which i the object's type (`directory` or `file`).
-- `size` the size of the file in bytes.
-- `hash` the hash of the file.
+- `name` which is the file's name
+- `type` which i the object's type (`directory` or `file`)
+- `size` the size of the file in bytes
+- `hash` the hash of the file
If no `callback` is passed, a promise is returned.
diff --git a/SPEC/PIN.md b/SPEC/PIN.md
index bc0aeeb1..1f27b140 100644
--- a/SPEC/PIN.md
+++ b/SPEC/PIN.md
@@ -16,7 +16,7 @@ Where:
- `hash` is an IPFS multihash.
- `options` is an object that can contain the following keys
- - 'recursive' - Recursively pin the object linked. Type: bool. Default: `false`
+ - 'recursive' - Recursively pin the object linked. Type: bool. Default: `true`
`callback` must follow `function (err, res) {}` signature, where `err` is an error if the operation was not successful. `res` is an array of objects that represent the files that were pinned. Example:
@@ -76,7 +76,7 @@ A great source of [examples][] can be found in the tests for this API.
Where:
- `hash` is a multihash.
- `options` is an object that can contain the following keys
- - 'recursive' - Recursively unpin the object linked. Type: bool. Default: `false`
+ - 'recursive' - Recursively unpin the object linked. Type: bool. Default: `true`
`callback` must follow `function (err) {}` signature, where `err` is an error if the operation was not successful.
diff --git a/SPEC/PUBSUB.md b/SPEC/PUBSUB.md
index 5e20cd97..5fd8e9c2 100644
--- a/SPEC/PUBSUB.md
+++ b/SPEC/PUBSUB.md
@@ -6,12 +6,6 @@
* [pubsub.ls](#pubsubls)
* [pubsub.peers](#pubsubpeers)
-* [pubsub.subscribe](#pubsubsubscribe)
-* [pubsub.unsubscribe](#pubsubunsubscribe)
-* [pubsub.publish](#pubsubpublish)
-* [pubsub.ls](#pubsubls)
-* [pubsub.peers](#pubsubpeers)
-
#### `pubsub.subscribe`
> Subscribe to a pubsub topic.
@@ -108,7 +102,7 @@ If no `callback` is passed, a promise is returned.
```JavaScript
const topic = 'fruit-of-the-day'
-const msg = new Buffer('banana')
+const msg = Buffer.from('banana')
ipfs.pubsub.publish(topic, msg, (err) => {
if (err) {
diff --git a/js/src/bitswap.js b/js/src/bitswap.js
new file mode 100644
index 00000000..0999e9da
--- /dev/null
+++ b/js/src/bitswap.js
@@ -0,0 +1,159 @@
+/* eslint-env mocha */
+'use strict'
+
+const chai = require('chai')
+const dirtyChai = require('dirty-chai')
+const series = require('async/series')
+const expect = chai.expect
+const statsTests = require('./utils/stats')
+const spawn = require('./utils/spawn')
+chai.use(dirtyChai)
+const CID = require('cids')
+
+module.exports = (common) => {
+ describe('.bitswap online', () => {
+ let ipfsA
+ let ipfsB
+ let withGo
+ let ipfsBId
+ const key = 'QmUBdnXXPyoDFXj3Hj39dNJ5VkN3QFRskXxcGaYFBB8CNR'
+
+ before(function (done) {
+ // CI takes longer to instantiate the daemon, so we need to increase the
+ // timeout for the before step
+ this.timeout(60 * 250)
+
+ common.setup((err, factory) => {
+ expect(err).to.not.exist()
+ series([
+ (cb) => spawn.spawnNodeWithId(factory, (err, node) => {
+ expect(err).to.not.exist()
+ ipfsA = node
+ withGo = node.peerId.agentVersion.startsWith('go-ipfs')
+ cb()
+ }),
+ (cb) => spawn.spawnNodeWithId(factory, (err, node) => {
+ expect(err).to.not.exist()
+ ipfsB = node
+ ipfsBId = node.peerId
+ ipfsB.block.get(new CID(key))
+ .then(() => {})
+ .catch(() => {})
+ ipfsA.swarm.connect(ipfsBId.addresses[0], (err) => {
+ expect(err).to.not.exist()
+ setTimeout(cb, 350)
+ })
+ })
+ ], done)
+ })
+ })
+
+ after((done) => common.teardown(done))
+
+ it('.stat', (done) => {
+ ipfsB.bitswap.stat((err, stats) => {
+ expect(err).to.not.exist()
+ statsTests.expectIsBitswap(err, stats)
+ done()
+ })
+ })
+
+ it('.wantlist', (done) => {
+ ipfsB.bitswap.wantlist((err, list) => {
+ expect(err).to.not.exist()
+ expect(list.Keys).to.have.length(1)
+ expect(list.Keys[0]['/']).to.equal(key)
+ done()
+ })
+ })
+
+ it('.wantlist peerid', (done) => {
+ ipfsA.bitswap.wantlist(ipfsBId.id, (err, list) => {
+ expect(err).to.not.exist()
+ expect(list.Keys[0]['/']).to.equal(key)
+ done()
+ })
+ })
+
+ it('.unwant', function (done) {
+ if (withGo) {
+ this.skip()
+ }
+ ipfsB.bitswap.unwant(key, (err) => {
+ expect(err).to.not.exist()
+ ipfsB.bitswap.wantlist((err, list) => {
+ expect(err).to.not.exist()
+ expect(list.Keys).to.be.empty()
+ done()
+ })
+ })
+ })
+ })
+
+ describe('.bitswap offline', () => {
+ let ipfs
+
+ before(function (done) {
+ // CI takes longer to instantiate the daemon, so we need to increase the
+ // timeout for the before step
+ this.timeout(60 * 1000)
+
+ common.setup((err, factory) => {
+ expect(err).to.not.exist()
+ factory.spawnNode((err, node) => {
+ expect(err).to.not.exist()
+ ipfs = node
+ ipfs.id((err, id) => {
+ expect(err).to.not.exist()
+ ipfs.stop((err) => {
+ // TODO: go-ipfs returns an error, https://github.com/ipfs/go-ipfs/issues/4078
+ if (!id.agentVersion.startsWith('go-ipfs')) {
+ expect(err).to.not.exist()
+ }
+ done()
+ })
+ })
+ })
+ })
+ })
+
+ it('.stat gives error while offline', (done) => {
+ ipfs.bitswap.stat((err, stats) => {
+ expect(err).to.exist()
+ // When run against core we get our expected error, when run
+ // as part of the http tests we get a connection refused
+ if (err.code !== 'ECONNREFUSED') {
+ expect(err).to.match(/online mode/)
+ }
+ expect(stats).to.not.exist()
+ done()
+ })
+ })
+
+ it('.wantlist gives error if offline', (done) => {
+ ipfs.bitswap.wantlist((err, list) => {
+ expect(err).to.exist()
+ // When run against core we get our expected error, when run
+ // as part of the http tests we get a connection refused
+ if (err.code !== 'ECONNREFUSED') {
+ expect(err).to.match(/online mode/)
+ }
+ expect(list).to.not.exist()
+ done()
+ })
+ })
+
+ it('.unwant gives error if offline', (done) => {
+ const key = 'QmUBdnXXPyoDFXj3Hj39dNJ5VkN3QFRskXxcGaYFBB8CNR'
+ ipfs.bitswap.unwant(key, (err) => {
+ expect(err).to.exist()
+ // When run against core we get our expected error, when run
+ // as part of the http tests we get a connection refused
+ if (err.code !== 'ECONNREFUSED') {
+ expect(err).to.match(/online mode/)
+ }
+ done()
+ })
+ })
+ })
+}
diff --git a/js/src/index.js b/js/src/index.js
index dd2012e9..07904c43 100644
--- a/js/src/index.js
+++ b/js/src/index.js
@@ -19,3 +19,4 @@ exports.repo = require('./repo')
exports.bootstrap = require('./bootstrap')
exports.types = require('./types')
exports.util = require('./util')
+exports.bitswap = require('./bitswap')
diff --git a/package.json b/package.json
index 1aca264b..ddd94073 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "interface-ipfs-core",
- "version": "0.67.0",
+ "version": "0.68.0",
"description": "A test suite and interface you can use to implement a IPFS core interface.",
"leadMaintainer": "Alan Shaw ",
"main": "js/src/index.js",
@@ -65,9 +65,12 @@
"Haad ",
"Henrique Dias ",
"Jacob Heun ",
+ "Jacob Karlsson ",
"Jason Papakostas ",
"Joel Gustafson ",
+ "Jonathan ",
"Kevin Simper ",
+ "Maciej Krüger ",
"Marius Darila ",
"Matt Zumwalt ",
"Michael Garvin ",