| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -321,6 +321,7 @@ class Blob { | |||
| 321 | 321 | ||
| 322 | 322 | const reader = this[kHandle].getReader(); | |
| 323 | 323 | return new lazyReadableStream({ | |
| 324 | + type: 'bytes', | ||
| 324 | 325 | start(c) { | |
| 325 | 326 | // There really should only be one read at a time so using an | |
| 326 | 327 | // array here is purely defensive. | |
@@ -340,6 +341,9 @@ class Blob { | |||
| 340 | 341 | if (status === 0) { | |
| 341 | 342 | // EOS | |
| 342 | 343 | 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); | ||
| 343 | 347 | const pending = this.pendingPulls.shift(); | |
| 344 | 348 | pending.resolve(); | |
| 345 | 349 | return; | |
@@ -353,13 +357,15 @@ class Blob { | |||
| 353 | 357 | pending.reject(error); | |
| 354 | 358 | return; | |
| 355 | 359 | } | |
| 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) { | ||
| 357 | 363 | c.enqueue(new Uint8Array(buffer)); | |
| 358 | 364 | } | |
| 359 | 365 | // We keep reading until we either reach EOS, some error, or we | |
| 360 | 366 | // hit the flow rate of the stream (c.desiredSize). | |
| 361 | 367 | queueMicrotask(() => { | |
| 362 | - if (c.desiredSize <= 0) { | ||
| 368 | + if (c.desiredSize < 0) { | ||
| 363 | 369 | // A manual backpressure check. | |
| 364 | 370 | if (this.pendingPulls.length !== 0) { | |
| 365 | 371 | // A case of waiting pull finished (= not yet canceled) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -331,12 +331,54 @@ assert.throws(() => new Blob({}), { | |||
| 331 | 331 | const b = new Blob(Array(10).fill('hello')); | |
| 332 | 332 | const stream = b.stream(); | |
| 333 | 333 | const reader = stream.getReader(); | |
| 334 | - assert.strictEqual(stream[kState].controller.desiredSize, 1); | ||
| 334 | + assert.strictEqual(stream[kState].controller.desiredSize, 0); | ||
| 335 | 335 | const { value, done } = await reader.read(); | |
| 336 | 336 | assert.strictEqual(value.byteLength, 5); | |
| 337 | 337 | assert(!done); | |
| 338 | 338 | 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 | + const blob = new Blob(['hello', 'world']); | ||
| 347 | + const stream = blob.stream(); | ||
| 348 | + const reader = stream.getReader({ mode: 'byob' }); | ||
| 349 | + const decoder = new TextDecoder(); | ||
| 350 | + const chunks = []; | ||
| 351 | + while (true) { | ||
| 352 | + const { value, done } = await reader.read(new Uint8Array(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 | + const b = new Blob(Array(10).fill('hello')); | ||
| 361 | + const stream = b.stream(); | ||
| 362 | + const reader = stream.getReader({ mode: 'byob' }); | ||
| 363 | + assert.strictEqual(stream[kState].controller.desiredSize, 0); | ||
| 364 | + const { value, done } = await reader.read(new Uint8Array(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 | + const b = new Blob(Array(10).fill('hello')); | ||
| 374 | + const stream = b.stream(); | ||
| 375 | + const reader = stream.getReader({ mode: 'byob' }); | ||
| 376 | + assert.strictEqual(stream[kState].controller.desiredSize, 0); | ||
| 377 | + const { value, done } = await reader.read(new Uint8Array(2)); | ||
| 378 | + assert.strictEqual(value.byteLength, 2); | ||
| 379 | + assert(!done); | ||
| 380 | + setTimeout(() => { | ||
| 381 | + assert.strictEqual(stream[kState].controller.desiredSize, -3); | ||
| 340 | 382 | }, 0); | |
| 341 | 383 | })().then(common.mustCall()); | |
| 342 | 384 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -44,12 +44,5 @@ | |||
| 44 | 44 | }, | |
| 45 | 45 | "Blob-slice.any.js": { | |
| 46 | 46 | "skip": "Depends on File API" | |
| 47 | - }, | ||
| 48 | - "Blob-stream.any.js": { | ||
| 49 | - "fail": { | ||
| 50 | - "expected": [ | ||
| 51 | - "Reading Blob.stream() with BYOB reader" | ||
| 52 | - ] | ||
| 53 | - } | ||
| 54 | 47 | } | |
| 55 | 48 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments