js-ipfs 0.44.0 released

by Alex Potsides on 2020-05-21

🔦 Highlights

Cancellable requests and a new browser datastore

js-IPFS@0.44.0 is out of the door with support for cancelling requests and a leaner, meaner datastore for the browser!

🤖 Cancellable requests

A user should be able to cancel long-lived asynchronous API operations. For example, if you are fetching the content for a CID from the network, and that CID is not resolveable, you should be able to set a timeout value for the request, after which the content would no longer be sought and control would be returned to your code with an error message describing what happened.

This is not as straightforward as it seems in JavaScript because a Promise is returned from the API call to resolve a piece of content and the Promises spec includes nothing about cancelling a Promise.

However, the browser fetch API has a notion of an AbortSignal which can be used to abort web requests. They are interacted with via an AbortController:

const controller = new AbortController()

setTimeout(() => {
  controller.abort()
}, 1000)

try {
  await result = fetch('http://example.com', {
    signal: controller.signal
  })
} catch (err) {
  console.err(err) // prints: user aborted the request
}

We’ve taken this approach and integrated it into every API call, so you can now use AbortControllers to cancel requests! We’ve also used this mechanism to add a timeout option to every API call which internally uses an AbortSignal to stop the request and throw a TimeoutError after the specified amount of time:

const cid = new CID('QmWillNeverResolve')

try {
  await ipfs.get(cid, {
    timeout: 1000 // abort after 1000ms
  })
} catch (err) {
  console.err(err) // err is a TimeoutError
}

You could also roll this yourself:

const cid = new CID('QmWillNeverResolve')
const controller = new AbortController()

setTimeout(() => {
  controller.abort()
}, 1000)

try {
  await ipfs.get(cid, {
    signal: controller.signal
  })
} catch (err) {
  console.err(err)
}

The AbortSignal is passed all the way down the call stack to the libp2p and ipld components that underpin IPFS. In this initial release, timeouts are supported by the IPFS layer and in future releases libp2p and ipld will use the AbortSignal to also free up resources and perform any other necessary cleanup that would have been done if the request had completed successfully.

New browser datastore

js-IPFS@0.44.0 brings a new datastore to the browser. In the browser, all blocks and other repo data is currently stored in IndexedDB, given that it is the only way available to persist and query large amounts of user data at the time of writing.

In node and go-ipfs, LevelDB has been the datastore of choice for application data (though blocks have been stored on the filesystem) and go-IPFS is moving to Badger).

Out of this grew interface-datastore — a spec for storing key/value pairs implemented by the datastores used by IPFS. In the browser this was datastore-level which was backed by level-js, which was backed by IndexedDB.

Phew.

To remove a few layers here, we’ve created the datastore-idb which implements the interface-datastore spec, backed by IndexedDB without going via level.

What does this mean?

The new datastore is smaller and faster and the upgrade is seamless since it’s still IndexedDB under the hood:

datastore-idb up to 44% faster and 69% smaller

batch idb x 5.26 ops/sec ±4.57% (29 runs sampled)
batch level x 2.92 ops/sec ±3.76% (19 runs sampled)
Fastest is batch idb

size 37.32KB to 11.41KB

✨New features

🦟 Bugs fixed

🗺️ What’s next?

Check out the js-ipfs Project Roadmap which contains headline features organised in the order we hope them to land.

Only large features are called out in the roadmap, expect lots of small bugfix releases between the roadmapped items!

😍 Huge thank you to everyone that made this release possible

🙌🏽 Want to contribute?

Would you like to contribute to the IPFS project and don’t know how? Well, there are a few places you can get started:

⁉️ Do you have questions?

The best place to ask your questions about IPFS, how it works, and what you can do with it is at discuss.ipfs.io. We are also available at the #ipfs channel on Freenode.

Comments