@@ -208,7 +208,7 @@ export function processReply(
208
208
return '$' + tag + blobId . toString ( 16 ) ;
209
209
}
210
210
211
- function serializeReadableStream ( stream : ReadableStream ) : string {
211
+ function serializeBinaryReader ( reader : any ) : string {
212
212
if ( formData === null ) {
213
213
// Upgrade to use FormData to allow us to stream this value.
214
214
formData = new FormData ( ) ;
@@ -218,23 +218,43 @@ export function processReply(
218
218
pendingParts++;
219
219
const streamId = nextPartId++;
220
220
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 ) ;
234
242
}
235
243
}
244
+ reader . read ( new Uint8Array ( 1024 ) ) . then ( progress , reject ) ;
236
245
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++;
238
258
239
259
function progress(entry: { done : boolean , value : ReactServerValue , ...} ) {
240
260
if ( entry . done ) {
@@ -258,7 +278,20 @@ export function processReply(
258
278
}
259
279
reader . read ( ) . then ( progress , reject ) ;
260
280
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);
262
295
}
263
296
264
297
function serializeAsyncIterable (
0 commit comments