From d55d4c05b10529fbe7c90fc1ee36803c6992ca16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Thu, 13 Aug 2026 14:29:22 +0200 Subject: [PATCH 1/2] Upgrade bufout to v1.0.0 and remove EventEmitter listener limits (#438) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: upgrade bufout to v1.0.0 and drop defaultMaxListeners bumps bufout v1.0.0 keeps the number of listeners on the process and on the output streams constant regardless of how many children are spawned concurrently: a single shared exit/SIGINT listener is attached only while children are running, and every child pipes into one shared pass-through per destination stream. That removes the reason the CLIs raised EventEmitter.defaultMaxListeners to 100, so those assignments (and the now-unused node:events / node:stream imports) are gone and Node's default limit applies again, restoring the leak warning it exists to give. Verified with 80 concurrent children in both "inherit" and "buffered" mode, plus the SpawnFailure flush path, at the default limit of 10: no MaxListenersExceededWarning, and process listener counts return to zero. The public API is unchanged from 0.3.x — the major bump reflects the 1.0.0 milestone, not a breaking change to spawn/SpawnFailure. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01BAjP89a9VA9EtQsVBxGcto * ci: trigger label-gated jobs The Check workflow only runs on opened/synchronize/reopened, so the Apple/Android/Ferric jobs gated on labels never evaluated the labels added after the pull request was opened. This empty commit fires a synchronize event so they run. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01BAjP89a9VA9EtQsVBxGcto --------- Co-authored-by: Claude (cherry picked from commit 48fa7fc6856b8c5b32bd5a2587fc6573a5d59f7a) --- .changeset/bufout-one-point-oh.md | 16 ++++++++++++++++ packages/cli-utils/package.json | 2 +- packages/cmake-rn/src/cli.ts | 4 ---- packages/ferric/src/run.ts | 5 ----- packages/host/src/node/cli/program.ts | 4 ---- pnpm-lock.yaml | 10 +++++----- 6 files changed, 22 insertions(+), 19 deletions(-) create mode 100644 .changeset/bufout-one-point-oh.md diff --git a/.changeset/bufout-one-point-oh.md b/.changeset/bufout-one-point-oh.md new file mode 100644 index 00000000..83ec2f32 --- /dev/null +++ b/.changeset/bufout-one-point-oh.md @@ -0,0 +1,16 @@ +--- +"@react-native-node-api/cli-utils": patch +"react-native-node-api": patch +"cmake-rn": patch +"ferric-cli": patch +--- + +Upgrade `bufout` to v1.0.0, which keeps the number of listeners on the process +and the output streams constant regardless of how many children are spawned +concurrently: a single shared `exit`/`SIGINT` listener is attached only while +children are running, and every child pipes into one shared pass-through per +destination stream. + +That removes the reason for the CLIs to raise `EventEmitter.defaultMaxListeners` +to 100, so those assignments are gone and Node's default limit again applies — +restoring the leak warning it exists to give. diff --git a/packages/cli-utils/package.json b/packages/cli-utils/package.json index 25cbaeef..f6fb1122 100644 --- a/packages/cli-utils/package.json +++ b/packages/cli-utils/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "@commander-js/extra-typings": "^14.0.0", - "bufout": "^0.3.2", + "bufout": "^1.0.0", "chalk": "^5.4.1", "commander": "^14.0.1", "ora": "^8.2.0", diff --git a/packages/cmake-rn/src/cli.ts b/packages/cmake-rn/src/cli.ts index b94e2fa2..a2b07e74 100644 --- a/packages/cmake-rn/src/cli.ts +++ b/packages/cmake-rn/src/cli.ts @@ -1,7 +1,6 @@ import assert from "node:assert/strict"; import path from "node:path"; import fs from "node:fs"; -import { EventEmitter } from "node:events"; import { chalk, @@ -22,9 +21,6 @@ import { import { Platform } from "./platforms/types.js"; import { getCcachePath } from "./ccache.js"; -// We're attaching a lot of listeners when spawning in parallel -EventEmitter.defaultMaxListeners = 100; - const verboseOption = new Option( "--verbose", "Print more output during the build", diff --git a/packages/ferric/src/run.ts b/packages/ferric/src/run.ts index 01311284..7b14eb8b 100644 --- a/packages/ferric/src/run.ts +++ b/packages/ferric/src/run.ts @@ -1,8 +1,3 @@ -import EventEmitter from "node:events"; - import { program } from "./program.js"; -// We're attaching a lot of listeners when spawning in parallel -EventEmitter.defaultMaxListeners = 100; - program.parseAsync(process.argv).catch(console.error); diff --git a/packages/host/src/node/cli/program.ts b/packages/host/src/node/cli/program.ts index e3c63904..77d8b8f4 100644 --- a/packages/host/src/node/cli/program.ts +++ b/packages/host/src/node/cli/program.ts @@ -1,6 +1,5 @@ import assert from "node:assert/strict"; import path from "node:path"; -import { EventEmitter } from "node:stream"; import { Command, @@ -28,9 +27,6 @@ import { linkModules, pruneLinkedModules, ModuleLinker } from "./link-modules"; import { ensureXcodeBuildPhase, createAppleLinker } from "./apple"; import { linkAndroidDir } from "./android"; -// We're attaching a lot of listeners when spawning in parallel -EventEmitter.defaultMaxListeners = 100; - export const program = new Command("react-native-node-api").addCommand( vendorHermes, ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a011bada..9632a67c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -144,8 +144,8 @@ importers: specifier: ^14.0.0 version: 14.0.0(commander@14.0.3) bufout: - specifier: ^0.3.2 - version: 0.3.4 + specifier: ^1.0.0 + version: 1.0.0 chalk: specifier: ^5.4.1 version: 5.6.2 @@ -2742,8 +2742,8 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - bufout@0.3.4: - resolution: {integrity: sha512-m8iGxYUvWLdQ9CQ9Sjnmr8hJHlpXfRQn2CV3eI5b107MWQqAe/K/pqsCGmczkSy3r7E1HW5u5z86z2aBYbwwxQ==} + bufout@1.0.0: + resolution: {integrity: sha512-ZCFKJOWLZqZKitcDUTIsJucC9EhOiYl/wb7Fg1TfzlFz1FhjrykZAkn5Gb7JyIsW5ViZjDXL8tr2bXReM/u/XQ==} bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} @@ -7760,7 +7760,7 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - bufout@0.3.4: {} + bufout@1.0.0: {} bytes@3.1.2: {} From 419a1d1c8379adfb20691586152e1ebf53ebd627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 7 Oct 2026 11:18:28 +0200 Subject: [PATCH 2/2] ci: trigger label-gated jobs Co-Authored-By: Claude Opus 5.5