Conversation
aron
left a comment
There was a problem hiding this comment.
I'm not 100% sure this is the right fix here. I'm curious why your example code in the ticket isn't being uploaded as a file, will reply on the ticket.
| const uint8Array = new Uint8Array(bytes); | ||
| let binaryString = ""; | ||
| for (let i = 0; i < uint8Array.length; i++) { | ||
| binaryString += String.fromCharCode(uint8Array[i]); |
There was a problem hiding this comment.
It's been a while since I looked at JS string performance but this change makes me nervous. I believe JS strings are immutable so each time we add a character here it's making a copy of the string leaving the old one to be garbage collected.
If the issue here is that the the number of bytes passed to Uint8Array is too large, then I have a feeling this is potentially going to consume a lot of memory. An alternative would be to build an array and use join() but as this implementation was supposed to be a quick "good enough" hack, at this point I think we'd be better off re-considering vendoring in a proper cross-platform base64 lib and avoiding the use of btoa altogether.
|
Alternative is to ship #184, where "each binary input is uploaded and replaced with a URL to the created file". That's fine with me! |
Resolves #247
This PR was written by the language model gods. Here's what they have to say about the reasoning behind the fix:
The error "RangeError: Maximum call stack size exceeded" in the original function arises due to the use of
String.fromCharCode.apply(null, new Uint8Array(bytes)). This method attempts to convert aUint8Arrayinto a string by applyingString.fromCharCodeto each byte in the array. However, when theUint8Arrayis large, this approach leads to a very large number of arguments being passed toString.fromCharCodevia theapplymethod, which exceeds the JavaScript engine's maximum call stack size.JavaScript has a limit on the number of arguments that can be passed to a function, and exceeding this limit results in a stack overflow error, as seen here. This is particularly problematic with large binary data like images, where the byte array can be very large.
The refactored bytesToBase64 function avoids this issue by iteratively building a string from the Uint8Array using a loop. In each iteration, it converts a single byte to a character using String.fromCharCode and appends this character to a string. This method does not involve passing a large number of arguments to a function at once, thus it stays within the call stack limit and avoids the error.
This approach is more efficient in terms of memory usage and avoids the call stack limit issue, making it suitable for handling large data arrays.