@@ -208,7 +208,7 @@ export function processReply(
208208 return '$' + tag + blobId . toString ( 16 ) ;
209209 }
210210
211- function serializeReadableStream ( stream : ReadableStream ) : string {
211+ function serializeBinaryReader ( reader : any ) : string {
212212 if ( formData === null ) {
213213 // Upgrade to use FormData to allow us to stream this value.
214214 formData = new FormData ( ) ;
@@ -218,23 +218,43 @@ export function processReply(
218218 pendingParts++;
219219 const streamId = nextPartId++;
220220
221- // Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
222- // receiving side. It also implies that different chunks can be split up or merged as opposed
223- // to a readable stream that happens to have Uint8Array as the type which might expect it to be
224- // received in the same slices.
225- // $FlowFixMe: This is a Node.js extension.
226- let supportsBYOB: void | boolean = stream.supportsBYOB;
227- if (supportsBYOB === undefined) {
228- try {
229- // $FlowFixMe[extra-arg]: This argument is accepted.
230- stream . getReader ( { mode : 'byob' } ) . releaseLock ( ) ;
231- supportsBYOB = true ;
232- } catch (x) {
233- supportsBYOB = false ;
221+ const buffer = [];
222+
223+ function progress(entry: { done : boolean , value : ReactServerValue , ...} ) {
224+ if ( entry . done ) {
225+ const blobId = nextPartId ++ ;
226+ // eslint-disable-next-line react-internal/safe-string-coercion
227+ data . append ( formFieldPrefix + blobId , new Blob ( buffer ) ) ;
228+ // eslint-disable-next-line react-internal/safe-string-coercion
229+ data . append (
230+ formFieldPrefix + streamId ,
231+ '"$o' + blobId . toString ( 16 ) + '"' ,
232+ ) ;
233+ // eslint-disable-next-line react-internal/safe-string-coercion
234+ data . append ( formFieldPrefix + streamId , 'C' ) ; // Close signal
235+ pendingParts -- ;
236+ if ( pendingParts === 0 ) {
237+ resolve ( data ) ;
238+ }
239+ } else {
240+ buffer . push ( entry . value ) ;
241+ reader . read ( new Uint8Array ( 1024 ) ) . then ( progress , reject ) ;
234242 }
235243 }
244+ reader . read ( new Uint8Array ( 1024 ) ) . then ( progress , reject ) ;
236245
237- const reader = stream . getReader ( ) ;
246+ return '$r ' + streamId . toString ( 16 ) ;
247+ }
248+
249+ function serializeReader ( reader : ReadableStreamReader ) : string {
250+ if ( formData === null ) {
251+ // Upgrade to use FormData to allow us to stream this value.
252+ formData = new FormData ( ) ;
253+ }
254+ const data = formData;
255+
256+ pendingParts++;
257+ const streamId = nextPartId++;
238258
239259 function progress(entry: { done : boolean , value : ReactServerValue , ...} ) {
240260 if ( entry . done ) {
@@ -258,7 +278,20 @@ export function processReply(
258278 }
259279 reader . read ( ) . then ( progress , reject ) ;
260280
261- return '$ ' + ( supportsBYOB ? 'r ' : 'R ') + streamId . toString ( 16 ) ;
281+ return '$R ' + streamId . toString ( 16 ) ;
282+ }
283+
284+ function serializeReadableStream ( stream : ReadableStream ) : string {
285+ // Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
286+ // receiving side. For binary streams, we serialize them as plain Blobs.
287+ let binaryReader ;
288+ try {
289+ // $FlowFixMe[extra-arg]: This argument is accepted.
290+ binaryReader = stream . getReader ( { mode : 'byob' } ) ;
291+ } catch (x) {
292+ return serializeReader ( stream . getReader ( ) ) ;
293+ }
294+ return serializeBinaryReader(binaryReader);
262295 }
263296
264297 function serializeAsyncIterable (
0 commit comments