posit-dev / shinylive

Run Shiny on Python and R (compiled to wasm) in the browser
https://shinylive.io/py/examples/
MIT License
179 stars 14 forks source link

Handling large files inputs/upload #148

Closed rariariari closed 1 week ago

rariariari commented 2 weeks ago

When building a shinylive app that accepts user uploads, large files produce errors. I found one recent post mentioning this issue, with no replies.

Locally hosting the static server with httpuv and inspecting in console, the error thrown when uploading a large file is:

Uncaught (in promise) RangeError: Invalid array length
    at Function.from (<anonymous>)
    at handleHttpuvRequests (shinylive.js:32198:52)
    at async makeHttpuvRequest (shinylive.js:32183:3)
    at async WebRWorkerProxy.makeRequest (shinylive.js:33904:5)

Which is produced in the shinylive.js script at the line (32198):

const bytes = await new shelter.RRaw(Array.from(body));

The error is produced because Chrome (the browser I tested with) does not allow javascript Arrays to be larger than 10 million elements while it does allow Uint8 arrays to be larger. Locally, the issue was fixed by removing the casting to Array from the Uint8 array, such that the prior line became:

const bytes = await new shelter.RRaw(body);

Admittedly, I don't know how robust this fix is, or the reason why Array.from() is used. Maybe there's a cleaner fix. Regardless, it'd be useful to allow for large file inputs for shinylive apps.

bschneidr commented 2 weeks ago

Thanks for posting this @rariariari. This would be very helpful for using Shinylive in production applications.

georgestagg commented 1 week ago

Thanks for this report! The Array.from() was previously required for older versions of webR where constructing an R raw atomic vector directly from a JS Uint8Array was not possible.

As you have observed, the problem has been fixed in the current webR release and we can now remove the workaround, in the way you have suggested.