node icon indicating copy to clipboard operation
node copied to clipboard

stream: do not pass `readable.compose()` output via `Readable.from()`

Open Renegade334 opened this issue 3 weeks ago β€’ 2 comments

readable.compose() was intended to return the Duplex constructed by stream.compose(), and is documented as such.

However, because it was added as a "stream-returning operator", its output is being passed via Readable.from(), which constructs a new object-mode Readable by wrapping the async iterator of the composed Duplex. This is inefficient in the best case, but causes breakage in a load of others:

  • if the destination stream is writable-only, then the composed stream would be a non-readable Duplex, but gets returned as a readable Readable.
  • if the source stream is a readable/writable Duplex, then the composed stream gets returned as a non-writable Readable, which misses the point of stream composition – the composed stream should be able to write to the head of the pipeline if it's writable, and read from the end if it's readable.
  • the returned stream is always in object mode, clobbering the object mode detection of stream.compose().

This change gets rid of the "operator" semantics for readable.compose(), and makes it a standalone method which returns the unaltered composed Duplex stream from stream.compose().

Fixes: #55203

Renegade334 avatar Nov 30 '25 18:11 Renegade334

Review requested:

  • [ ] @nodejs/streams

nodejs-github-bot avatar Nov 30 '25 18:11 nodejs-github-bot

Codecov Report

:white_check_mark: All modified and coverable lines are covered by tests. :white_check_mark: Project coverage is 88.52%. Comparing base (83ba6b1) to head (9cc1c88). :warning: Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #60907      +/-   ##
==========================================
+ Coverage   88.51%   88.52%   +0.01%     
==========================================
  Files         703      703              
  Lines      208432   208428       -4     
  Branches    40200    40200              
==========================================
+ Hits       184502   184520      +18     
+ Misses      15957    15909      -48     
- Partials     7973     7999      +26     
Files with missing lines Coverage Ξ”
lib/internal/streams/operators.js 96.14% <ΓΈ> (-0.30%) :arrow_down:
lib/internal/streams/readable.js 96.26% <100.00%> (+0.05%) :arrow_up:

... and 27 files with indirect coverage changes

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

codecov[bot] avatar Nov 30 '25 19:11 codecov[bot]

CI: https://ci.nodejs.org/job/node-test-pull-request/70482/

nodejs-github-bot avatar Dec 10 '25 18:12 nodejs-github-bot