Repository navigation
bun-types: declare memoryPressure in ProcessEventMap; fix and enforce the scripts/build typecheck - #37790
bun-types: declare memoryPressure in ProcessEventMap; fix and enforce the scripts/build typecheck#37790robobun wants to merge 3 commits into
Conversation
… typecheck clean and enforced
bun-types declared on()/once()/off()/... overloads for "memoryPressure"
directly on NodeJS.Process. Interface merging puts those next to the
members Process declares itself, but replaces anything Process only
inherits: on @types/node 25.0.x, where Process extends
InternalEventEmitter<ProcessEventMap>, that is every event method, so
process.on("exit", ...) and every signal stop typechecking; on
@types/node <= 24 it is off() and removeListener(), which Process
inherits from EventEmitter. The repo pins @types/node 25.0.0, which is
why `tsc -p scripts/build/tsconfig.json` failed on the process.once /
process.off calls in scripts/build/ci.ts.
Declare the event in @types/node's ProcessEventMap instead. The
inherited (25.0.x) and redeclared (25.1+) generic overloads both key
off that map, so the listener stays typed and Node's own events are
untouched.
Also fix the three remaining noUncheckedIndexedAccess errors in
jsonByteClass.ts, xmlByteClass.ts and rust-lto-fix-cli.ts, and add
test/internal/build-typecheck.test.ts, which runs the typecheck that
scripts/build/CLAUDE.md documents so it cannot silently rot again.
|
Updated 1:05 PM PT - Aug 12th, 2026
❌ @robobun, your commit 01561c9 has some failures in 🧪 To try this PR locally: bunx bun-pr 37790That installs a local version of the PR into your bun-37790 --bun |
|
Status: reproduced on main with CI for the current head (01561c9, build 93310): all 179 jobs that ran passed, including both new tests on every lane, the bun-types workflow and source-lints. The build is marked failed only because the two darwin 26 aarch64 test shards expired without ever getting an agent; that is happening to every PR build right now (darwin 26 shards on all of the last ~40 PR builds are expired or waiting_failed) and has been reported separately. The earlier build (92998) had the same expired shards plus one unrelated grpc flake on darwin 14, also reported separately. Nothing left to do here from my side; ready for @alii's review of the bun-types change. |
WalkthroughChangesBun types and build checks
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Comment |
|
@coderabbitai review |
|
There was a problem hiding this comment.
I reviewed this PR and didn't find any bugs. Since it changes the public shape of the memoryPressure declaration in packages/bun-types/overrides.d.ts (CODEOWNER-protected) and takes an explicit trade-off on @types/node ≤ 24, a human sign-off on the bun-types change would still be worthwhile.
What was reviewed
ProcessEventMapaugmentation vs. the old per-method overloads — checked that thedeclare module "node:process"pattern matches the file's existingnode:tls/node:fs/promisesaugmentations and that the JSDoc is preserved.rust-lto-fix-cli.ts—bitcode[0] !== undefinedis equivalent tobitcode.length > 0here (array built fromreaddirSync().filter().map(), no sparse slots) and narrows the laterbitcode[0]use.jsonByteClass.ts/xmlByteClass.ts— LUT indices areb & 0xfandb >> 4on a byte, always 0–15 into 16-element arrays;!is safe and generated output is unchanged.- New
build-typecheck.test.ts— drains pipes concurrently,await using,skipIfgated on local devDeps, prefersnodeExe()to keep debug/ASAN runtime flat.
Extended reasoning...
Overview
This PR fixes a rotted tsc --noEmit -p scripts/build/tsconfig.json typecheck (11 errors on main) and enforces it in CI. The root cause of six errors is a bun-types bug: #32594 declared on/once/off/etc. overloads for "memoryPressure" directly on NodeJS.Process, which under interface merging replaces (rather than augments) methods that Process only inherits — on @types/node 25.0.x that is every event method, so process.on("exit", ...) etc. reject. The fix moves the declaration into @types/node's ProcessEventMap via a declare module "node:process" augmentation. The remaining five errors are trivial noUncheckedIndexedAccess fixes in build scripts (two ! assertions on provably-in-range LUT lookups; one bitcode.length > 0 → bitcode[0] !== undefined to get type narrowing). A new test/internal/build-typecheck.test.ts runs the typecheck in CI, and the bun-types fixture is expanded to cover all EventEmitter methods for both Node events and memoryPressure.
Security risks
None. This is type-declaration and build-script tooling only; no runtime code paths, no untrusted input handling, no auth/crypto/permissions.
Level of scrutiny
The build-script changes are mechanical and zero-risk (non-null assertions on 0–15 indices into 16-element const arrays; an equivalent length check). The bun-types change is small but is a public API surface change to a published package with an acknowledged behavioral trade-off on @types/node ≤ 24 (where ProcessEventMap doesn't exist, memoryPressure falls through to the untyped on/once fallback overloads instead of being typed on all eight methods). The PR argues this is the right side of the trade since bun-types already targets @types/node 25 (#25460) and the old declaration was actively breaking off/removeListener on ≤ 24 anyway — that reasoning is sound, but it's a policy call the bun-types codeowner should confirm.
Other factors
packages/bun-types/and*.d.tsare owned by a CODEOWNER per.github/CODEOWNERS, which by itself is reason to defer.- The new test follows repo conventions (harness helpers, concurrent pipe drain,
await using,skipIfwith a reason, combined-object assertion so failures show the tsc error list). It runstscundernodeExe() ?? bunExe()so debug/ASAN lanes don't pay a 10–100× penalty. - The fixture additions include exact-type assertions (
expectType(...).is<...>()) that would fail against the old declarations even on latest @types/node (viaProcessEventMap["memoryPressure"]andlisteners("memoryPressure")), so they guard the declaration shape and not just the pinned version. - I did not independently verify the augmentation against all three @types/node versions the PR lists (node_modules aren't installed in this checkout), but the mechanism described matches how TypeScript module augmentation and interface-vs-inherited-member merging work, and the file's other
node:*augmentations use the same pattern.
|
On the one point the review could not check itself, the @types/node matrix: each version was verified by installing it next to a copy of the new overrides.d.ts and typechecking a probe (Node events on every event method with exact listener types, memoryPressure on every method, Assigned to @alii for the bun-types sign-off since the trade-off on @types/node <= 24 is a policy call. |
…ild typecheck under node only Which @types/node version a typecheck loads decides whether redeclaring an event method on Process is caught (25.0.x catches all of them, <= 24 only off/removeListener, 25.1+ none), so the rule is enforced by a source lint over packages/bun-types instead of by whichever version the repo or the fixture happens to resolve. The source-lints workflow now also runs on bun-types changes. The build typecheck falling back to the bun under test was dead code in CI (the runner is node) and could not pass locally on a debug build, where tsc takes minutes; it now skips without node like it already did without the root devDependencies.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/internal/build-typecheck.test.ts`:
- Line 31: Update the command arguments in the build typecheck test to pass an
absolute TypeScript project path by replacing the relative project argument with
join(repoRoot, "scripts", "build", "tsconfig.json"), while preserving the
existing tsc invocation.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 40e93020-d080-4743-97bc-0df0ba060e30
📒 Files selected for processing (9)
.github/workflows/source-lints.ymlpackages/bun-types/overrides.d.tsscripts/build/CLAUDE.mdscripts/build/jsonByteClass.tsscripts/build/rust-lto-fix-cli.tsscripts/build/xmlByteClass.tstest/integration/bun-types/fixture/process.tstest/internal/build-typecheck.test.tstest/internal/source-lints/bun-types-process-event-methods.test.ts
There was a problem hiding this comment.
I reviewed this PR and didn't find any bugs. Since it changes the published packages/bun-types declarations (CODEOWNER-gated) and the author already flagged the @types/node ≤ 24 trade-off as a policy call for alii, I'll leave the sign-off to them.
What was reviewed:
overrides.d.ts: confirmed theProcessEventMapaugmentation follows the file's existingdeclare module "node:*"pattern and the JSDoc moved intact.rust-lto-fix-cli.ts/*ByteClass.ts: the!andbitcode[0] !== undefinednarrowing are behavior-preserving; generated LUT output is unchanged.- New source-lint: checked the brace/string blanker handles the nested-object-type and commented-overload cases its self-test covers, and that the vacuous-pass guard (
merges.length > 0) is present. build-typecheck.test.ts: skip gating on!isCI && (node === null || !existsSync(tsc))matches the stated CI invariants; pipes drained concurrently.
Extended reasoning...
Overview
The PR fixes a rotted tsc --noEmit -p scripts/build/tsconfig.json typecheck (11 errors on main) and enforces it going forward. Six of the errors trace to a bun-types regression: #32594 declared per-method memoryPressure overloads directly on NodeJS.Process, which under interface-merging rules replaces inherited EventEmitter members rather than adding to them, and how much Process inherits varies by @types/node version. The fix moves the declaration to a ProcessEventMap augmentation inside declare module "node:process". The remaining five errors are trivial noUncheckedIndexedAccess fixes in build scripts. Two new tests enforce the typecheck in CI and structurally lint bun-types for the pattern that caused the regression; the bun-types fixture gains exact-type coverage for both Node's events and memoryPressure across all EventEmitter methods.
Security risks
None. This is type-declaration and build-tooling only; no runtime code paths, auth, crypto, or untrusted-input handling are touched.
Level of scrutiny
Medium. The build-script edits (! assertions on in-range LUT indices, bitcode[0] !== undefined narrowing) are mechanical and provably behavior-preserving. The overrides.d.ts change, however, is a user-facing API-surface change to a published package with an explicitly documented trade-off on @types/node ≤ 24 (memoryPressure loses typed addListener/prepend*/off there in exchange for un-breaking off/removeListener for every other event). The reasoning is sound and well-verified across the version matrix, but it is exactly the kind of compatibility policy decision the CODEOWNER should confirm.
Other factors
.github/CODEOWNERSassigns/packages/bun-types/to alii, and the PR author explicitly requested their sign-off on the trade-off — approving over that would be inappropriate.- Test quality is high: the fixture uses
expectType().is<>exact assertions, the source-lint has a self-test proving it sees the right members and ignores nested/commented ones plus a non-vacuous guard, andbuild-typecheck.test.tsruns tsc under node so debug/ASAN lanes stay fast. The workflowpaths:addition ensures the new lint actually triggers on bun-types edits. - No prior claude[bot] review exists on this PR, so this is the first pass.
…ible with @types/node 24 (#40004) ### Problem - With `@types/node@24` installed, tsc rejects `process.removeListener("SIGINT", fn)` and `process.off(...)` with `error TS2345: Argument of type '"SIGINT"' is not assignable to parameter of type '"memoryPressure"'` (#40003). - The cause is `packages/bun-types/overrides.d.ts:112-114`. It declares `off` and `removeListener` overloads for the `memoryPressure` event on `NodeJS.Process`. `@types/node@24` does not declare these two methods on `Process`, it only inherits them from `EventEmitter`. A method declared on a derived interface hides the inherited overloads, so `memoryPressure` became the only accepted event name. ### Fix - Re-declare the generic `(event: string | symbol, listener: (...args: any[]) => void): this` signatures for `off` and `removeListener` next to the `memoryPressure` overloads. - This restores exactly what `EventEmitter` provides on `@types/node@24`. On `@types/node@26`, which declares the same generic signatures on `Process` directly, the merge adds an identical overload and nothing changes. - The other overridden methods (`on`, `once`, `addListener`, `prependListener`, `prependOnceListener`, `emit`) are declared on `Process` by `@types/node@24`, so declaration merging keeps them visible and they need no change. - Verified: new case in `test/integration/bun-types/bun-types.test.ts` pins `@types/node@24` and runs tsc over `removeListener`/`off`/`memoryPressure` calls. It fails on main with the exact error above. The full bun-types integration suite passes (16/16). ### Background - `bun-types` augments `NodeJS.Process` in `overrides.d.ts` to type the Bun-only `memoryPressure` event (#32594). - TypeScript merges same-name interface declarations, so overloads added to `Process` coexist with the ones `@types/node` declares there. Hiding only happens for methods the base interface (`EventEmitter`) declares and the derived interface (`Process`) does not. - The existing bun-types fixture resolves `@types/node@latest` (currently 26), which masks the bug. That is why #39807 was closed as unreproducible. The new test pins major 24 and asserts the installed major so resolution drift cannot make it vacuous. - #37790 touches the same declarations with a `ProcessEventMap` approach, bundled with unrelated scripts/build typecheck fixes. This PR is the minimal fix for the reported break on the current `@types/node` LTS. <!-- robobun:evidence:begin --> --- **[review]** gate passed · iteration 1 · 2 files touched <details><summary>fails on main (without fix)</summary> ```console ASAN without fix: BUILD FAILED (no junit output) $ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/integration/bun-types/bun-types.test.ts ninja: Entering directory `/workspace/bun/build/debug' [1/26] gen generated_host_exports.rs generated_host_exports.rs: 122 exports (host=5, lazy=10, generic=107, rust=0); 244 extern-C blocks audited [2/26] gen cpp.rs (cppbind) [3/26] gen JS modules (bundle-modules) Preprocess modules (7475ms) Bundle modules (60ms) Postprocesss modules (199ms) Bundle Functions (490ms) Generate Code (35ms) [8.27s] Bundled "src/js" for development 2787 kb 197 internal modules 13 native modules 50 internal functions across 16 files [3/8] cargo bun_runtime → libbun_runtime.a [4/8] cc obj/codegen/InternalModuleRegistryConstants.S.o FAILED: rust-target/x86_64-unknown-linux-gnu/debug/libbun_runtime.a /workspace/bun/build/release/bun /workspace/bun/scripts/build/stream.ts rust --console --cwd=/workspace/bun --env=CARGO_TERM_COLOR=always --env=BUN_CODEGEN_DIR=/workspace/bun/build/debug/codegen --env=CC=/usr/lib/llvm-21/bin/clang --env=CXX=/usr/lib/llvm-21/bin/clang++ --env=AR=/usr/lib/llvm-21/bin/llvm-ar - ... (truncated) release without fix: 1 FAILED bun test v1.4.1-canary.1 (7e07e7a) test/integration/bun-types/bun-types.test.ts: (pass) @types/bun integration test > building and packing bun-types leaves packages/bun-types untouched [0.10ms] (pass) @types/bun integration test > packed bun-types includes CLAUDE.md [0.34ms] (pass) @types/bun integration test > basic type checks > checks without lib.dom.d.ts [2875.25ms] (pass) @types/bun integration test > tsgo (TypeScript 7 native preview) > checks without lib.dom.d.ts [553.59ms] (pass) @types/bun integration test > Bun.mmap > MMapOptions accepts offset and size [48.09ms] (pass) @types/bun integration test > TextDecoder > accepts the encoding labels the runtime supports [49.86ms] (pass) @types/bun integration test > TextDecoder > the fixture label table matches the runtime [0.79ms] (pass) @types/bun integration test > Event and EventTarget > lib.dom's composedPath() declaration wins when lib.dom is loaded [78.63ms] (pass) @types/bun integration test > Event and EventTarget > the Node-style composedPath() tuple applies without lib.dom [51.17ms] 570 | }); 571 | 572 | const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr ... (truncated) ``` </details> <details><summary>passes on PR (with fix)</summary> ```console ASAN with fix: 12 skipped $ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/integration/bun-types/bun-types.test.ts bun test v1.4.1 (d578a8c) test/integration/bun-types/bun-types.test.ts: (pass) @types/bun integration test > building and packing bun-types leaves packages/bun-types untouched [2.04ms] (pass) @types/bun integration test > packed bun-types includes CLAUDE.md [5.88ms] (skip) @types/bun integration test > basic type checks > checks without lib.dom.d.ts (skip) @types/bun integration test > tsgo (TypeScript 7 native preview) > checks without lib.dom.d.ts (pass) @types/bun integration test > Bun.mmap > MMapOptions accepts offset and size [745.09ms] (pass) @types/bun integration test > TextDecoder > accepts the encoding labels the runtime supports [682.14ms] (pass) @types/bun integration test > TextDecoder > the fixture label table matches the runtime [38.91ms] (pass) @types/bun integration test > Event and EventTarget > lib.dom's composedPath() declaration wins when lib.dom is loaded [718.69ms] (pass) @types/bun integration test > Event and EventTarget > the Node-style composedPath() tuple appl ... (truncated) release with fix: all passed $ bun scripts/build.ts --profile=release [configured] bun-profile → bun (stripped) in 773ms (unchanged) ninja: Entering directory `/workspace/bun/build/release' [1/23] gen generated_host_exports.rs generated_host_exports.rs: 122 exports (host=5, lazy=10, generic=107, rust=0); 244 extern-C blocks audited [2/23] gen cpp.rs (cppbind) [3/23] gen JS modules (bundle-modules) Preprocess modules (7439ms) Bundle modules (34ms) Postprocesss modules (40ms) Bundle Functions (439ms) Generate Code (23ms) [7.98s] Bundled "src/js" for production 2594 kb 197 internal modules 13 native modules 50 internal functions across 16 files [3/8] cargo bun_runtime → libbun_runtime.a �[1m�[92m Compiling�[0m bun_core v0.0.0 (/workspace/bun/src/bun_core) �[1m�[92m Compiling�[0m bun_errno v0.0.0 (/workspace/bun/src/errno) �[1m�[92m Compiling�[0m bun_ptr v0.0.0 (/workspace/bun/src/ptr) �[1m�[92m Compiling�[0m bun_boringssl_sys v0.0.0 (/workspace/bun/src/boringssl_sys) �[1m�[92m Compiling�[0m bun_safety v0.0.0 (/workspace/bun/src/safety) �[1m�[92m Compiling�[0m bun_base64 v0.0.0 (/workspace/bun/src/base64) �[1m�[92m Compiling�[0m bun_cares_sys v0.0.0 (/workspace/bun/src/ca ... (truncated) ``` </details> <details><summary>diff hotspot</summary> ``` packages/bun-types/overrides.d.ts | 8 +++++ test/integration/bun-types/bun-types.test.ts | 53 ++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) ``` </details> **gate history** · 4 passed · 0 rejected · iteration 1 <details><summary>evidence per changed file</summary> ``` file reads edits tests packages/bun-types/overrides.d.ts 1 1 0 test/integration/bun-types/bun-types.test.ts 4 5 0 ``` </details> **root cause** · written by the author bot The bug was that the memoryPressure overloads for removeListener and off in overrides.d.ts were the only declarations of those methods on the NodeJS.Process interface under @types/node@24, where Process inherits them solely from EventEmitter; since re-declared methods in a derived interface hide inherited overloads rather than merging with them, the memoryPressure signature became the only one visible, rejecting any other event name. The fix re-declares the generic (eventName: string | symbol, listener: (...args: any[]) => void) overload alongside the memoryPressure overloads, so both the t… <!-- robobun:evidence:end -->
|
The bun-types part of this change is now #41208 on its own, on top of #40004, which removed the conflict this branch has with main. That PR also drops the |
|
this was fixed already i think? |
|
shall we close this |
|
Partly. I checked main at 1d1f431. Fixed on main:
Not fixed on main:
Yes, I am closing this PR. It conflicts with main, and #41208 has its bun-types part. If you want CI to enforce the scripts/build typecheck, mention me here. Then I will open a small PR with the two one-line fixes and the test from this branch. |
Problem
bunx tsc --noEmit -p scripts/build/tsconfig.json, the typecheck scripts/build/CLAUDE.md documents, exits 2 on main with 11 errors in files nobody is editing. Nothing in CI runs it, so it rotted.TS2345: Argument of type '"beforeExit"' is not assignable to parameter of type '"memoryPressure"'on plainprocess.once/process.offcalls. They come from Add process.on('memoryPressure') event #32594, which declared thememoryPressureoverloads ofon/once/off/... directly onNodeJS.Process."memoryPressure"is the only event they accept. On <= 24 onlyoff/removeListenerbreak; on 25.1+ nothing does, and that is what the bun-types fixture installs, so it never saw this.TS2532,TS2769) are ordinarynoUncheckedIndexedAccessmisses in code added after the typecheck stopped being run.Fix
memoryPressurebecomes an entry in @types/node'sProcessEventMap(adeclare module "node:process"augmentation) instead of redeclared methods. Both the inherited (25.0.x) and redeclared (25.1+) method sets key off that map, so every method types the event and Node's own events are untouched.memoryPressureis only accepted whereProcesshas an untyped fallback overload (on,once). bun-types has targeted @types/node 25 since @types/bun: Update to @types/node@25, fallback to PropertyKey in test expect matchers whenkeyof unknownis used #25460 and its othernode:*augmentations degrade the same way.!assertions or an!== undefinedcheck. The table lookups are in range for any byte, and the generated output is byte-identical.Processmerge in bun-types (eight hits on main, none here, on any @types/node), and a new test runs the scripts/build typecheck in CI (fails on main). The declaration was also typechecked against @types/node 25.0.0, 25.1.0 and 26.2.0.Background
packages/bun-typesis the published type package. It adds Bun's members to Node'sNodeJS.Processby declaringinterface Process { ... }again, which TypeScript merges with @types/node's declaration.onadds an overload or wipes the method depending on where @types/node put it, and that moved between 24, 25.0 and 25.1.ProcessEventMap(@types/node 25) maps each process event name to its listener argument tuple; the event methods are generic over it, so one entry types an event on all of them.noUncheckedIndexedAccessis the tsconfig option under whicharr[i]isT | undefined, hence the!assertions.test/internal/source-lints/runs on a bare checkout with nothing installed, so its lint is a text scan;test/internal/has the root devDependencies, which tsc needs.Original description
Problem
bunx tsc --noEmit -p scripts/build/tsconfig.json, the typecheck scripts/build/CLAUDE.md documents, exits 2 on main (9518091 and 626034f) with 11 errors in files nobody is editing. Nothing in CI runs it, so it rotted:Cause
The six ci.ts errors are a bun-types bug, not a build-script one. #32594 added
process.on("memoryPressure")by declaringon/once/off/addListener/removeListener/prependListener/prependOnceListener/emitoverloads for that one event directly onNodeJS.Processin overrides.d.ts. Interface merging adds those next to overloadsProcessdeclares itself, but a member declared on the merged interface replaces anythingProcessonly inherits, and what it inherits depends on the @types/node version:Process, exceptoffandremoveListener, which come fromEventEmitterprocess.off(...)andprocess.removeListener(...)only accept"memoryPressure"InternalEventEmitter<ProcessEventMap>"memoryPressure",process.on("exit", ...)includedProcessEventMap, declared onProcessagainlatestThe repo pins @types/node 25.0.0 (root and test/
resolutions), so anything typechecked against packages/bun-types in this repo gets the middle row. Theprocess.once/process.offcalls in ci.ts are where the build project runs into it.The other five errors are ordinary
noUncheckedIndexedAccessmisses in code added after the typecheck stopped being run.Fix
overrides.d.ts: declare the event in @types/node'sProcessEventMap(adeclare module "node:process"augmentation, like the file's othernode:*augmentations) instead of redeclaring the methods. The inherited (25.0.x) and redeclared (25.1+) generic overloads both key off that map, solevelis typed"warning" | "critical"on every method,process.ProcessEventMap["memoryPressure"]exists the same way it does for Node's events, and Node's own events are left alone. The JSDoc moves onto the map entry. Trade-off on @types/node <= 24, which has no event map:memoryPressureis only accepted whereProcesshas an untyped fallback overload (on,once), whereas before it was typed on all eight methods butoff/removeListenerwere broken for every other event. bun-types has targeted @types/node 25 since @types/bun: Update to @types/node@25, fallback to PropertyKey in test expect matchers whenkeyof unknownis used #25460 (the existingnode:tlsandnode:fs/promisesaugmentations degrade the same way on 24), so this seems like the right side of the trade.jsonByteClass.ts,xmlByteClass.ts: the nibble LUT lookups are in range for any byte; assert it with!like the rest of scripts/build. Generated output is byte-identical.rust-lto-fix-cli.ts: assertbitcode[0] !== undefinedrather thanbitcode.length > 0, which narrows the later use; same patternmain()already uses forargv.Tests
test/internal/source-lints/bun-types-process-event-methods.test.tsis the durable guard for the bun-types rule. Whether a typecheck catches an event method redeclared onProcessdepends on which @types/node it loads (all of them on 25.0.x, onlyoff/removeListeneron <= 24, none on 25.1+, which is what the bun-types fixture installs), so instead the lint scans everyinterface Processmerge in the published .d.ts files and fails on any EventEmitter member declared there. On main it reports the eight members from Add process.on('memoryPressure') event #32594 (overrides.d.ts:78: on,once,off, ...); it also checks its own scanner against a sample with nested object types, doc comments and string literals, and asserts it still finds the package'sProcessmerges so it cannot pass vacuously.source-lints.ymlnow also runs onpackages/bun-types/**.test/internal/build-typecheck.test.tsruns the documented typecheck with the typescript pinned in the root package.json. On main it fails with the ci.ts errors above in the assertion output; with this change it passes. tsc runs under node (always present in CI, where the runner itself is node; locally the test skips without it or without the root devDependencies), since the same run under a debug bun takes minutes. It is in test/internal rather than test/internal/source-lints because it needs the root devDependencies installed, which that workflow deliberately does not do.test/integration/bun-types/fixture/process.tsnow assertsmemoryPressureis an entry inprocess.ProcessEventMapand is typed on every method includinglisteners()(both fail against the old declarations on any @types/node), and exercises Node's own events on the methods that have at times been inherited, which matters whenever the current @types/node has such a shape.Verification
memoryPressureon every method, withskipLibCheckoff, against @types/node 25.0.0, 25.1.0 and 26.2.0; the old one fails 25.0.0 as described above. The updated fixture typechecked against packages/bun-types with the repo's pinned 25.0.0: 19 errors with the old declaration, none with the new one.bun test test/integration/bun-types/bun-types.test.tswith a release bun (fixture resolves @types/node 26.2.0): 14/14 pass.bun test test/internal/source-lints/as the workflow runs it: 85/85 pass;bun bd test test/internal/build-*.test.ts: pass;tsc -p packages/bun-typespasses.