- From: Domenic Denicola <notifications@github.com>
- Date: Wed, 26 May 2021 11:04:04 -0700
- To: whatwg/streams <streams@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/streams/issues/1128/849000992@github.com>
**Here is the start of a proposal for a seek-based API:** - Underlying sources/sinks can supply a promise-returning `seek` method. If supplied, then the stream's readers/writers support seeking; otherwise they don't. - We add `seek()` methods and `canSeek` getters to `ReadableStreamDefaultReader` / `ReadableStreamBYOBReader` / `WritableStreamDefaultWriter`. The `seek()` method forwards to the underlying source/sink after doing some basic argument validation (nonnegative, finite). - Seeks are queued up (i.e. not yet forwarded to the underlying source/sink) if there are any outstanding read requests or write requests. So e.g. even without `await`s, `writer.write(c1); writer.seek(10); writer.write(c2)` writes `c2` at position 10. - If you seek while a readable stream's queue is non-empty, the queue gets emptied; all the buffered-up chunks are lost since they're no longer relevant. In this model, the underlying source/sink is responsible for knowing what seek means, and how it interacts with reads/writes. The expectation is that they implement things so that reads/writes advance the current position, e.g. `writer.seek(10); writer.write(size5Chunk); writer.write(chunk)` writes `chunk` at position 15. But this is not enforced by the streams mechanisms. **Here is the start of a proposal for an offset-based API:** - Underlying sources/sinks can set `supportsRandomAccess: true`. - For such streams, `defaultReader.read({ at })`, `byobReader.read(view, { at })`, and `defaultWriter.write(chunk, { at })` work. (For streams without that boolean set, supplying any value for `at` rejects the promise.) They perform basic validation on `at`. - We add `reader.supportsAt` and `writer.supportsAt` booleans. - For writable streams, the underlying sink's `write()` method gets forwarded the `at` value from the `writer.write()` call, which it can use as it sees fit. The existing queuing mechanisms for writes ensure that the stream is never asked to write to two different locations concurrently. - If no `at` is supplied, we can either omit it from the call to the underlying sink, or we can auto-compute it based on the size of the chunks. Not sure which is best. - For readable streams, the situation is similar, except with the underlying source's `pull()` instead of the underlying sink's `write()`. The automatic calls to `pull()` which occur based on `highWaterMark` would take place at an auto-computed or omitted `at`, and would not be able to fulfill read requests with mismatching `at`s. The simplest thing to do here might be to empty the queue if a read request comes in with an `at` mismatching what was expected; otherwise the "queue" starts becoming a non-queue. On balance the offset-based API seems a bit cleaner. -- 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#issuecomment-849000992
Received on Wednesday, 26 May 2021 18:04:17 UTC