56 lines
1.1 KiB
JavaScript
56 lines
1.1 KiB
JavaScript
|
|
|
|
export const streamChunk = function* (chunk, chunkSize) {
|
|
let len = chunk.byteLength;
|
|
|
|
if (!chunkSize || len < chunkSize) {
|
|
yield chunk;
|
|
return;
|
|
}
|
|
|
|
let pos = 0;
|
|
let end;
|
|
|
|
while (pos < len) {
|
|
end = pos + chunkSize;
|
|
yield chunk.slice(pos, end);
|
|
pos = end;
|
|
}
|
|
}
|
|
|
|
export const readBytes = async function* (iterable, chunkSize, encode) {
|
|
for await (const chunk of iterable) {
|
|
yield* streamChunk(ArrayBuffer.isView(chunk) ? chunk : (await encode(String(chunk))), chunkSize);
|
|
}
|
|
}
|
|
|
|
export const trackStream = (stream, chunkSize, onProgress, onFinish, encode) => {
|
|
const iterator = readBytes(stream, chunkSize, encode);
|
|
|
|
let bytes = 0;
|
|
|
|
return new ReadableStream({
|
|
type: 'bytes',
|
|
|
|
async pull(controller) {
|
|
const {done, value} = await iterator.next();
|
|
|
|
if (done) {
|
|
controller.close();
|
|
onFinish();
|
|
return;
|
|
}
|
|
|
|
let len = value.byteLength;
|
|
onProgress && onProgress(bytes += len);
|
|
controller.enqueue(new Uint8Array(value));
|
|
},
|
|
cancel(reason) {
|
|
onFinish(reason);
|
|
return iterator.return();
|
|
}
|
|
}, {
|
|
highWaterMark: 2
|
|
})
|
|
}
|