Created
March 13, 2017 20:43
-
-
Save damieng/359f73c4b2ff372f7b1201a2cfcfd340 to your computer and use it in GitHub Desktop.
Download a file using just window.fetch (flowtype version)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
import fs from 'fs'; | |
export default async function download(sourceUrl: string, targetFile: string, progressCallback: ?ByteProgressCallback, length: ?number): Promise<void> { | |
const request = new Request(sourceUrl, { | |
headers: new Headers({'Content-Type': 'application/octet-stream'}) | |
}); | |
const response = await fetch(request); | |
if (!response.ok) { | |
throw Error(`Unable to download, server returned ${response.status} ${response.statusText}`); | |
} | |
const body = response.body; | |
if (body == null) { | |
throw Error('No response body'); | |
} | |
length = length || parseInt(response.headers.get('Content-Length' || '0')); | |
const reader = body.getReader(); | |
const writer = fs.createWriteStream(targetFile); | |
await streamWithProgress(length, reader, writer, progressCallback); | |
writer.end(); | |
} | |
async function streamWithProgress(length: number, reader: ReadableStreamReader, writer: fs.WriteStream, progressCallback: ?ByteProgressCallback): Promise<void> { | |
let bytesDone = 0; | |
while (true) { | |
const result = await reader.read(); | |
if (result.done) { | |
return; | |
} | |
const chunk = result.value; | |
if (chunk == null) { | |
throw 'Empty chunk received during download'; | |
} else { | |
writer.write(Buffer.from(chunk)); | |
if (progressCallback != null) { | |
bytesDone += chunk.byteLength; | |
const percent: ?number = length === 0 ? null : Math.floor(bytesDone / length * 100); | |
progressCallback(bytesDone, percent); | |
} | |
} | |
} | |
if (progressCallback != null) { | |
progressCallback(length, 100); | |
} | |
} | |
export type ByteProgressCallback = (bytesDone: number, percent: ?number) => {}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment