I had to convert a ReadableSteam to base64 recently, and I was shocked at how much boilerplate it required in 2023:
if (isReadableStream<Uint8Array>(value)) {
const chunks = [];
for await (const chunk of value) {
chunks.push(chunk);
}
if (chunks[0].byteLength) {
const length = chunks.reduce(
(agg, next) => agg + next.length, 0
);
// Make the same species TypedArray that ReadableStream gave us.
value = new (chunks[0].constructor as Uint8ArrayConstructor)(length);
for (let i = 0, offset = 0; i < chunks.length; i++) {
value.set(chunks[i], offset);
offset += chunks[i].length;
}
} else {
throw new Error(`Unrecognized readable stream type: ${ chunks[0].constructor.name }`);
}
}
return `data:application/octet-stream;base64,${
btoa(
(value as Uint8Array).reduce(
(result, charCode) => result + String.fromCharCode(charCode),
''
)
)
}`;
I had to learn/implement a lot of little details to simply change the encoding from binary to its most common text representation. That's a day I would have rather spent doing product work.