@@ -200,7 +200,7 @@ export function processReply(
200200 return '$' + tag + blobId . toString ( 16 ) ;
201201 }
202202
203- function serializeReadableStream(stream: ReadableStream ): string {
203+ function serializeBinaryReader(reader: any ): string {
204204 if ( formData === null ) {
205205 // Upgrade to use FormData to allow us to stream this value.
206206 formData = new FormData ( ) ;
@@ -210,23 +210,43 @@ export function processReply(
210210 pendingParts++;
211211 const streamId = nextPartId++;
212212
213- // Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
214- // receiving side. It also implies that different chunks can be split up or merged as opposed
215- // to a readable stream that happens to have Uint8Array as the type which might expect it to be
216- // received in the same slices.
217- // $FlowFixMe: This is a Node.js extension.
218- let supportsBYOB: void | boolean = stream.supportsBYOB;
219- if (supportsBYOB === undefined) {
220- try {
221- // $FlowFixMe[extra-arg]: This argument is accepted.
222- stream . getReader ( { mode : 'byob' } ) . releaseLock ( ) ;
223- supportsBYOB = true ;
224- } catch (x) {
225- supportsBYOB = false ;
213+ const buffer = [];
214+
215+ function progress(entry: { done : boolean , value : ReactServerValue , ...} ) {
216+ if ( entry . done ) {
217+ const blobId = nextPartId ++ ;
218+ // eslint-disable-next-line react-internal/safe-string-coercion
219+ data . append ( formFieldPrefix + blobId , new Blob ( buffer ) ) ;
220+ // eslint-disable-next-line react-internal/safe-string-coercion
221+ data . append (
222+ formFieldPrefix + streamId ,
223+ '"$o' + blobId . toString ( 16 ) + '"' ,
224+ ) ;
225+ // eslint-disable-next-line react-internal/safe-string-coercion
226+ data . append ( formFieldPrefix + streamId , 'C' ) ; // Close signal
227+ pendingParts -- ;
228+ if ( pendingParts === 0 ) {
229+ resolve ( data ) ;
230+ }
231+ } else {
232+ buffer . push ( entry . value ) ;
233+ reader . read ( new Uint8Array ( 1024 ) ) . then ( progress , reject ) ;
226234 }
227235 }
236+ reader . read ( new Uint8Array ( 1024 ) ) . then ( progress , reject ) ;
228237
229- const reader = stream . getReader ( ) ;
238+ return '$r ' + streamId . toString ( 16 ) ;
239+ }
240+
241+ function serializeReader ( reader : ReadableStreamReader ) : string {
242+ if ( formData === null ) {
243+ // Upgrade to use FormData to allow us to stream this value.
244+ formData = new FormData ( ) ;
245+ }
246+ const data = formData;
247+
248+ pendingParts++;
249+ const streamId = nextPartId++;
230250
231251 function progress(entry: { done : boolean , value : ReactServerValue , ...} ) {
232252 if ( entry . done ) {
@@ -250,7 +270,20 @@ export function processReply(
250270 }
251271 reader . read ( ) . then ( progress , reject ) ;
252272
253- return '$ ' + ( supportsBYOB ? 'r ' : 'R ') + streamId . toString ( 16 ) ;
273+ return '$R ' + streamId . toString ( 16 ) ;
274+ }
275+
276+ function serializeReadableStream ( stream : ReadableStream ) : string {
277+ // Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
278+ // receiving side. For binary streams, we serialize them as plain Blobs.
279+ let binaryReader ;
280+ try {
281+ // $FlowFixMe[extra-arg]: This argument is accepted.
282+ binaryReader = stream . getReader ( { mode : 'byob' } ) ;
283+ } catch (x) {
284+ return serializeReader ( stream . getReader ( ) ) ;
285+ }
286+ return serializeBinaryReader(binaryReader);
254287 }
255288
256289 function serializeAsyncIterable (
0 commit comments