[whatwg/streams] Specification unclear on type of byobRequest.view (Issue #1366)

cinderflash created an issue (whatwg/streams#1366)

### What is the issue with the Streams Standard?

To implement a readable byte stream, an underlying source fulfills BYOB requests. The request provides a `.view` property as a space to write data into. The specification in various places indicates this is an `ArrayBufferView` or `TypedArray` or `Uint8Array`. Is it possible to get some clarification on this?

FWIW my preference would be that it's always `Uint8Array`. That would make it simpler and easier to implement byte streams. I think it's rare for a source of binary data to provide something other than octets, so in virtually all cases you'll be converting to `Uint8Array` internally if you receive anything else.

Details of what I'm seeing in the spec.

The [Web IDL definition](https://streams.spec.whatwg.org/#rs-byob-request-class-definition) of `ReadableStreamBYOBRequest` says `.view` is an `ArrayBufferView`. [This means](https://webidl.spec.whatwg.org/#ArrayBufferView) `TypedArray` or `DataView`.

```
readonly attribute ArrayBufferView? view;
```

The `.view` property [exposes the internal slot](https://streams.spec.whatwg.org/#rs-byob-request-prototype) `[[view]]`.

```
The `view` getter steps are:
  1. Return this.[[view]].
```

The [description of `[[view]]`](https://streams.spec.whatwg.org/#rs-byob-request-internal-slots) says it contains a `TypedArray` (but never a `DataView`).

>A typed array representing the destination region to which the controller can write generated data, or null after the BYOB request has been invalidated.

The only place `[[view]]` is set is in `ReadableByteStreamControllerGetBYOBRequest` (no direct link available). This logic sets it to a value that is always a `Uint8Array` (never a `DataView` or any other type of `TypedArray`).

> 2. Let view be ! Construct(%Uint8Array%, « firstDescriptor’s buffer, firstDescriptor’s byte offset + firstDescriptor’s bytes filled, firstDescriptor’s byte length − firstDescriptor’s bytes filled »).
> ..
> 5. Set byobRequest.[[view]] to view.

This is all about the internal view provided to the underlying source. There is another view constructed and provided in response to a `byobReader.read(view)` call. This output view can be any `ArrayBufferView`. Maybe these internal and external views just got muddled up a little while writing the spec.

The algorithm `ReadableByteStreamControllerPullInto` takes the view passed to `.read()` and stores its constructor into a pull-into descriptor.

> Set ctor to the constructor specified in the typed array constructors table for view.[[TypedArrayName]].

> Let pullIntoDescriptor be a new pull-into descriptor with
> * view constructor  ctor

After a BYOB request is fulfilled, `ReadableByteStreamControllerConvertPullIntoDescriptor` constructs the output view using the stored constructor. This makes the output view the same type as the view the user provided to `.read()`.

> Return ! Construct(pullIntoDescriptor’s view constructor, « buffer, pullIntoDescriptor’s byte offset, bytesFilled ÷ elementSize »).

The description of "view constructor" says it's [used to construct the internal view](https://streams.spec.whatwg.org/#rbs-controller-internal-slots), which seems to be wrong. The internal view is always `Uint8Array` and the stored "view constructor" is used to construct the output view.

> view constructor
>   A typed array constructor or %DataView%, which will be used for constructing a view with which to write into the buffer

-- 
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/streams/issues/1366
You are receiving this because you are subscribed to this thread.

Message ID: <whatwg/streams/issues/1366@github.com>

Received on Sunday, 12 April 2026 01:21:44 UTC