blobHelpers.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*! Based on fetch-blob. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> & David Frank */
  2. import { isFunction } from "./isFunction.js";
  3. const CHUNK_SIZE = 65536;
  4. async function* clonePart(part) {
  5. const end = part.byteOffset + part.byteLength;
  6. let position = part.byteOffset;
  7. while (position !== end) {
  8. const size = Math.min(end - position, CHUNK_SIZE);
  9. const chunk = part.buffer.slice(position, position + size);
  10. position += chunk.byteLength;
  11. yield new Uint8Array(chunk);
  12. }
  13. }
  14. async function* consumeNodeBlob(blob) {
  15. let position = 0;
  16. while (position !== blob.size) {
  17. const chunk = blob.slice(position, Math.min(blob.size, position + CHUNK_SIZE));
  18. const buffer = await chunk.arrayBuffer();
  19. position += buffer.byteLength;
  20. yield new Uint8Array(buffer);
  21. }
  22. }
  23. export async function* consumeBlobParts(parts, clone = false) {
  24. for (const part of parts) {
  25. if (ArrayBuffer.isView(part)) {
  26. if (clone) {
  27. yield* clonePart(part);
  28. }
  29. else {
  30. yield part;
  31. }
  32. }
  33. else if (isFunction(part.stream)) {
  34. yield* part.stream();
  35. }
  36. else {
  37. yield* consumeNodeBlob(part);
  38. }
  39. }
  40. }
  41. export function* sliceBlob(blobParts, blobSize, start = 0, end) {
  42. end !== null && end !== void 0 ? end : (end = blobSize);
  43. let relativeStart = start < 0
  44. ? Math.max(blobSize + start, 0)
  45. : Math.min(start, blobSize);
  46. let relativeEnd = end < 0
  47. ? Math.max(blobSize + end, 0)
  48. : Math.min(end, blobSize);
  49. const span = Math.max(relativeEnd - relativeStart, 0);
  50. let added = 0;
  51. for (const part of blobParts) {
  52. if (added >= span) {
  53. break;
  54. }
  55. const partSize = ArrayBuffer.isView(part) ? part.byteLength : part.size;
  56. if (relativeStart && partSize <= relativeStart) {
  57. relativeStart -= partSize;
  58. relativeEnd -= partSize;
  59. }
  60. else {
  61. let chunk;
  62. if (ArrayBuffer.isView(part)) {
  63. chunk = part.subarray(relativeStart, Math.min(partSize, relativeEnd));
  64. added += chunk.byteLength;
  65. }
  66. else {
  67. chunk = part.slice(relativeStart, Math.min(partSize, relativeEnd));
  68. added += chunk.size;
  69. }
  70. relativeEnd -= partSize;
  71. relativeStart = 0;
  72. yield chunk;
  73. }
  74. }
  75. }