mirror of
https://github.com/denoland/deno.git
synced 2025-09-21 18:10:02 +00:00

Ref https://github.com/denoland/deno/issues/28836 This PR replaces the _stream.mjs bundle with a file-by-file port instead. A codemod transpiles Node.js internals to ESM. The codemod performs three tasks: translating CJS to ESM, remapping internal dependencies, and hoisting lazy requires as imports. The process is fully automated through the `update_node_stream.ts` script, simplifying future internal updates. The script checks out Node.js from a specific tag defined in the `tests/node_compat/runner`. Additionally, the update enables new tests in our Node test runner and adds features (like compose()) that were missing from the outdated bundle. ## Performance There is a 140KB+ binary size increase on aarch64-apple-darwin and nop startup time stays the same.
67 lines
1.5 KiB
JavaScript
67 lines
1.5 KiB
JavaScript
// deno-lint-ignore-file
|
|
// Copyright 2018-2025 the Deno authors. MIT license.
|
|
|
|
import process from "node:process";
|
|
import { primordials } from "ext:core/mod.js";
|
|
import { Duplex } from "node:stream";
|
|
import assert from "ext:deno_node/internal/assert.mjs";
|
|
"use strict";
|
|
const {
|
|
Symbol,
|
|
} = primordials;
|
|
|
|
const kCallback = Symbol("Callback");
|
|
const kInitOtherSide = Symbol("InitOtherSide");
|
|
|
|
class DuplexSide extends Duplex {
|
|
#otherSide = null;
|
|
|
|
constructor(options) {
|
|
super(options);
|
|
this[kCallback] = null;
|
|
this.#otherSide = null;
|
|
}
|
|
|
|
[kInitOtherSide](otherSide) {
|
|
// Ensure this can only be set once, to enforce encapsulation.
|
|
if (this.#otherSide === null) {
|
|
this.#otherSide = otherSide;
|
|
} else {
|
|
assert(this.#otherSide === null);
|
|
}
|
|
}
|
|
|
|
_read() {
|
|
const callback = this[kCallback];
|
|
if (callback) {
|
|
this[kCallback] = null;
|
|
callback();
|
|
}
|
|
}
|
|
|
|
_write(chunk, encoding, callback) {
|
|
assert(this.#otherSide !== null);
|
|
assert(this.#otherSide[kCallback] === null);
|
|
if (chunk.length === 0) {
|
|
process.nextTick(callback);
|
|
} else {
|
|
this.#otherSide.push(chunk);
|
|
this.#otherSide[kCallback] = callback;
|
|
}
|
|
}
|
|
|
|
_final(callback) {
|
|
this.#otherSide.on("end", callback);
|
|
this.#otherSide.push(null);
|
|
}
|
|
}
|
|
|
|
function duplexPair(options) {
|
|
const side0 = new DuplexSide(options);
|
|
const side1 = new DuplexSide(options);
|
|
side0[kInitOtherSide](side1);
|
|
side1[kInitOtherSide](side0);
|
|
return [side0, side1];
|
|
}
|
|
export default duplexPair;
|
|
export { duplexPair };
|