Skip to content

Commit

Permalink
lib: allow byob reader for 'blob.stream()'
Browse files Browse the repository at this point in the history
  • Loading branch information
debadree25 committed Sep 19, 2023
1 parent 18e00a5 commit 50ab557
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 10 deletions.
4 changes: 3 additions & 1 deletion lib/internal/blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ class Blob {

const reader = this[kHandle].getReader();
return new lazyReadableStream({
type: 'bytes',
start(c) {
// There really should only be one read at a time so using an
// array here is purely defensive.
Expand All @@ -339,6 +340,7 @@ class Blob {
if (status === 0) {
// EOS
c.close();
c.byobRequest?.respond(0);
const pending = this.pendingPulls.shift();
pending.resolve();
return;
Expand All @@ -358,7 +360,7 @@ class Blob {
// We keep reading until we either reach EOS, some error, or we
// hit the flow rate of the stream (c.desiredSize).
queueMicrotask(() => {
if (c.desiredSize <= 0) {
if (c.desiredSize < 0) {
// A manual backpressure check.
if (this.pendingPulls.length !== 0) {
// A case of waiting pull finished (= not yet canceled)
Expand Down
46 changes: 44 additions & 2 deletions test/parallel/test-blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -331,12 +331,54 @@ assert.throws(() => new Blob({}), {
const b = new Blob(Array(10).fill('hello'));
const stream = b.stream();
const reader = stream.getReader();
assert.strictEqual(stream[kState].controller.desiredSize, 1);
assert.strictEqual(stream[kState].controller.desiredSize, 0);
const { value, done } = await reader.read();
assert.strictEqual(value.byteLength, 5);
assert(!done);
setTimeout(() => {
assert.strictEqual(stream[kState].controller.desiredSize, 0);
// the blob stream is now a byte stream hence after the first read,
// it should pull in the next 'hello' which is 5 bytes hence -5.
assert.strictEqual(stream[kState].controller.desiredSize, -5);
}, 0);
})().then(common.mustCall());

(async () => {
const blob = new Blob(['hello', 'world']);
const stream = blob.stream();
const reader = stream.getReader({ mode: 'byob' });
const decoder = new TextDecoder();
const chunks = [];
while (true) {
const { value, done } = await reader.read(new Uint8Array(100));
if (done) break;
chunks.push(decoder.decode(value, { stream: true }));
}
assert.strictEqual(chunks.join(''), 'helloworld');
})().then(common.mustCall());

(async () => {
const b = new Blob(Array(10).fill('hello'));
const stream = b.stream();
const reader = stream.getReader({ mode: 'byob' });
assert.strictEqual(stream[kState].controller.desiredSize, 0);
const { value, done } = await reader.read(new Uint8Array(100));
assert.strictEqual(value.byteLength, 5);
assert(!done);
setTimeout(() => {
assert.strictEqual(stream[kState].controller.desiredSize, -5);
}, 0);
})().then(common.mustCall());

(async () => {
const b = new Blob(Array(10).fill('hello'));
const stream = b.stream();
const reader = stream.getReader({ mode: 'byob' });
assert.strictEqual(stream[kState].controller.desiredSize, 0);
const { value, done } = await reader.read(new Uint8Array(2));
assert.strictEqual(value.byteLength, 2);
assert(!done);
setTimeout(() => {
assert.strictEqual(stream[kState].controller.desiredSize, -3);
}, 0);
})().then(common.mustCall());

Expand Down
7 changes: 0 additions & 7 deletions test/wpt/status/FileAPI/blob.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,5 @@
},
"Blob-slice.any.js": {
"skip": "Depends on File API"
},
"Blob-stream.any.js": {
"fail": {
"expected": [
"Reading Blob.stream() with BYOB reader"
]
}
}
}

0 comments on commit 50ab557

Please sign in to comment.