we (web engine): Experimental web browser project to understand the limits of Claude
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Implement Streams API foundation: ReadableStream, WritableStream, TransformStream #182

open opened by pierrelf.com

Goal#

Implement the WHATWG Streams API foundation: ReadableStream, WritableStream, and TransformStream as JS-exposed classes in we-js, with their default controllers, default readers and writers, and the queuing strategies and state machines required by later issues.

Scope#

  • ReadableStream
    • Constructor: new ReadableStream(underlyingSource?, strategy?)
    • underlyingSource callbacks: start, pull, cancel, type (undefined → default, 'bytes' deferred to the next issue)
    • ReadableStreamDefaultController: enqueue(chunk), close(), error(e), desiredSize
    • ReadableStreamDefaultReader: getReader(), read()Promise<{ value, done }>, releaseLock(), closed, cancel(reason)
    • State: readable / closed / errored
    • locked getter
    • Async iterator (@@asyncIterator) on ReadableStream so for await (const chunk of stream) works
  • WritableStream
    • Constructor: new WritableStream(underlyingSink?, strategy?)
    • underlyingSink callbacks: start, write, close, abort, type (reserved)
    • WritableStreamDefaultController: error(e), signal
    • WritableStreamDefaultWriter: getWriter(), write(chunk), close(), abort(reason), releaseLock(), desiredSize, ready, closed
    • State: writable / closing / closed / erroring / errored
  • TransformStream
    • Constructor: new TransformStream(transformer?, writableStrategy?, readableStrategy?)
    • transformer callbacks: start, transform, flush
    • TransformStreamDefaultController: enqueue, terminate, error, desiredSize
    • Exposes a paired readable and writable
  • Queuing strategies
    • CountQueuingStrategy({ highWaterMark }) with .size = () => 1
    • ByteLengthQueuingStrategy({ highWaterMark }) with .size = (chunk) => chunk.byteLength
  • Internal queue with desiredSize = highWaterMark - currentSize semantics
  • Microtask scheduling: pulls and writes run via the existing microtask queue from Phase 10

Acceptance Criteria#

  • new ReadableStream(...).getReader().read() returns a thenable that resolves to { value, done } matching the WHATWG semantics
  • Backpressure: controller.desiredSize decreases as chunks are enqueued, and pull() is invoked when desiredSize > 0 and the queue is below the high water mark
  • Errored streams reject pending reads/writes and subsequent read()/write() calls
  • writable.getWriter().write(chunk) returns a promise that resolves when the underlying sink accepts the chunk (respecting backpressure via ready)
  • TransformStream paired streams chain backpressure correctly (writable ready depends on readable buffer level)
  • Async iteration over a ReadableStream yields enqueued chunks and terminates on close
  • Unit tests covering: default reader read/close/error/cancel, default writer write/close/abort, queueing strategies, transform stream identity, error propagation, locking, async iteration
  • Conventions
    • cargo fmt --all --check
    • cargo clippy --workspace -- -D warnings
    • cargo test --workspace
    • No external crate dependencies; unsafe only inside js if strictly needed for GC integration
sign up or login to add to the discussion
Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:meotu43t6usg4qdwzenk4s2t/sh.tangled.repo.issue/3mly7os54gc2k