@@ -39,36 +39,38 @@ export async function fetch(resource, options = {}) {
3939
4040 let body = options . body || '' ;
4141
42- if ( body instanceof ArrayBuffer ) {
43- request . arrayBufferBody ( body ) ;
44- } else if ( body instanceof Uint8Array ) {
45- request . uint8ArrayBody ( body ) ;
46- } else if ( typeof body === 'string' || body instanceof String ) {
47- request . stringBody ( body ) ;
48- } else if ( body instanceof ReadableStream ) {
49- // TODO: currently the native implementation does not support streaming request body, so we just buffer the stream here
50- const reader = body . getReader ( ) ;
51- let chunks = [ ] ;
52- let done , value ;
53- while ( { done, value} = await reader . read ( ) , ! done ) {
54- chunks . push ( value ) ;
55- }
56- // Concatenate all chunks into a single Uint8Array
57- const totalLength = chunks . reduce ( ( acc , chunk ) => acc + chunk . length , 0 ) ;
58- const concatenated = new Uint8Array ( totalLength ) ;
59- let offset = 0 ;
60- for ( const chunk of chunks ) {
61- concatenated . set ( chunk , offset ) ;
62- offset += chunk . length ;
42+ if ( body instanceof ReadableStream ) {
43+ request . initSend ( ) ;
44+ const bodyWriter = request . initRequestBody ( ) ;
45+ request . sendRequest ( ) ;
46+
47+ async function sendBody ( bodyWriter , body ) {
48+ const reader = body . getReader ( ) ;
49+ while ( true ) {
50+ const { done, value } = await reader . read ( ) ;
51+ if ( done ) break ;
52+ await bodyWriter . writeRequestBodyChunk ( value ) ;
53+ }
54+ bodyWriter . finishBody ( ) ;
6355 }
64- request . uint8ArrayBody ( concatenated ) ;
65- } else {
66- console . warn ( 'Unsupported body type' ) ;
67- }
6856
69- let nativeResponse = await request . send ( ) ;
57+ const [ nativeResponse , _ ] = await Promise . all ( [ request . receiveResponse ( ) , sendBody ( bodyWriter , body ) ] ) ;
58+
59+ return new Response ( nativeResponse , resource ) ;
60+ } else {
61+ if ( body instanceof ArrayBuffer ) {
62+ request . arrayBufferBody ( body ) ;
63+ } else if ( body instanceof Uint8Array ) {
64+ request . uint8ArrayBody ( body ) ;
65+ } else if ( typeof body === 'string' || body instanceof String ) {
66+ request . stringBody ( body ) ;
67+ } else {
68+ console . warn ( 'Unsupported body type' ) ;
69+ }
7070
71- return new Response ( nativeResponse , resource ) ;
71+ const nativeResponse = await request . simpleSend ( ) ;
72+ return new Response ( nativeResponse , resource ) ;
73+ }
7274}
7375
7476export class Response {
@@ -87,9 +89,27 @@ export class Response {
8789 }
8890
8991 get body ( ) {
90- let streamSource = this . nativeResponse . stream ( ) ;
92+ let nativeStreamSource = this . nativeResponse . stream ( ) ;
9193 this . bodyUsed = true ;
92- return new ReadableStream ( streamSource ) ;
94+ return new ReadableStream ( {
95+ start ( ) {
96+ } ,
97+ get type ( ) {
98+ return "bytes" ;
99+ } ,
100+ async pull ( controller ) {
101+ // controller is https://developer.mozilla.org/en-US/docs/Web/API/ReadableByteStreamController
102+ const [ next , err ] = await nativeStreamSource . pull ( ) ;
103+ if ( err !== undefined ) {
104+ console . error ( "Error reading response body stream:" , err ) ;
105+ controller . error ( err ) ;
106+ } else if ( next === undefined ) {
107+ controller . close ( ) ;
108+ } else {
109+ controller . enqueue ( next ) ;
110+ }
111+ }
112+ } ) ;
93113 }
94114
95115 get headers ( ) {
0 commit comments