Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
9cf2ce7
deps: update perfetto to 57.2
nodejs-github-bot Aug 14, 2026
38e3955
deps: cherry-pick libuv/libuv@e640dc9
Aug 14, 2026
553aec1
doc: document open pull request limit
mcollina Aug 14, 2026
bc813a7
stream: preserve falsy cancellation reasons
trivikr Aug 14, 2026
c4b755e
sqlite: reject connection access from authorizer callbacks
TrevorBurnham Aug 14, 2026
c8996ea
sqlite: add stmt persistent flag
araujogui Aug 14, 2026
4551732
stream: speed up async iteration of Readable
mcollina Aug 14, 2026
3e4d2e4
benchmark: apply `highWaterMark` in webstreams `pipe-to`
mcollina Aug 8, 2026
ec1a8df
stream: cut promise churn in webstreams hot paths
mcollina Aug 8, 2026
2929417
stream: consolidate non-op algorithm callbacks
mcollina Aug 8, 2026
91aaf05
doc: fix SQLite changeset constant descriptions
greenheadHQ Aug 15, 2026
c55fa12
test: wait for FFI background optimization
trivikr Aug 15, 2026
9ad097b
quic: fix wake up blob
martenrichter Aug 15, 2026
c2b2e3f
test: use for-of instead of forEach
devfep Aug 15, 2026
c7b962c
sqlite: add diagnostic channel
araujogui Aug 15, 2026
5615b25
test: accomodate multi-global tests in WPT{Runner,TestSpec,Report}
panva Aug 1, 2026
c757550
test: add opt-in process WPT runner
panva Aug 4, 2026
b9afdd0
worker: add support for Web Workers
avivkeller Aug 1, 2026
78cca36
test: enable multi-global WPTs
panva Aug 4, 2026
c73d0b1
worker: add wpt tests for Web Workers
avivkeller Aug 1, 2026
30bff4a
test: convert forEach to for in test-constant.js file
Nixxy25 Aug 13, 2026
8606604
cli: add No-Op `--experimental-repl-await`
avivkeller Aug 4, 2026
86c871e
test: replace `forEach()` with `for...of` in parallel tests
pmarkert Aug 15, 2026
d099639
test: convert test-async-local-storage-bind to async loop
freida-code Aug 13, 2026
04a0c27
tools: update nixpkgs-unstable to 6b5e5b7a6631f065bf6908986990b37d845
nodejs-github-bot Aug 16, 2026
46cac5a
doc: add missing `added:` tags to `fs.lchmod`
lazerg Aug 16, 2026
ad7a5b8
build: update binary-upload to use correct tarball name
sxa Aug 16, 2026
9129555
doc: fix typo in onboarding.md
minirang Aug 17, 2026
6054ff3
doc: fix lint clean command
greenheadHQ Aug 17, 2026
26398a9
stream: use validateNumber for BYOB reader options.min
greenheadHQ Aug 17, 2026
1dacb39
stream: use validateObject for zlib/iter params
greenheadHQ Aug 17, 2026
3abf65f
sqlite: validate StatementSync.run() integers
trivikr Aug 17, 2026
977c20e
stream: avoid leaking consumers on signal failure
trivikr Aug 17, 2026
11176fd
typings: add watchdog internal binding types
leah-1ee Aug 17, 2026
671ff97
typings: add diagnostics_channel typings
leah-1ee Aug 17, 2026
2004fbd
debugger: wait for target startup
panva Aug 10, 2026
0795d82
typings: add signal_wrap internal binding types
leah-1ee Aug 17, 2026
cc60845
util: use more primordials in `comparisons.js`
Ayoub-Mabrouk Aug 17, 2026
3781ebc
test: enforce exit code in `test-http-server-stale-close`
aduh95 Aug 17, 2026
8f6c69f
ffi: keep FFI functions non-constructible
trivikr Aug 17, 2026
d95dba2
ffi: remove dead null check in callback arguments
trivikr Aug 4, 2026
89310c7
repl: add benchmarks
avivkeller Jul 19, 2026
6456418
src: add v8::Local specialization for MaybeStackBuffer
jasnell Aug 9, 2026
45d6d31
http: fix keylog listener setup on existing agent sockets
shani-singh1 Aug 17, 2026
8488e13
fs: fix close listener leak in FileHandle streams
Y1D7NG Aug 17, 2026
8b9f89f
build: pass target architecture to small-icu genccode
ulofiai Aug 17, 2026
92ee8b7
test: avoid timer race in event loop delay test
trivikr Jul 25, 2026
13fcd6f
deps: update googletest to 49495eacfdbda3f4b6ba219923fedbb2e3f99376
nodejs-github-bot Aug 18, 2026
47af16c
url: speed up WHATWG URL parsing
anonrig Aug 18, 2026
a023478
url: skip unused href reuse comparison
anonrig Aug 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ See [details on our policy on Code of Conduct](./doc/contributing/code-of-conduc

Pull Requests are the way concrete changes are made to the code, documentation,
dependencies, and tools contained in the `nodejs/node` repository.
Contributors who are not Collaborators may have no more than 10 pull requests
open at a time.

* [Dependencies](./doc/contributing/pull-requests.md#dependencies)
* [Setting up your local environment](./doc/contributing/pull-requests.md#setting-up-your-local-environment)
Expand Down
16 changes: 8 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1449,15 +1449,15 @@ binary: $(BINARYTAR) ## Build release binary tarballs.
# Note: this is strictly for release builds on release machines only.
binary-upload: binary
ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)"
chmod 664 $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz
scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz
ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz"
ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz.done"
chmod 664 $(BINARYNAME).tar.gz
scp -p $(BINARYNAME).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.gz
ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.gz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.gz"
ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.gz.done"
ifeq ($(XZ), 1)
chmod 664 $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz
scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz
ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz"
ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz.done"
chmod 664 $(BINARYNAME).tar.xz
scp -p $(BINARYNAME).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.xz
ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.xz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.xz"
ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.xz.done"
endif

.PHONY: bench-all
Expand Down
1 change: 1 addition & 0 deletions benchmark/misc/startup-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ function main({ n, script, mode }) {
const warmup = 3;
const state = { n, finished: -warmup };
if (mode === 'worker') {
// eslint-disable-next-line no-global-assign
Worker = require('worker_threads').Worker;
spawnWorker(script, bench, state);
} else {
Expand Down
53 changes: 53 additions & 0 deletions benchmark/repl/completion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
'use strict';

const common = require('../common.js');
const repl = require('node:repl');
const { PassThrough, Writable } = require('node:stream');

const bench = common.createBenchmark(main, {
n: [5e3],
query: [
'cons',
'console.lo',
'Buffer.prototype.wri',
"require('f",
],
useGlobal: [0, 1],
});

function main({ n, query, useGlobal }) {
const input = new PassThrough();
const output = new Writable({ write(c, e, cb) { cb(); } });
const server = new repl.REPLServer({
input,
output,
terminal: false,
useGlobal: !!useGlobal,
});

// Inspector callbacks do not keep the event loop alive on their own.
const keepAlive = setInterval(() => {}, 0x7fffffff);
let remaining = n;

function complete() {
server.complete(query, onComplete);
}

function onComplete(err) {
if (err) {
throw err;
}

if (--remaining === 0) {
bench.end(n);
clearInterval(keepAlive);
server.close();
return;
}

setImmediate(complete);
}

bench.start();
setImmediate(complete);
}
39 changes: 39 additions & 0 deletions benchmark/repl/creation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict';

const common = require('../common.js');
const repl = require('node:repl');
const { PassThrough, Writable } = require('node:stream');

const bench = common.createBenchmark(main, {
n: [500],
preview: [0, 1],
terminal: [0, 1],
useGlobal: [0, 1],
}, {
combinationFilter: ({ preview, terminal }) => !!terminal || !preview,
});

function main({ n, preview, terminal, useGlobal }) {
const inputs = Array.from({ length: n }, () => new PassThrough());
const outputs = Array.from(
{ length: n },
() => new Writable({ write(c, e, cb) { cb(); } }),
);
const servers = new Array(n);

bench.start();
for (let i = 0; i < n; i++) {
servers[i] = new repl.REPLServer({
input: inputs[i],
output: outputs[i],
preview: !!preview,
terminal: !!terminal,
useGlobal: !!useGlobal,
});
}
bench.end(n);

for (const server of servers) {
server.close();
}
}
57 changes: 57 additions & 0 deletions benchmark/repl/evaluate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use strict';

const common = require('../common.js');
const repl = require('node:repl');
const { PassThrough, Writable } = require('node:stream');

const bench = common.createBenchmark(main, {
n: [2e4],
code: [
'1 + 1',
'({ answer: 42 })',
'Promise.resolve(42)',
'await Promise.resolve(42)',
],
mode: ['sloppy', 'strict'],
useGlobal: [0, 1],
});

function main({ n, code, mode, useGlobal }) {
const input = new PassThrough();
const output = new Writable({ write(c, e, cb) { cb(); } });
const server = new repl.REPLServer({
input,
output,
replMode: mode === 'strict' ?
repl.REPL_MODE_STRICT :
repl.REPL_MODE_SLOPPY,
terminal: false,
useGlobal: !!useGlobal,
});

// Inspector callbacks do not keep the event loop alive on their own.
const keepAlive = setInterval(() => {}, 0x7fffffff);
let remaining = n;

function evaluate() {
server.eval(`${code}\n`, server.context, 'repl', onEvaluate);
}

function onEvaluate(err) {
if (err) {
throw err;
}

if (--remaining === 0) {
bench.end(n);
clearInterval(keepAlive);
server.close();
return;
}

setImmediate(evaluate);
}

bench.start();
setImmediate(evaluate);
}
52 changes: 52 additions & 0 deletions benchmark/repl/process-lines.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use strict';

const common = require('../common.js');
const repl = require('node:repl');
const { PassThrough, Writable } = require('node:stream');

const bench = common.createBenchmark(main, {
n: [1e4],
code: [
'1 + 1\n',
'Promise.resolve(42)\n',
],
mode: ['sloppy', 'strict'],
terminal: [0, 1],
useGlobal: [0, 1],
});

function main({ n, code: inputCode, mode, terminal, useGlobal }) {
const input = new PassThrough();
const output = new Writable({ write(c, e, cb) { cb(); } });
const server = new repl.REPLServer({
input,
output,
replMode: mode === 'strict' ?
repl.REPL_MODE_STRICT :
repl.REPL_MODE_SLOPPY,
terminal: !!terminal,
useGlobal: !!useGlobal,
});
const originalEval = server.eval;
// TTY input dispatch can briefly have no other active event loop handles.
const keepAlive = setInterval(() => {}, 0x7fffffff);
let remaining = n;

// eslint-disable-next-line node-core/func-name-matching
server.eval = function REPLEval(code, context, file, callback) {
originalEval(code, context, file, function onEvaluate() {
const result = Reflect.apply(callback, this, arguments);
if (--remaining === 0) {
bench.end(n);
clearInterval(keepAlive);
server.close();
} else {
setImmediate(() => input.write(inputCode));
}
return result;
});
};

bench.start();
input.write(inputCode);
}
26 changes: 26 additions & 0 deletions benchmark/repl/reset-context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

const common = require('../common.js');
const repl = require('node:repl');
const { PassThrough, Writable } = require('node:stream');

const bench = common.createBenchmark(main, {
n: [1e3],
});

function main({ n }) {
const input = new PassThrough();
const output = new Writable({ write(c, e, cb) { cb(); } });
const server = new repl.REPLServer({
input,
output,
terminal: false,
});

bench.start();
for (let i = 0; i < n; i++) {
server.resetContext();
}
bench.end(n);
server.close();
}
42 changes: 42 additions & 0 deletions benchmark/sqlite/sqlite-diagnostic-channel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use strict';
const common = require('../common.js');
const sqlite = require('node:sqlite');
const dc = require('node:diagnostics_channel');
const assert = require('node:assert');

const bench = common.createBenchmark(main, {
n: [1e5],
mode: ['none', 'subscribed', 'unsubscribed'],
});

function main(conf) {
const { n, mode } = conf;

const db = new sqlite.DatabaseSync(':memory:');
db.exec('CREATE TABLE t (x INTEGER)');
const insert = db.prepare('INSERT INTO t VALUES (?)');

let subscriber;
if (mode === 'subscribed') {
subscriber = () => {};
dc.subscribe('sqlite.db.query', subscriber);
} else if (mode === 'unsubscribed') {
subscriber = () => {};
dc.subscribe('sqlite.db.query', subscriber);
dc.unsubscribe('sqlite.db.query', subscriber);
}
// mode === 'none': no subscription ever made

let result;
bench.start();
for (let i = 0; i < n; i++) {
result = insert.run(i);
}
bench.end(n);

if (mode === 'subscribed') {
dc.unsubscribe('sqlite.db.query', subscriber);
}

assert.ok(result !== undefined);
}
10 changes: 4 additions & 6 deletions benchmark/webstreams/pipe-to.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,27 @@ const {

const bench = common.createBenchmark(main, {
n: [5e5],
highWaterMarkR: [512, 1024, 2048, 4096],
highWaterMarkW: [512, 1024, 2048, 4096],
highWaterMarkR: [1, 1024, 4096],
highWaterMarkW: [1, 1024, 4096],
});


async function main({ n, highWaterMarkR, highWaterMarkW }) {
const b = Buffer.alloc(1024);
let i = 0;
const rs = new ReadableStream({
highWaterMark: highWaterMarkR,
pull: function(controller) {
if (i++ < n) {
controller.enqueue(b);
} else {
controller.close();
}
},
});
}, { highWaterMark: highWaterMarkR });
const ws = new WritableStream({
highWaterMark: highWaterMarkW,
write(chunk, controller) {},
close() { bench.end(n); },
});
}, { highWaterMark: highWaterMarkW });

bench.start();
rs.pipeTo(ws);
Expand Down
11 changes: 4 additions & 7 deletions deps/googletest/include/gtest/gtest-printers.h
Original file line number Diff line number Diff line change
Expand Up @@ -1173,15 +1173,12 @@ class [[nodiscard]] UniversalTersePrinter<const wchar_t*> {
}
}
};
#endif

template <>
class [[nodiscard]] UniversalTersePrinter<wchar_t*> {
public:
static void Print(wchar_t* str, ::std::ostream* os) {
UniversalTersePrinter<const wchar_t*>::Print(str, os);
}
};
class [[nodiscard]] UniversalTersePrinter<wchar_t*>
: public UniversalTersePrinter<const wchar_t*> {};

#endif // GTEST_HAS_STD_WSTRING

template <typename T>
void UniversalTersePrint(const T& value, ::std::ostream* os) {
Expand Down
Loading