ipfs / js-dag-service

Library for storing and replicating hash-linked data over the IPFS network.
Other
93 stars 17 forks source link

Prefer web APIs over node APIs #13

Open Gozala opened 4 years ago

Gozala commented 4 years ago

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.

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:

interface Peer {
  put(FormData|File|Blob):Promise<CID>
  get(CID|Path):Response;
  head(CID|Path):Response; // 404 if not found, 502 if network is spotty
  delete(CID):Response; // Delete from local storage
}
carsonfarmer commented 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 :)).

carsonfarmer commented 4 years ago

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

rumkin commented 4 years ago

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