Contexts that are not deserialized from the built-in snapshot -- worker
threads, and the main context of embedders that create their own
isolate or of `node --no-node-snapshot` -- compile (with the code cache
at best) every builtin the bootstrap touches, so each eagerly required
builtin is startup time (~0.15-0.4 ms apiece). A number of them are only
required eagerly so that they end up in the snapshot, or for features
the bootstrap path never uses.
Load lazily what those paths do not need:
- is_main_thread.js: preload util, url, the ESM loader (translators,
resolver, module_job/map, source maps, node:module, vm modules, mime,
data_url, the TypeScript stripper), internal/blob and
internal/dns/utils only while building a snapshot; they load on first
use otherwise.
- fs: internal/blob (+ internal/encoding and its tables) is only used
by fs.openAsBlob().
- internal/url: internal/data_url (+ internal/mime) is only used by the
Buffer-returning file URL helpers.
- internal/process/execution, the CommonJS loader, esm/translators and
esm/load: the TypeScript stripper and data: URL helpers are only
needed for TypeScript sources / data: URLs.
- pre_execution: internal/dns/utils (+ internal/net) is only needed up
front to validate an explicit --dns-result-order or to register the
resolver's snapshot serializer; the default order becomes the
variable's initializer.
- internal/worker: event_loop_utilization and error_serdes are only
needed once a sub-worker's ELU is read or it reports an error.
- worker_threads: `locks` is defined lazily, like util's lazy exports.
Main-thread startup with the snapshot is unchanged (the same modules
are preloaded into it; the bootstrap-modules test lists are adjusted).
A bare worker compiles 95 -> 83 builtins (cold start -5%); without the
snapshot an empty CommonJS entry point compiles 76 -> 59 builtins and an
empty ES module entry point 76 -> 69.
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65329
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Aviv Keller <me@aviv.sh>
Decided to take a short break from the work on QUIC
to implement a DTLS API. Very experimental at this
point but the basic API is there (inspired by the
QUIC API work).
The implementation is based on OpenSSL's built-in
DTLS support and no other dependencies are required.
DTLS is a datagram-based version of TLS that is used
for things like WebRTC and CoAP. It provides similar
security guarantees as TLS but is designed to work over
UDP instead of TCP.
This shouldn't be considered ready for production
but it is a good starting point for experimentation
and feedback.
```bash
./configure --experimental-dtls
make -j{nproc}
./node --experimental-dtls my-dtls-app.js
```
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode:Opus 4.6
PR-URL: https://github.com/nodejs/node/pull/63182
Fixes: https://github.com/nodejs/node/issues/61630
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Implement QuotaExceededError as a DOMException-derived interface per the
WebIDL specification update.
QuotaExceededError is now a proper constructor exposed as a global
[Exposed=*] interface that extends DOMException with optional `quota`
and `requested` attributes (both nullable doubles, defaulting to null).
The constructor validates that quota and requested are finite,
non-negative, and that requested is not less than quota when both are
provided.
QuotaExceededError is [Serializable] and supports structuredClone,
preserving the quota and requested values across the serialization
boundary.
Callers updated:
- crypto.getRandomValues() now throws a QuotaExceededError instance
- WebStorage (C++) now constructs QuotaExceededError directly
Refs: https://redirect.github.com/whatwg/webidl/pull/1465
Fixes: https://github.com/nodejs/node/issues/58987
PR-URL: https://github.com/nodejs/node/pull/62293
Reviewed-By: Mattias Buelens <mattias@buelens.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Replace the domain-based error handling with AsyncLocalStorage and
setUncaughtExceptionCaptureCallback. This removes the REPL's dependency
on the deprecated domain module while preserving all existing behavior:
- Synchronous errors during eval are caught and displayed
- Async errors (setTimeout, promises, etc.) are caught via the
uncaught exception capture callback
- Top-level await errors are caught and displayed
- The REPL continues operating after errors
- Multiple REPL instances can coexist with errors routed correctly
Changes:
- Use AsyncLocalStorage to track which REPL instance owns an async
context, replacing domain's automatic async tracking
- Add setupExceptionCapture() to install
setUncaughtExceptionCaptureCallback for catching async errors and
routing them to the correct REPL
- Extract error handling logic into REPLServer.prototype._handleError()
- Wrap eval execution in replContext.run() for async context tracking
- Update newListener protection to check AsyncLocalStorage context
- Throw ERR_INVALID_ARG_VALUE if options.domain is passed
PR-URL: https://github.com/nodejs/node/pull/61227
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Move node:quic behind a compile-time flag, disabled by default.
Use --experimental-quic at configure time to enable.
- Add --experimental-quic flag to configure.py
- Add node_use_quic variable and HAVE_QUIC define
- Make QUIC sources conditional in node.gyp
- Move ngtcp2/nghttp3 deps under QUIC condition in node.gypi
- Update C++ guards to check HAVE_QUIC
- Update process.features.quic to check node_use_quic
PR-URL: https://github.com/nodejs/node/pull/61444
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
`v8::Module::IsGraphAsync()` traverses the dependencies to find if they
contain TLA each time. `ModuleWrap.hasAsyncGraph` caches the result
and exposes the property to JS land so that the presence of the property
`module.hasAsyncGraph` can be consistent.
This also allows C++ access of cached `hasAsyncGraph`.
This merges the `intantiateSync`/`instantiate` and
`getNamespaceSync`/`getNamespace` as they are always sync.
PR-URL: https://github.com/nodejs/node/pull/59703
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Split `module.link(linker)` into two synchronous step
`sourceTextModule.linkRequests()` and
`sourceTextModule.instantiate()`. This allows creating vm modules and
resolving the dependencies in a complete synchronous procedure.
This also makes `syntheticModule.link()` redundant. The link step for a
SyntheticModule is no-op and is already taken care in the constructor
by initializing the binding slots with the given export names.
PR-URL: https://github.com/nodejs/node/pull/59000
Refs: https://github.com/nodejs/node/issues/37648
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Files in `node_modules` are not authored by the user directly and the
original sources are less relevant to the user.
Skipping source maps in `node_modules` improves the general
performance. Add `module.setSourceMapsSupport(enabled, options)` to
skip source maps in `node_modules` if it is needed. This moves
all source maps related API to `node:module` and this a step to
promote the source maps API to stable.
PR-URL: https://github.com/nodejs/node/pull/56639
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
The `process.ref(...)` and `process.unref(...)` methods are intended
to replace the use of `ref()` and `unref()` methods defined directly
on individual API objects. The existing `ref()` and `unref()` methods
will be marked as legacy and won't be removed but new APIs should use
`process.ref()` and `process.unref()` instead.
Refs: https://github.com/nodejs/node/issues/53266
PR-URL: https://github.com/nodejs/node/pull/56400
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
`process.getBuiltinModule(id)` provides a way to load built-in modules
in a globally available function. ES Modules that need to support
other environments can use it to conditionally load a Node.js built-in
when it is run in Node.js, without having to deal with the resolution
error that can be thrown by `import` in a non-Node.js environment or
having to use dynamic `import()` which either turns the module into an
asynchronous module, or turns a synchronous API into an asynchronous
one.
```mjs
if (globalThis.process.getBuiltinModule) {
// Run in Node.js, use the Node.js fs module.
const fs = globalThis.process.getBuiltinModule('fs');
// If `require()` is needed to load user-modules, use
// createRequire()
const module = globalThis.process.getBuiltinModule('module');
const require = module.createRequire(import.meta.url);
const foo = require('foo');
}
```
If `id` specifies a built-in module available in the current Node.js
process, `process.getBuiltinModule(id)` method returns the
corresponding built-in module. If `id` does not correspond to any
built-in module, `undefined` is returned.
`process.getBuiltinModule(id)` accept built-in module IDs that are
recognized by `module.isBuiltin(id)`. Some built-in modules must be
loaded with the `node:` prefix.
The built-in modules returned by `process.getBuiltinModule(id)` are
always the original modules - that is, it's not affected by
`require.cache`.
PR-URL: https://github.com/nodejs/node/pull/52762
Fixes: https://github.com/nodejs/node/issues/52599
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Zijian Liu <lxxyxzj@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
undici's MessageEvent is better tested and has a complete WebIDL
implementation for validation. Not only this, but it's also used in
Node's current WebSocket implementation. There are a large number of
webidl-related issues in the current MessageEvent, such as not
implementing `MessageEvent.prototype.initMessageEvent`, not validating
arguments passed to its constructor
(https://github.com/nodejs/node/pull/51771), not validating the values
passed to the constructor (such as not validating that `ports` is a
sequence, not converting origin to a USVString, etc.), and other issues.
fixup
PR-URL: https://github.com/nodejs/node/pull/52370
Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Robert Nagy <ronagy@icloud.com>