A pipeline stage that arrives as an untyped value now follows Node's
stage ladder for more shapes. As the first stage, a function is a source
function: the pipeline calls it with { signal } while it is set up and
pumps its result, which must be iterable (ERR_INVALID_RETURN_VALUE
otherwise), and a { readable, writable } pair pumps its readable side.
After the first stage, the pipeline call is lowered once per combination
of its first three untyped stages being functions or not, and a typeof
test picks the branch at run time. A function stage is called with the
previous stage and { signal }; before the last stage its result must be
async iterable, and as the last stage a promise resolves the pipeline's
value and an async iterable feeds the PassThrough pipeline() returns
(SCR_PIPE_DEST_DYN). Any other value that is not a stream becomes
Duplex.from of it, which the next stage reads from without the previous
stage being piped into it, and Duplex.from's ERR_INVALID_ARG_TYPE for
the values it rejects.
An untyped stage followed by an untyped function stage hands its value to
that stage through a cell created per pipeline call, so the function
receives the previous stage's own iterator, as Node's makeAsyncIterable
answers it, instead of an async generator over it.
Untyped web streams, pairs after the first stage, and function stages
that return a stream throw the not-supported error.
RUNTIME_ABI_VERSION goes from 45 to 46 for the new stream exports.
Records inherit toString, toLocaleString, valueOf, hasOwnProperty,
isPrototypeOf and propertyIsEnumerable. Calls of these methods by name
run an own callable entry when the record's type allows one and the
record holds it, and otherwise the built-in with the record as receiver;
toLocaleString, valueOf and isPrototypeOf on records were refused, and
toString ignored an own entry. Keyed reads of records of functions answer
the built-in as a native function value when the key misses: bound to the
record when called at once, with an undefined `this` otherwise. The
backend fuses the read with its fallback, so hits cost nothing extra.
Records of other value types keep reading undefined for these names; the
limitations page says so.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Preflight admits a createRequire loader's require.resolve call with a
computed request inside a try block, but lowering refused the call, so
in JavaScript source the whole statement became a runtime fence. The
fence threw before the request expression ran, and before anything else
in the statement: `try { where = load.resolve(candidate(name)); }`
skipped candidate()'s side effects, so the catch clause saw a different
state than in Node.
Such calls (a computed request, another argument shape, or
runtime-computed options, on require.resolve and require.resolve.paths)
now evaluate their arguments in order and then throw the fence, as a
computed require call does. The addon-probe fixture checks that a
computed candidate path runs before each failed lookup.
A pipeline whose first stage is a checked-dynamic value now checks it at
run time, as Node's stage ladder does: a stream is piped as before, and a
string or a value with a Symbol.asyncIterator or Symbol.iterator method is
pumped into the next stage through an async generator over its iterator.
A typed Set, Map, generator or async generator object as the first stage
takes the same path. This covers the callback and stream/promises forms,
with or without function stages and pipeline options.
A write whose callback fails synchronously no longer sets needDrain, so no
'drain' follows the error and a pumped source stops at the failed write,
as in Node.
RUNTIME_ABI_VERSION goes from 37 to 42 for scr_stream_dyn_iterable_source.
tls.connect, https.request and http2.connect verified the server against
the default CAs when ca was an empty Buffer, because the runtime read a
zero-length ca as none. The compiled calls now pass a null ca for none
(an omitted ca, or an empty string, which Node reads as no ca) and a
non-null one for any Buffer, and runtime option records read ca the same
way, so an empty Buffer or array trusts no certificate, as in Node. The
connection pool keys tell an empty ca from none. An empty array, which
threw, is an empty trust store too. A runtime-valued empty string ca in
http2.connect is refused instead of being read as an empty store.