Skip to content

Commit a0ebfd2

Browse files
committed
fix(api/fetch): improve streaming
1 parent fbbbe85 commit a0ebfd2

2 files changed

Lines changed: 36 additions & 6 deletions

File tree

api/fetch/fetch.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ export function Request(input, options) {
393393
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
394394
throw new TypeError('Body not allowed for GET or HEAD requests')
395395
}
396-
this._initBody(body)
396+
this._initBody(body, options)
397397

398398
if (this.method === 'GET' || this.method === 'HEAD') {
399399
if (options.cache === 'no-store' || options.cache === 'no-cache') {
@@ -478,7 +478,7 @@ export function Response(bodyInit, options) {
478478
this.statusText = options.statusText === undefined ? '' : '' + options.statusText
479479
this.headers = new Headers(options.headers)
480480
this.url = options.url || ''
481-
this._initBody(bodyInit)
481+
this._initBody(bodyInit, options)
482482
}
483483

484484
Body.call(Response.prototype)
@@ -575,6 +575,10 @@ export function fetch(input, init) {
575575
}, 0)
576576
}
577577

578+
if (init?.onxhr) {
579+
init.onxhr(xhr)
580+
}
581+
578582
function fixUrl(url) {
579583
try {
580584
return url === '' && g.location.href ? g.location.href : url

api/fetch/index.js

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,24 +97,50 @@ async function initBody (body) {
9797
if (this._bodyArrayBuffer) {
9898
const arrayBuffer = this._bodyArrayBuffer
9999
this.body = new ReadableStream({
100-
start (controller) {
100+
async start (controller) {
101101
controller.enqueue(arrayBuffer)
102102
controller.close()
103103
}
104104
})
105105
} else if (this._bodyBlob) {
106106
const blob = this._bodyBlob
107107
this.body = new ReadableStream({
108+
type: 'bytes',
108109
async start (controller) {
109-
controller.enqueue(await blob.arrayBuffer())
110+
const stream = await blob.stream()
111+
if (controller.byobRequest) {
112+
const reader = stream.getReader({ mode: 'byob' })
113+
while (true) {
114+
const { done, value } = await reader.read(controller.byobRequest.view)
115+
if (done) {
116+
break
117+
}
118+
119+
if (value?.byteLength > 0) {
120+
controller.byobRequest.respond(value.byteLength)
121+
}
122+
}
123+
} else {
124+
const reader = stream.getReader()
125+
while (true) {
126+
const { done, value } = await reader.read()
127+
if (done) {
128+
break
129+
}
130+
131+
controller.enqueue(value)
132+
}
133+
}
134+
110135
controller.close()
111136
}
112137
})
113138
} else if (this._bodyText) {
114139
const text = this._bodyText
140+
const encoded = textEncoder.encode(text)
115141
this.body = new ReadableStream({
116-
start (controller) {
117-
controller.enqueue(textEncoder.encode(text))
142+
async start (controller) {
143+
controller.enqueue(encoded)
118144
controller.close()
119145
}
120146
})

0 commit comments

Comments
 (0)