Replies: 1 comment
-
Hi @Nyoxis — great proposal 👏 Exposing native ReadableStream per part is the right direction (closer to Fetch/Web Streams, better back-pressure & memory). I’d suggest shipping it behind a new API with a clear migration path, plus an adapter so existing callback consumers don’t break. ✅ API shape (suggestion) Keep the current callback API as-is, and add a streaming-first variant that returns an async iterator of parts with a Web ReadableStream body: // New, non-breaking API declare function parseMultipartStream( Consumer examples Edge / Fetch runtimes for await (const part of await parseMultipartStream(request)) { Node adapter (when a Node stream is needed) import { readableWebToNode } from 'stream/web'; Back-compat adapter (emulate old “chunk callback”) async function onEachChunk(part: MultipartPart, cb: (c: Uint8Array)=>void) { 🔁 Migration & breaking-change handling Ship as new function (parseMultipartStream) and deprecate the callback style over time; keep it working via the adapter above. Provide a codemod (or docs snippet) that converts onChunk(part, buf) to for await ... over ReadableStream. Version gates: mark the old API “stable” this release; announce deprecation window before removal. 🧪 Performance & correctness checklist Back-pressure: verify slow consumer doesn’t buffer the whole file (compare RSS vs callback API). Many small parts vs few large parts benchmarks; include GC & throughput. Edge constraints: no Node-only types; ensure it runs in Workers/Deno runtimes. Security limits: maxParts, maxPartSize, maxHeaderSize, early abort on boundary abuse. Error semantics: consistent cancel/abort when consumer throws; ensure upstream stream is closed. Interoperability: example showing streaming directly to fetch()/S3 SDKs that accept Web streams. ✍️ Docs Position the old API as “callback (legacy)” and the new one as “ReadableStream (recommended)”. Provide end-to-end examples for file upload → storage and form fields without buffering. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Overview
I have implemented native
ReadableStream
support for multipart parts aiming to improve streaming efficiency and compatibility with modern standard streams. This proposal discusses the design and invites feedback from maintainers and the community.Context and Motivation
Currently, the existing PR for streaming parts uses a state change callbacks mechanism that returns chunks of parts rather than native
ReadableStreams
. My implementation differs by exposingReadableStream
instances per multipart part, which aligns better with the Fetch API and modern streaming patterns.I am unsure why originally wasn't implemented
ReadableStreams
for multipart parts yet — there might be considerations, performance or compatibility trade-offs I might have missed.Additionally, I am uncertain if the
parseMultipart
in the library is intended to yield non-streamed (fully buffered) parts, or if that should be adjusted to keep consistency with the streaming API. I was unable to find any existing implementation clarifying this point.Breaking Changes
My changes introduce breaking API changes that could affect existing implementations. This discussion aims to gather feedback on whether this direction is acceptable and under what conditions.
Discussion Points
ReadableStream
per part approachI welcome all feedback, suggestions, and alternative ideas to refine this design and reach consensus.
Beta Was this translation helpful? Give feedback.
All reactions