Repository navigation
Conversation
|
✅ Approved — This is a behaviour-preserving cleanup with no findings. The inner streams' controllers are recorded synchronously during construction, which makes the removed unset-checks unreachable, as the description says. The decision is advisory: this comment never approves, blocks or requests changes on the pull request. ✅ All checks passed🔒 Security: ✅ LGTMNo security concerns. 📖 AGENTS.md: ✅ LGTMNo AGENTS.md updates are needed. 📋 Code Quality: ✅ LGTMNo correctness problems were found in
⚡ Performance: ✅ LGTMNo performance concerns. 📝 Documentation: ✅ LGTMThe updated comments describe the current code. Reviewed commit: |
|
Since last review: 0 resolved, 0 still open, 1 new. The TransformStream cleanup remains sound; the completion-path comment still needs correction. Other findings
Carried forward from the last review: docs (no author changes in their files since then; earlier findings stand) Not re-run: api-compat, tests, compat-flags, design-simplicity (no author changes in their files since the last review) Reviewed commit: 7f02098d · github run |
DUP-42, as D-7 decides: unreachable code goes. A TransformStreamDefaultController was created and then attached to its stream in one synchronous step, before any user code could reach it, so the four "Controller is not attached to a stream" throws in its methods could never fire. The controller now takes its stream as a constructor argument, as ReadableStreamDefaultController does, and the init slot goes. Its length stays 0, which the module sets explicitly. The inner streams' start algorithms record their controllers while the TransformStream constructor builds the pair, before transformer.start(), the first user code that can reach it. The two fields are now typed as always set, and the nine checks for an unset one go, among them desiredSize's null arm and enqueue's "TransformStream is not fully initialized" throw. Nothing observable changes.
DUP-24. The sink's close and abort algorithms and the source's cancel algorithm were three copies of one skeleton: return the finish promise if a finish has started; otherwise set it, run flush or cancel, clear the algorithms, and settle the finish when that result settles, rejecting with the ended half's stored error if that half has errored by then. They differed only in the algorithm and in the half they end: the readable for the sink's close and abort, the writable for the source's cancel. #finish(kind, reason) now holds the skeleton once, and the inner sink and source call it. #closeReadable is the spec's ReadableStreamDefaultControllerClose, which returns at once when the readable cannot close. terminate() and the close finish each spelled it as a try/catch around the captured close(). It now checks CanCloseOrEnqueue, which internalsForTransform already exports, rather than catching whatever close() throws: nothing in close() can throw once that check passes. The finish promise is still set before the algorithm runs and the algorithms clear after it, with one reaction on its result, so nothing observable changes. Mutation probes against the three copies found each of their differences pinned, by the transform suite or by WPT's transform-streams.
eb5c02f to
7f02098
Compare
A TransformStreamDefaultController was created and then attached to
its stream in one synchronous step, before any user code could reach
it, so the four "Controller is not attached to a stream" throws in
its methods could never fire. The controller now takes its stream as
a constructor argument, as ReadableStreamDefaultController does, and
the init slot goes. Its length stays 0, which the module sets
explicitly.
The inner streams' start algorithms record their controllers while
the TransformStream constructor builds the pair, before
transformer.start(), the first user code that can reach it. The two
fields are now typed as always set, and the nine checks for an unset
one go, among them desiredSize's null arm and enqueue's
"TransformStream is not fully initialized" throw.
Nothing observable changes.