trackStream.js 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. export const streamChunk = function* (chunk, chunkSize) {
  2. let len = chunk.byteLength;
  3. if (!chunkSize || len < chunkSize) {
  4. yield chunk;
  5. return;
  6. }
  7. let pos = 0;
  8. let end;
  9. while (pos < len) {
  10. end = pos + chunkSize;
  11. yield chunk.slice(pos, end);
  12. pos = end;
  13. }
  14. }
  15. export const readBytes = async function* (iterable, chunkSize, encode) {
  16. for await (const chunk of iterable) {
  17. yield* streamChunk(ArrayBuffer.isView(chunk) ? chunk : (await encode(String(chunk))), chunkSize);
  18. }
  19. }
  20. export const trackStream = (stream, chunkSize, onProgress, onFinish, encode) => {
  21. const iterator = readBytes(stream, chunkSize, encode);
  22. let bytes = 0;
  23. return new ReadableStream({
  24. type: 'bytes',
  25. async pull(controller) {
  26. const {done, value} = await iterator.next();
  27. if (done) {
  28. controller.close();
  29. onFinish();
  30. return;
  31. }
  32. let len = value.byteLength;
  33. onProgress && onProgress(bytes += len);
  34. controller.enqueue(new Uint8Array(value));
  35. },
  36. cancel(reason) {
  37. onFinish(reason);
  38. return iterator.return();
  39. }
  40. }, {
  41. highWaterMark: 2
  42. })
  43. }