# 🔦 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 (opens new window) from the network, and that CID (opens new window) 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 (opens new window) is returned from the API call to resolve a piece of content and the Promises spec (opens new window) includes nothing about cancelling a Promise.
However, the browser fetch API (opens new window) has a notion of an AbortSignal (opens new window) which can be used to abort web requests. They are interacted with via an AbortController (opens new window):
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 (opens new window) 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 (opens new window), 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 (opens new window) has been the datastore of choice for application data (though blocks have been stored on the filesystem) and go-IPFS is moving to Badger (opens new window)).
Out of this grew interface-datastore (opens new window) — a spec for storing key/value pairs implemented by the datastores used by IPFS. In the browser this was datastore-level (opens new window) which was backed by level-js (opens new window), which was backed by IndexedDB.
Phew.
To remove a few layers here, we’ve created the datastore-idb (opens new window) 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
- Cancellable API calls (#2993 (opens new window)) (2b24f59 (opens new window)), closes #3015 (opens new window)
ipfs.block.put
now accepts thepin
argument in line with go-ipfs #3015 (opens new window)
# 🦟 Bugs fixed
- Fixes browser script tag example (#3034 (opens new window)) (ee8b769 (opens new window)), closes #3027 (opens new window)
- No longer produces browser bundle with all IPLD formats in the browser (#3025 (opens new window)) (e6079c1 (opens new window))
typeof
bug when passing timeout to dag.get (#3035 (opens new window)) (026a542 (opens new window))- Removes use of node globals and built ins to prepare us for when browser bundlers stop automatically including them (opens new window) #2932 (opens new window)
- Source maps are no longer included with production builds ipfs/aegir#549 (opens new window)
# 🗺️ What’s next?
Check out the js-ipfs Project Roadmap (opens new window) 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
- @5310 (opens new window) (2 comments)
- @achingbrain (opens new window) (55 commits, 17 PRs, 3 issues, 33 comments)
- @alanshaw (opens new window) (1 issue, 3 comments)
- @aphelionz (opens new window) (2 comments)
- @AuHau (opens new window) (1 comment)
- @autonome (opens new window) (1 comment)
- @bertrandfalguiere (opens new window) (1 comment)
- @betamos (opens new window) (1 PR, 1 issue, 7 comments)
- @bluelovers (opens new window) (1 PR, 1 comment)
- @carsonfarmer (opens new window) (1 commit)
- @codecov-io (opens new window) (1 comment)
- @corporatepiyush (opens new window) (1 issue)
- @dapplion (opens new window) (2 comments)
- @dirkmc (opens new window) (2 commits)
- @Gozala (opens new window) (5 issues, 15 comments)
- @hugomrdias (opens new window) (11 commits, 4 PRs, 1 issue, 17 comments)
- @jacobheun (opens new window) (8 commits, 2 PRs, 1 issue, 8 comments)
- @jakehemmerle (opens new window) (3 comments)
- @koivunej (opens new window) (1 comment)
- @lidel (opens new window) (1 commit, 2 comments)
- @mdtanrikulu (opens new window) (1 issue, 1 comment)
- @mistakia (opens new window) (1 PR)
- @npfoss (opens new window) (1 commit, 1 PR, 1 issue)
- @obo20 (opens new window) (1 commit, 1 PR, 1 comment)
- @oed (opens new window) (1 comment)
- @RobertFischer (opens new window) (1 comment)
- @robertkiel (opens new window) (1 comment)
- @rvagg (opens new window) (1 PR, 1 comment)
- @spasimir21 (opens new window) (1 issue, 3 comments)
- @stensonb (opens new window) (1 commit, 13 PRs)
- @thattommyhall (opens new window) (1 PR, 3 comments)
- @typhu-xyz (opens new window) (1 comment)
- @vasco-santos (opens new window) (14 commits, 15 PRs, 2 issues, 16 comments)
- @vmx (opens new window) (5 commits, 1 PR, 2 comments)
- @welcome (19 comments)
- @wemeetagain (opens new window) (2 commits, 1 PR, 3 comments)
# 🙌🏽 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:
- Check the issues with the
help wanted
label in the js-ipfs repo (opens new window) - Join an IPFS All Hands, introduce yourself and let us know where you would like to contribute: https://github.com/ipfs/team-mgmt/#weekly-ipfs-all-hands
- Hack with IPFS and show us what you made! The All Hands call is also the perfect venue for demos, join in and show us what you built
- Join the discussion at https://discuss.ipfs.tech/ and help users finding their answers.
- Join the 🚀 IPFS Core Implementations Weekly Sync 🛰 (opens new window) and be part of the action!
# ⁉️ 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.tech (opens new window). We are also available at the #ipfs
channel on Freenode.