Skip to content

Commit 1287d5b

Browse files
debadree25ruyadorno
authored andcommitted
lib: allow byob reader for 'blob.stream()'
Fixes: #47993 PR-URL: #49713 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 8bfbe70 commit 1287d5b

File tree

3 files changed

+52
-11
lines changed

3 files changed

+52
-11
lines changed

‎lib/internal/blob.js‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ class Blob{
321321

322322
constreader=this[kHandle].getReader();
323323
returnnewlazyReadableStream({
324+
type: 'bytes',
324325
start(c){
325326
// There really should only be one read at a time so using an
326327
// array here is purely defensive.
@@ -340,6 +341,9 @@ class Blob{
340341
if(status===0){
341342
// EOS
342343
c.close();
344+
// This is to signal the end for byob readers
345+
// see https://streams.spec.whatwg.org/#example-rbs-pull
346+
c.byobRequest?.respond(0);
343347
constpending=this.pendingPulls.shift();
344348
pending.resolve();
345349
return;
@@ -353,13 +357,15 @@ class Blob{
353357
pending.reject(error);
354358
return;
355359
}
356-
if(buffer!==undefined){
360+
// ReadableByteStreamController.enqueue errors if we submit a 0-length
361+
// buffer. We need to check for that here.
362+
if(buffer!==undefined&&buffer.byteLength!==0){
357363
c.enqueue(newUint8Array(buffer));
358364
}
359365
// We keep reading until we either reach EOS, some error, or we
360366
// hit the flow rate of the stream (c.desiredSize).
361367
queueMicrotask(()=>{
362-
if(c.desiredSize<=0){
368+
if(c.desiredSize<0){
363369
// A manual backpressure check.
364370
if(this.pendingPulls.length!==0){
365371
// A case of waiting pull finished (= not yet canceled)

‎test/parallel/test-blob.js‎

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,12 +331,54 @@ assert.throws(() => new Blob({}),{
331331
constb=newBlob(Array(10).fill('hello'));
332332
conststream=b.stream();
333333
constreader=stream.getReader();
334-
assert.strictEqual(stream[kState].controller.desiredSize,1);
334+
assert.strictEqual(stream[kState].controller.desiredSize,0);
335335
const{ value, done }=awaitreader.read();
336336
assert.strictEqual(value.byteLength,5);
337337
assert(!done);
338338
setTimeout(()=>{
339-
assert.strictEqual(stream[kState].controller.desiredSize,0);
339+
// The blob stream is now a byte stream hence after the first read,
340+
// it should pull in the next 'hello' which is 5 bytes hence -5.
341+
assert.strictEqual(stream[kState].controller.desiredSize,-5);
342+
},0);
343+
})().then(common.mustCall());
344+
345+
(async()=>{
346+
constblob=newBlob(['hello','world']);
347+
conststream=blob.stream();
348+
constreader=stream.getReader({mode: 'byob'});
349+
constdecoder=newTextDecoder();
350+
constchunks=[];
351+
while(true){
352+
const{ value, done }=awaitreader.read(newUint8Array(100));
353+
if(done)break;
354+
chunks.push(decoder.decode(value,{stream: true}));
355+
}
356+
assert.strictEqual(chunks.join(''),'helloworld');
357+
})().then(common.mustCall());
358+
359+
(async()=>{
360+
constb=newBlob(Array(10).fill('hello'));
361+
conststream=b.stream();
362+
constreader=stream.getReader({mode: 'byob'});
363+
assert.strictEqual(stream[kState].controller.desiredSize,0);
364+
const{ value, done }=awaitreader.read(newUint8Array(100));
365+
assert.strictEqual(value.byteLength,5);
366+
assert(!done);
367+
setTimeout(()=>{
368+
assert.strictEqual(stream[kState].controller.desiredSize,-5);
369+
},0);
370+
})().then(common.mustCall());
371+
372+
(async()=>{
373+
constb=newBlob(Array(10).fill('hello'));
374+
conststream=b.stream();
375+
constreader=stream.getReader({mode: 'byob'});
376+
assert.strictEqual(stream[kState].controller.desiredSize,0);
377+
const{ value, done }=awaitreader.read(newUint8Array(2));
378+
assert.strictEqual(value.byteLength,2);
379+
assert(!done);
380+
setTimeout(()=>{
381+
assert.strictEqual(stream[kState].controller.desiredSize,-3);
340382
},0);
341383
})().then(common.mustCall());
342384

‎test/wpt/status/FileAPI/blob.json‎

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,5 @@
4444
},
4545
"Blob-slice.any.js":{
4646
"skip": "Depends on File API"
47-
},
48-
"Blob-stream.any.js":{
49-
"fail":{
50-
"expected": [
51-
"Reading Blob.stream() with BYOB reader"
52-
]
53-
}
5447
}
5548
}

0 commit comments

Comments
(0)