@@ -39,36 +39,38 @@ export async function fetch(resource, options = {}) {
39
39
40
40
let body = options . body || '' ;
41
41
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 ( ) ;
63
55
}
64
- request . uint8ArrayBody ( concatenated ) ;
65
- } else {
66
- console . warn ( 'Unsupported body type' ) ;
67
- }
68
56
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
+ }
70
70
71
- return new Response ( nativeResponse , resource ) ;
71
+ const nativeResponse = await request . simpleSend ( ) ;
72
+ return new Response ( nativeResponse , resource ) ;
73
+ }
72
74
}
73
75
74
76
export class Response {
@@ -87,9 +89,27 @@ export class Response {
87
89
}
88
90
89
91
get body ( ) {
90
- let streamSource = this . nativeResponse . stream ( ) ;
92
+ let nativeStreamSource = this . nativeResponse . stream ( ) ;
91
93
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
+ } ) ;
93
113
}
94
114
95
115
get headers ( ) {
0 commit comments