Open Gozala opened 4 years ago
Thanks! These are great suggestions.
We definitely have plans to expose browser native APIs via both getFile and addFile, so your suggestions will help define what that will look like :)
The one catch at the moment is, we need the IPFS-Lite interface to match that of js-ipld
, or at least, those core methods for now. So that's why we have the getFile
and addFile
as separate APIs in there (they aren't part of the IPLD interface).
Having said that, as is, addFile
does not depend on node read streams, that's just an example. At the moment we are depending on https://github.com/ipfs/js-ipfs-unixfs-importer{/exporter}, which does indeed use Buffers and other less-nice things. This was mostly to avoid having to re-write everything from scratch... but I'd like to re-implement some of that anyway, as it is actually pretty heavy handed for what we need here for the most part. Good call.
I really like the Response
suggestion for getFile
... let's do that. Though not sure sure what your head
API would be used for?
Similarly, addFile
most certainly should support FormData
and the native Files/Blob
API. I'll create separate issues for those two (and certainly, PRs are welcome :)).
Building on this, I think I have a nice idea to make the API easier to use... see https://github.com/textileio/js-ipfs-lite/tree/carson/restructure/src/files which is where we could put all the nicer browser native files stuff... an example of how we'd do this in a browser/nodejs compatible way is here: https://github.com/textileio/js-ipfs-lite/tree/carson/restructure/src/setup
I'm working on web server which is based on WebAPI Streams, and there is one issue with the disturbed stream. You can read more here: https://github.com/whatwg/streams/issues/1025. In a few words, there is no way to specify wether the current stream will provide an initial chunk of data on read in a browser. But there is a hack to do so:
function isStreamDisturbed(stream: ReadableStream): Boolean {
try {
new Response(stream)
return false
}
catch {
return true
}
}
const stream = new ReadableStream()
stream.cancel()
isStreamDisturbed(stream) // -> true
I often struggle using JS-IPFS in the browser because it predates all the nice web APIs that made working with binary data and files convenient. Often time this implies to using some node polyfills and / or needing to convert node constructs to browser ones so that other browser APIs can interact with it.
Here are few things that I have noticed.
addFile
depends on node read stream etc.. https://github.com/textileio/js-ipfs-lite/blob/0bb38fc91e10c480aef3109fde9ef98612a9c5a4/src/index.ts#L110-L124I would suggest to use web native
File
API instead which can have apath
and can be constructed in arbitrary ways.As of files bundles there is
FormData
and I think it would make more sense to us that instead. It also has advantage that web forms can directly be written to IPFS. And all this works well withfetch
andXMLHTTPRequest
stuff.getFile
returns nodeBuffer
. Which luckily in browser pollyfill implemented as a subclass ofUint8Array
so it is somewhat more usable. However that still implies allocating memory for the whole content etc... On the other hand web has aResponse
API available who's body can be read as string, bytes, json,FormData
or a stream. In fact it's also possible to use slices over the whole thing and also has notion ofError
. It also can be stored in browsercache
etc...I would propose to draw inspiration from web native APIs and try to be as similar to
fetch
API as possible so it can be used as a drop in replacement. Specifically I'd very much prefer following intterface: