The one true API, the ipfsx upgrade path #2509
Description
Land #1670 🤯 🎊 😅
#2506 (comment)
But what does that mean though?
Something that bothers me is that we already support promises & callbacks in the API, so removing callbacks doesn't really give our users anything except a whole bunch of refactoring for those who do used the callbackified API. That can't be the end goal of #1670.
I think we should get on and implement ipfsx
.
We've seen the API grow organically over time and it doesn't present the most streamlined interface. The key point is that IPFS is all about files, yet loads of the file operations are not top-level operations. Plus we have confusing caveat-filled weirdness with things like ipfs.ls
and ipfs.files.ls
.
The ipfsx
approach is to finally unify the files API and move them all to the top level front and centre and have the low level stuff grouped by domain (e.g. block
, dag
, etc). It also removes readable streams, pull streams, etc giving us a smaller, more focused API surface area and (hopefully) smaller bundle size. I think we're all agreed that this is where we're heading.
As the internals follow the path of ipfs._addAsyncIterator
we can start to implement ipfsx on top of them, then eventually split out the current API as a separate module to ease upgrading for people.
Step 1
Allow the user to expose the new API as an experimental flag. The old API will not be exposed - this may mean that some operations are impossible until they are implemented. Welcome to the bleeding edge.
const IPFS = require('ipfs')
const ipfs = await IPFS.create({
EXPERIMENTAL: {
ipfsx: true
}
// ... other options
})
// call the new API
await ipfs.mkdir('/somedir')
Step 2
Once the API is implemented, remove the old API entirely, deps and all. This should give us a leaner bundle and small surface area for those who have kept up to date.
Then create a wrapper for the new API that implements the old by calling new API methods and is callbackified/promisified/promise-nodified. This gives existing users a smooth upgrade path.
We should be able to verify it using today's interface-ipfs-core
suite, though we should make tomorrow's version will only test the ipfsx
interface.
const IPFS = require('ipfs')
const legacy = require('ipfs-legacy')
const ipfs = await legacy(IPFS).create({
// ... other options
}))
// call the old API
await ipfs.files.mkdir('/somedir')