diff --git a/browse/js/download.js b/browse/js/download.js index 24be58d..b489ff7 100644 --- a/browse/js/download.js +++ b/browse/js/download.js @@ -44,6 +44,12 @@ } // Trigger a download from a same-origin server URL via Content-Disposition. + // NOTE: an click is fire-and-forget — a server error + // (401/403/404/5xx) can't be observed here, so failures surface only as + // the browser's own download error, not a toast. This is deliberate: the + // folder path points at zddc-server's streamed virtual ".zip" + // endpoint, and buffering it through fetch() to make errors catchable + // would defeat the streaming (the archive can be arbitrarily large). function downloadUrl(filename, url) { var a = document.createElement('a'); a.href = url; @@ -97,9 +103,12 @@ var zip = new window.JSZip(); for (var i = 0; i < files.length; i++) { ev.statusInfo('Zipping ' + rootHandle.name + '… (' + (i + 1) + '/' + files.length + ')'); + // Hand JSZip the File (a Blob, backed by disk) rather than + // pre-reading every file's arrayBuffer — otherwise the whole + // tree's raw bytes sit in the JS heap at once before zipping. + // JSZip reads each Blob lazily during generateAsync. var f = await files[i].handle.getFile(); - var buf = await f.arrayBuffer(); - zip.file(rootHandle.name + '/' + files[i].relPath, buf); + zip.file(rootHandle.name + '/' + files[i].relPath, f); } ev.statusInfo('Generating ' + rootHandle.name + '.zip…'); var blob = await zip.generateAsync({ type: 'blob' });