jimmywarting / StreamSaver.js

StreamSaver writes stream to the filesystem directly asynchronous
https://jimmywarting.github.io/StreamSaver.js/example.html
MIT License
3.98k stars 413 forks source link

Missing documentation #123

Closed rubmz closed 4 years ago

rubmz commented 4 years ago

Hi There + Thanks for the great work!

Yet, I must say I am kind of frustrated by the documentation... It is really unclear if there is a simple way to do something I believe is one of the most basic use cases for the library: Download a large file.

Yes, there is an explanation of downloading a File/Blob - BUT - blobs do have their annoying 2GB limitation. Now, Does the library use Blobs to download files (as shown in the only example)? If so, it's not really supporting large files, as blobs themselves are limited. If it does, please correct the documentations, and separate the "Blob" from the "File" - as it really confuses.

jimmywarting commented 4 years ago

The StreamSaver lib operates on the Streams API to save files, so it dose not have a limit on how much you can save - however, In IE & Safari it will fall back to building a blob out of a stream and later download a constructed blob due to technical limitations... Latest version of the new chromium Edge, opera, chrome & firefox can handle much larger data since have all the tools needed to writes to the disc directly.

The StreamSaver api don't know anything about files or blob's, it only use it internally for the fallback solution. (#69). The public use of this API is, like i said: based on the stream API so there is not much else i can write about in the documentation. cuz if you know how the stream api works then you basically already know how the StreamSaver lib works and how it can be used.

I believe is one of the most basic use cases for the library: Download a large file. ... Does the library use Blobs to download files (as shown in the only example)?

Saving a blob is not the only example i have. maybe you just missed it. What you may want is to pipe the response.body directly to StreamSaver

jimmywarting commented 4 years ago

In a nutshell:

const url = 'https://d8d913s460fub.cloudfront.net/videoserver/cat-test-video-320x240.mp4'

const fileStream = streamSaver.createWriteStream('cat.mp4')
fetch(url).then(res => res.body.pipeTo(fileStream))

more manual code is needed if you can't use pipe

jimmywarting commented 4 years ago

if you like to get a readable stream out of a blob/file: use the new blob.stream() api or the more wider supported hack: new Response(blob).body

rubmz commented 4 years ago

Sounds cool! But the explanation you just gave me should really make it to the docs... It is the most critical point to make clear. 90% + of users uses chrome, so the fact that Safari suffers from Appleness should not be a bother for humans :~)

jimmywarting commented 4 years ago

I'm always suggesting that ppl that use files from the cloud to download stuff should be using content-disposition attachment response header instead to tell the browser to save it. wider support cross browsers, no need for any javascript. they are re-downloadable pausable also

the hole tech stuff in StreamSaver that makes everything works is basically emulating what a server dose with service workers. creating a uniq link adding content-disposition header. and open it.

So i don't really wan't to encourage users to save files using fetch + StreamSaver. both StreamSaver.js and fileSaver.js was built to save stuff that is generated in the client side like a image from canvas element or a video stream from the webcam. anything other than that i recommend using server side technology

so i'm happy with the way the docs is right now... streamsaver have nothing to do with fetch either. there are more ways to get a readableStream from more than just the fetch api.

jimmywarting commented 4 years ago

did you know that there is a download attribute that you can use also?

<a href="url" download="cat.mp4">download cat.mp4</a>
rubmz commented 4 years ago

The reason we wanted to use StreamSaver.js instead of a download link, is that a download link does not provide event information of the download progress. Also, if you want to create a button with a download link that allows to close a dialog once the download is complete, you might also need some other invention. So, there is the File API (chrome) but it uses blobs which are limited in size, and it is also not too compatible with other browsers, hence the need for another solution, based on... <tiny/big hole in the internet filled by StreamSaver.js>

jimmywarting commented 4 years ago

Okey then, just take into consideration that when you use StreamSaver it will more look and feel like the native experience. ppl will think it will be fine to click on the download link and then close the page b/c it's being downloaded in the background but it isn't cuz you are using the main thread together with StreamSaver. so you have to keep the page open and make use of unload event

there is a similar discussion about that in #97

this is also part of a reasoning i think server side downloads are better when it comes to saving a remote file