diff --git a/pkgs/development/web/nodejs/deprecate-http2-priority-signaling.patch b/pkgs/development/web/nodejs/deprecate-http2-priority-signaling.patch new file mode 100644 index 0000000000000..efcf74cdb26c1 --- /dev/null +++ b/pkgs/development/web/nodejs/deprecate-http2-priority-signaling.patch @@ -0,0 +1,113 @@ +Adapted from https://github.com/nodejs/node/pull/58293 for 22.x and 20.x lines. + +diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js +index cf7b06d987..369133dafb 100644 +--- a/lib/internal/http2/core.js ++++ b/lib/internal/http2/core.js +@@ -30,2 +30,4 @@ const { + promisify, ++ deprecate, ++ deprecateProperty, + SymbolAsyncDispose, +@@ -713,2 +715,7 @@ function onGoawayData(code, lastStreamID, buf) { + ++// TODO(aduh95): remove this in future semver-major ++const deprecateWeight = deprecateProperty('weight', ++ 'Priority signaling has been deprecated as of RFC 1993.', ++ 'DEP0194'); ++ + // When a ClientHttp2Session is first created, the socket may not yet be +@@ -741,2 +748,4 @@ function requestOnConnect(headers, options) { + ++ deprecateWeight(options); ++ + // `ret` will be either the reserved stream ID (if positive) +@@ -746,3 +755,3 @@ function requestOnConnect(headers, options) { + options.parent | 0, +- options.weight | 0, ++ NGHTTP2_DEFAULT_WEIGHT, + !!options.exclusive); +@@ -785,7 +794,3 @@ function requestOnConnect(headers, options) { + const setAndValidatePriorityOptions = hideStackFrames((options) => { +- if (options.weight === undefined) { +- options.weight = NGHTTP2_DEFAULT_WEIGHT; +- } else { +- validateNumber.withoutStackTrace(options.weight, 'options.weight'); +- } ++ deprecateWeight(options); + +@@ -845,21 +850,2 @@ function submitSettings(settings, callback) { + +-// Submits a PRIORITY frame to be sent to the remote peer +-// Note: If the silent option is true, the change will be made +-// locally with no PRIORITY frame sent. +-function submitPriority(options) { +- if (this.destroyed) +- return; +- this[kUpdateTimer](); +- +- // If the parent is the id, do nothing because a +- // stream cannot be made to depend on itself. +- if (options.parent === this[kID]) +- return; +- +- this[kHandle].priority(options.parent | 0, +- options.weight | 0, +- !!options.exclusive, +- !!options.silent); +-} +- + // Submit a GOAWAY frame to be sent to the remote peer. +@@ -2255,21 +2241,2 @@ class Http2Stream extends Duplex { + +- priority(options) { +- if (this.destroyed) +- throw new ERR_HTTP2_INVALID_STREAM(); +- +- assertIsObject(options, 'options'); +- options = { ...options }; +- setAndValidatePriorityOptions(options); +- +- const priorityFn = submitPriority.bind(this, options); +- +- // If the handle has not yet been assigned, queue up the priority +- // frame to be sent as soon as the ready event is emitted. +- if (this.pending) { +- this.once('ready', priorityFn); +- return; +- } +- priorityFn(); +- } +- + sendTrailers(headers) { +@@ -2431,2 +2398,8 @@ class Http2Stream extends Duplex { + ++// TODO(aduh95): remove this in future semver-major ++Http2Stream.prototype.priority = deprecate(function priority(options) { ++ if (this.destroyed) ++ throw new ERR_HTTP2_INVALID_STREAM(); ++}, 'http2Stream.priority is longer supported after priority signalling was deprecated in RFC 1993', 'DEP0194'); ++ + function callTimeout(self, session) { +diff --git a/lib/internal/util.js b/lib/internal/util.js +index 254791eb48..2f12f5a3f1 100644 +--- a/lib/internal/util.js ++++ b/lib/internal/util.js +@@ -135,2 +135,13 @@ function isPendingDeprecation() { + ++function deprecateProperty(key, msg, code, isPendingDeprecation) { ++ const emitDeprecationWarning = getDeprecationWarningEmitter( ++ code, msg, undefined, false, isPendingDeprecation, ++ ); ++ return (options) => { ++ if (key in options) { ++ emitDeprecationWarning(); ++ } ++ }; ++} ++ + // Internal deprecator for pending --pending-deprecation. This can be invoked +@@ -911,2 +922,3 @@ module.exports = { + deprecate, ++ deprecateProperty, + emitExperimentalWarning, diff --git a/pkgs/development/web/nodejs/nodejs.nix b/pkgs/development/web/nodejs/nodejs.nix index 03d8cbb0dac62..77a237432e716 100644 --- a/pkgs/development/web/nodejs/nodejs.nix +++ b/pkgs/development/web/nodejs/nodejs.nix @@ -2,11 +2,36 @@ lib, stdenv, fetchurl, - openssl, + fetchpatch2, + fetchFromGitHub, python, - zlib, + ada, + brotli, + c-ares, libuv, + llhttp, + nghttp2, + nghttp3, + ngtcp2, + openssl, + simdjson, + simdutf, + simdutf_6 ? ( + simdutf.overrideAttrs { + version = "6.5.0"; + + src = fetchFromGitHub { + owner = "simdutf"; + repo = "simdutf"; + rev = "v6.5.0"; + hash = "sha256-bZ4r62GMz2Dkd3fKTJhelitaA8jUBaDjG6jOysEg8Nk="; + }; + } + ), sqlite, + uvwasi, + zlib, + zstd, icu, bash, ninja, @@ -98,14 +123,47 @@ let null; # TODO: also handle MIPS flags (mips_arch, mips_fpu, mips_float_abi). - useSharedSQLite = lib.versionAtLeast version "22.5"; + useSharedAdaAndSimd = !stdenv.hostPlatform.isStatic && lib.versionAtLeast version "22.2"; + useSharedSQLite = !stdenv.hostPlatform.isStatic && lib.versionAtLeast version "22.5"; + useSharedZstd = !stdenv.hostPlatform.isStatic && lib.versionAtLeast version "22.15"; - sharedLibDeps = { - inherit openssl zlib libuv; - } - // (lib.optionalAttrs useSharedSQLite { - inherit sqlite; - }); + sharedLibDeps = + (lib.optionalAttrs (!stdenv.hostPlatform.isStatic) { + inherit + brotli + libuv + nghttp3 + ngtcp2 + openssl + uvwasi + zlib + ; + cares = c-ares; + http-parser = llhttp; + nghttp2 = nghttp2.overrideAttrs { + patches = [ + (fetchpatch2 { + url = "https://github.com/nghttp2/nghttp2/commit/7784fa979d0bcf801a35f1afbb25fb048d815cd7.patch?full_index=1"; + hash = "sha256-RG87Qifjpl7HTP9ac2JwHj2XAbDlFgOpAnpZX3ET6gU="; + excludes = [ "lib/includes/nghttp2/nghttp2.h" ]; + revert = true; + }) + ]; + }; + }) + // (lib.optionalAttrs useSharedAdaAndSimd { + inherit + ada + simdjson + ; + simdutf = if lib.versionAtLeast version "25" then simdutf else simdutf_6; + }) + // (lib.optionalAttrs useSharedSQLite { + inherit sqlite; + }) + // (lib.optionalAttrs useSharedZstd { + inherit zstd; + }); copyLibHeaders = map (name: "${lib.getDev sharedLibDeps.${name}}/include/*") ( builtins.attrNames sharedLibDeps @@ -182,13 +240,10 @@ let # wrappers over the corresponding JS scripts. There are some packages though # that use bash wrappers, e.g. polaris-web. buildInputs = [ - zlib - libuv - openssl - icu bash + icu ] - ++ lib.optionals useSharedSQLite [ sqlite ]; + ++ builtins.attrValues sharedLibDeps; nativeBuildInputs = [ installShellFiles @@ -388,6 +443,10 @@ let ++ lib.optionals (!lib.versionAtLeast version "22") [ "test-tls-multi-key" ] + ++ lib.optionals useSharedAdaAndSimd [ + # Different versions of Ada affect the WPT tests + "test-url" + ] ++ lib.optionals stdenv.hostPlatform.is32bit [ # utime (actually utimensat) fails with EINVAL on 2038 timestamp "test-fs-utimes-y2K38" diff --git a/pkgs/development/web/nodejs/v20.nix b/pkgs/development/web/nodejs/v20.nix index a71eb5ce3f288..9c5104b72367b 100644 --- a/pkgs/development/web/nodejs/v20.nix +++ b/pkgs/development/web/nodejs/v20.nix @@ -1,4 +1,6 @@ { + lib, + stdenv, callPackage, fetchpatch2, openssl, @@ -54,5 +56,19 @@ buildNodejs { hash = "sha256-wF4+CytC1OB5egJGOfLm1USsYY12f9kADymVrxotezE="; }) ] + ++ lib.optionals (!stdenv.hostPlatform.isStatic) [ + # Fix builds with shared llhttp + (fetchpatch2 { + url = "https://github.com/nodejs/node/commit/ff3a028f8bf88da70dc79e1d7b7947a8d5a8548a.patch?full_index=1"; + hash = "sha256-LJcO3RXVPnpbeuD87fiJ260m3BQXNk3+vvZkBMFUz5w="; + }) + # update tests for nghttp2 1.65 + ./deprecate-http2-priority-signaling.patch + (fetchpatch2 { + url = "https://github.com/nodejs/node/commit/a63126409ad4334dd5d838c39806f38c020748b9.diff?full_index=1"; + hash = "sha256-lfq8PMNvrfJjlp0oE3rJkIsihln/Gcs1T/qgI3wW2kQ="; + includes = [ "test/*" ]; + }) + ] ++ gypPatches; } diff --git a/pkgs/development/web/nodejs/v22.nix b/pkgs/development/web/nodejs/v22.nix index a9be2fdad4b36..e696eef7fecb0 100644 --- a/pkgs/development/web/nodejs/v22.nix +++ b/pkgs/development/web/nodejs/v22.nix @@ -57,5 +57,19 @@ buildNodejs { ./use-correct-env-in-tests.patch ./bin-sh-node-run-v22.patch ./use-nix-codesign.patch + ] + ++ lib.optionals (!stdenv.hostPlatform.isStatic) [ + # Fix builds with shared llhttp + (fetchpatch2 { + url = "https://github.com/nodejs/node/commit/ff3a028f8bf88da70dc79e1d7b7947a8d5a8548a.patch?full_index=1"; + hash = "sha256-LJcO3RXVPnpbeuD87fiJ260m3BQXNk3+vvZkBMFUz5w="; + }) + # update tests for nghttp2 1.65 + ./deprecate-http2-priority-signaling.patch + (fetchpatch2 { + url = "https://github.com/nodejs/node/commit/a63126409ad4334dd5d838c39806f38c020748b9.diff?full_index=1"; + hash = "sha256-lfq8PMNvrfJjlp0oE3rJkIsihln/Gcs1T/qgI3wW2kQ="; + includes = [ "test/*" ]; + }) ]; }