[whatwg/streams] Adding generic seek or read/write-at-offset abilities to readable/writable streams (#1128)

A lot of the streams ecosystem so far has focused on network and device streams, where data is definitely sequential and read in order. However, [File System Access](https://wicg.github.io/file-system-access/) and the [Storage Foundation API](https://github.com/WICG/storage-foundation-api-explainer) (which will hopefully soon become an extension of File System Access) operate on file system streams, which are slightly different. In particular, a common operation on file system streams is random access, i.e. reading/writing to a specified offset.

One could imagine using a separate API for random access, and leaving streams only for the kind of streaming sequential reads/writes that they're already good at. But this feels like a bad outcome. It would result in two similar APIs side-by-side, e.g. read/cancel on stream readers, and read/cancel/seek on random access readers.

Instead we could imagine augmenting stream readers/writers to support this use case. If the underlying source/sink advertises seeking or random access support, then the corresponding reader could expose that capability. Most streams on the web platform today would not support random access. (E.g., seeking a HTTP response doesn't make much sense. Except maybe seeking forward?) But file system streams, and maybe `blob.stream()`, could support it.

There are a few API details that come to mind:

* Is `reader.seek(offset)` the right API, or should it be something like `reader.read(view, { offset })` or `reader.readAt(offset, view)`? (That's the BYOB case; omit the `view` for the default reader case.) This seems like a big fork in the road that affects other parts of the API. E.g. if it's a seek-type API, then we need to consider how to queue up the seeks vs. the reads/writes/read requests.

* Should this be done via adding a `seek()` or `readAt()` method to `ReadableStreamDefaultReader` / `ReadableStreamBYOBReader` / `WritableStreamDefaultWriter`, which throws if the underlying sink doesn't support it? Or should we create dedicated "seekable reader/writer" classes or subclasses? The former is a good deal simpler on the spec and implementation side, and is perhaps a better precedent for any future such expansions. But then feature detection would need some kind of `canSeek` or `supportsOffset` getter, which is a bit annoying.

* What are the "units" for the seeking `offset`? They could be totally opaque: just a value you pass through to the underlying source/sink. (This starts feeling like some of the generic message-passing mechanisms discussed in #960 and #1026.) Or there could be some minimal validation, e.g. has to be a number (integer?), has to be nonnegative, has to be finite.

* Relatedly, should there be a convention for whether seeking past the end throws an exception vs. clamps to the end? I don't know if we can enforce this in the streams infrastructure, but if we could that'd be cool.

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

Received on Wednesday, 26 May 2021 17:44:32 UTC