Last active
December 22, 2025 03:14
-
-
Save mhart/dc7320acacd3e5a635f39db1fe767fd7 to your computer and use it in GitHub Desktop.
A utility function that creates/reads a byte stream (eg request.body) with larger chunks (defaults to 256KB)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export default { | |
| async fetch(request: Request) { | |
| const chunkedRequestBody = request.body && chunkStream(request.body); | |
| return new Response(chunkedRequestBody); | |
| }, | |
| }; | |
| // By default will emit chunks of length `chunkSize` (default 256KB). | |
| // If you wish to emit as soon as available, you can pass in `allowPartial: true`, | |
| // you may just end up with more buffers, some smaller than `chunkSize`. | |
| function chunkStream( | |
| sourceStream: ReadableStream<Uint8Array>, | |
| { chunkSize = 256 * 1024, allowPartial = false }: { chunkSize?: number; allowPartial?: boolean } = {}, | |
| ): ReadableStream<Uint8Array> { | |
| const reader = sourceStream.getReader({ mode: "byob" }); | |
| return new ReadableStream({ | |
| async pull(controller) { | |
| const { done, value } = await reader.read( | |
| new Uint8Array(new ArrayBuffer(chunkSize)), | |
| // @ts-expect-error 2nd arg currently missing from @cloudflare/workers-types | |
| allowPartial ? undefined : { min: chunkSize }, | |
| ); | |
| if (value != null && value.byteLength > 0) { | |
| controller.enqueue(new Uint8Array(value.buffer, 0, value.byteLength)); | |
| } | |
| if (done) { | |
| controller.close(); | |
| } | |
| }, | |
| cancel(reason) { | |
| return reader.cancel(reason); | |
| }, | |
| }); | |
| } | |
| // Or a class version if you want to do `new ChunkedStream(sourceStream)` | |
| class ChunkedStream extends ReadableStream<Uint8Array> { | |
| constructor( | |
| sourceStream: ReadableStream<Uint8Array>, | |
| { chunkSize = 256 * 1024, allowPartial = false }: { chunkSize?: number; allowPartial?: boolean } = {}, | |
| ) { | |
| const reader = sourceStream.getReader({ mode: "byob" }); | |
| super({ | |
| async pull(controller) { | |
| // as above... | |
| }, | |
| cancel(reason) { | |
| // as above... | |
| }, | |
| }); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment