Repository navigation
Conversation
A ReadableStreamDrainingReader read that takes the last queued chunk but stops before the close sentinel reports done: false and leaves the stream readable, its desiredSize at the high-water mark and its closed promise pending, until the next read reaches the close. A default read closes the stream as it takes the last chunk. Pin it ahead of reporting the close with the chunks. The drain stops there for its maxSize, which only the internal-testing global can pass, or where the chunk sizes add up to Infinity, the one stop a read without a maxSize can meet: the C++ bridge's pump and body consumption read that way. Pin both on a value stream, and the maxSize case on a byte stream, whose controller has its own close check. The reader exists only under the TypeScript implementation; the C++ cells assert its absence, as the rest of these files do.
A ReadableStreamDrainingReader read whose size limit ran out at the last chunk before the close sentinel stopped short of the sentinel and reported done: false. The stream stayed readable, its closed promise pending, until a second read found the close. A controller.error() in between errored it, and the second read rejected, although every chunk had been read. A default read closes the stream as it takes the last chunk (spec PullSteps), and the error is then a no-op. The sentinel has no size, so the limit has no bearing on it. QueueCursor.drain now reports done whenever it ends at the sentinel, as the byte cursor's drain does through it, and the read closes the stream in the same call, as a default read does. The limit runs out at the read's maxSize, which only the internal-testing global passes, or, for a read without one, where the chunk sizes add up to Infinity. The C++ bridge's pump and body consumption read without one, so in production only streams whose chunk sizes add up to Infinity change: they finish in one read instead of two. Flip drainingReaderMaxSizeEndsAtClose, drainingReaderSizeOverflowEndsAtClose and drainingReaderByteMaxSizeEndsAtClose. typescript_implemented_streams is experimental, so this needs no compatibility flag.
A default read that waits takes its completion steps, the controller's drain-then-close check and then closing the stream if the read is done, through readCompletionSteps. Answered from the queue (readBufferedSync, which the pipe's synchronous read shares), it repeated them inline, and the draining read repeated them too, making the check only when done. Both now pull as before and then call readCompletionSteps, which takes the done flag in place of the result. The default read and the draining read's wait-read each looked up autoAllocateChunkSize behind their own queued-byte brand check and cast. getByteControllerAutoAllocateChunkSize now takes any controller and makes the check itself, answering undefined for all but the queued byte controller. No behavior change. The draining read now makes the check on every completion. Since the previous commit it reports done whenever its cursor ends at the close sentinel, so after any other completion the check finds nothing to close: a stream whose cursor is at the sentinel closed when the cursor got there, or at close(). The steps keep their order, and the brand check is the same private-field test.
Contributor
|
LGTM! Reviewed commit: bc0ab46f · github run |
jasnell
added this pull request to stack #7753
October 15, 2026 03:58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A ReadableStreamDrainingReader read that takes the last queued
chunk but stops before the close sentinel reports done: false and
leaves the stream readable, its desiredSize at the high-water mark
and its closed promise pending, until the next read reaches the
close. A default read closes the stream as it takes the last chunk.
Pin it ahead of reporting the close with the chunks.
The drain stops there for its maxSize, which only the
internal-testing global can pass, or where the chunk sizes add up
to Infinity, the one stop a read without a maxSize can meet: the
C++ bridge's pump and body consumption read that way. Pin both on a
value stream, and the maxSize case on a byte stream, whose
controller has its own close check. The reader exists only under
the TypeScript implementation; the C++ cells assert its absence, as
the rest of these files do.