We're experiencing a bug with this package where getArrayBufferForBlob() does not account for the bytes of the Blob not being available yet after Blob.new() is called. This seems to indicate that a synchronous API somewhere is not actually synchronous. I have not dug into the C++ to figure out how that's possible. We have a JS based solution but it's inelegant.
Repro:
const foo = new Blob(['foo']);
const arrayBuffer = getArrayBufferForBlob(foo);
// tried to getArrayBufferForBlob but the bytes of the Blob weren't ready
JS based patch (with overhead):
/**
* Patches bug caused by calling getArrayBufferForBlob() right after constructing a new Blob()`.
*
* In React Native, Blobs are created via NativeBlobModule. Despite the API to
* create Blobs being synchronous, the actual bytes backing the Blob may not be
* available immmediately.
*
* This function looks for the backing arrayBuffer for a Blob, with small microsleeps
* until it is ultimately available via the JSI.
*/
async function getArrayBuffer(blob: Blob): Promise<Uint8Array> {
let arrayBuffer: Uint8Array | undefined = undefined;
try {
arrayBuffer = getArrayBufferForBlob(blob);
} catch {}
if (arrayBuffer && arrayBuffer.length === blob.size) {
return arrayBuffer;
} else {
// The buffer isn't available yet from the JSI.
// Microsleep to advance to the next runloop, and try again.
await sleep(1);
return getArrayBuffer(blob);
}
}
function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
We're experiencing a bug with this package where
getArrayBufferForBlob()
does not account for the bytes of the Blob not being available yet afterBlob.new()
is called. This seems to indicate that a synchronous API somewhere is not actually synchronous. I have not dug into the C++ to figure out how that's possible. We have a JS based solution but it's inelegant.Repro:
JS based patch (with overhead):