mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-08 08:44:37 +08:00
Node's constructNT reads _construct on the construction tick, so an assignment after the constructor and before that tick replaces a scheduled construct hook. The assignment was dropped, so the original hook ran. It now lowers to stream.replaceConstruct, which swaps the hook while its tick has not run and has no effect after it or on a stream without a hook. Runtime decodeStrings and defaultEncoding values are read into locals before the constructor evaluates the other option members, while Node evaluates the members in order. A runtime value after a member whose value has effects (a call or an assignment) now refuses instead of reading a value that member could still change.
47 lines
1.1 KiB
JavaScript
47 lines
1.1 KiB
JavaScript
// Assigning _construct after construction: Node reads it on the
|
|
// construction tick, so an assignment before that tick replaces the
|
|
// scheduled hook, and one after it, or on a stream without a hook, has no
|
|
// effect.
|
|
import { Readable, Writable } from "node:stream";
|
|
|
|
const w = new Writable({
|
|
construct(cb) {
|
|
console.log("original construct");
|
|
cb();
|
|
},
|
|
write(chunk, _enc, cb) {
|
|
console.log("write", chunk.toString());
|
|
cb();
|
|
},
|
|
});
|
|
w._construct = function (cb) {
|
|
console.log("replacement construct");
|
|
cb();
|
|
};
|
|
w.write("a");
|
|
w.end();
|
|
w.on("finish", () => {
|
|
w._construct = function (cb) {
|
|
console.log("late construct");
|
|
cb();
|
|
};
|
|
console.log("finish");
|
|
readable();
|
|
});
|
|
|
|
// A stream without a construct hook: the assignment has no effect.
|
|
function readable() {
|
|
const r = new Readable({
|
|
read() {
|
|
this.push("x");
|
|
this.push(null);
|
|
},
|
|
});
|
|
r._construct = function (cb) {
|
|
console.log("never");
|
|
cb();
|
|
};
|
|
r.on("data", (d) => console.log("data", d.toString()));
|
|
r.on("end", () => console.log("end"));
|
|
}
|