Skip to content

Bun parity: cover the Bun.serve idleTimeout mapping (server timeouts) #663

@vivek7405

Description

@vivek7405

Problem

The server-timeout configuration (webjs.requestTimeoutMs / headersTimeoutMs / keepAliveTimeoutMs, #237) has cross-runtime coverage on Node only. The node test packages/server/test/body-limit/server-timeouts.test.js asserts server.requestTimeout / headersTimeout / keepAliveTimeout (node:http-specific) and is DENYLISTED from the Bun matrix (scripts/run-bun-tests.js) for that reason. On the Bun shell, startBunListener maps the configured requestTimeout to Bun.serve's single idleTimeout via a private bunIdleTimeout() (#511), but that mapping has no test on either runtime and no test/bun script asserts the Bun shell honors the configured timeout. So the Bun side of this feature shipped unverified.

This was surfaced by an audit of the run-bun-tests.js DENYLIST for "Bun parity missed" gaps. It is the ONLY genuine gap found: every other denylisted entry cites real Bun coverage (listener.mjs, compression.mjs, file-storage.mjs, smoke.mjs, dev-hot-reload.mjs) or is runtime-agnostic (importmap test-ordering, redis env, docs-content app-boot).

Design / approach

Add a cross-runtime assertion for the Bun timeout mapping. Two complementary pieces:

  1. Export bunIdleTimeout from listener-bun.js and add a unit test for the pure mapping (ms to seconds; the documented clamp so the idle timeout stays above the 25s SSE keepalive; the default when no config is set). A unit test on the exported function runs under the Bun matrix automatically, so it is proven on both runtimes.
  2. Assert the wiring: that startBunListener passes the configured requestTimeoutMs through to Bun.serve({ idleTimeout }). Either extend test/bun/listener.mjs (it already boots a real Bun.serve socket) to assert the configured value is applied, or add a focused test/bun/timeouts.mjs.

Alternative considered: leaving it to the node test only. Rejected, because the whole point of #508 parity is that a runtime-specific mapping (node requestTimeout to Bun idleTimeout) is exactly where the two diverge and must be pinned.

Implementation notes (for the implementing agent)

  • Where to edit:
    • packages/server/src/listener-bun.js: bunIdleTimeout(timeouts) is the private mapping (~L346-352); it is consumed at the Bun.serve({ idleTimeout: bunIdleTimeout(timeouts) }) call (~L66). Export bunIdleTimeout so it is unit-testable.
    • Unit test: packages/server/test/body-limit/ (alongside server-timeouts.test.js), or a new listener-bun test. Assert the ms to seconds conversion, the >= 25s SSE-keepalive clamp, and the no-config default.
    • Cross-runtime: extend test/bun/listener.mjs (it boots startServer on a real socket and runs under BOTH node and bun) to assert the configured timeout reached the shell, OR add test/bun/timeouts.mjs wired into the CI bun job + scripts/run-bun-tests.js expectations.
  • Landmines:
    • bunIdleTimeout is currently private; exporting it is the cleanest way to get matrix (cross-runtime) coverage of the mapping logic without booting a socket.
    • Do NOT un-denylist server-timeouts.test.js from the matrix; it asserts node:http server fields that do not exist on Bun.serve. The Bun coverage is the NEW mapping test, not that file.
    • Bun.serve idleTimeout is in SECONDS and is a single value (no separate headers/keepAlive); the node side is three millisecond fields. The mapping is intentionally lossy; the test asserts the documented contract, not field-for-field equality.
  • Invariants to respect: AGENTS.md cross-runtime parity (Support both Bun and Node runtimes (first-class create + run) #508) and the new Bun-parity gate (.claude/hooks/require-bun-parity-with-runtime-src.sh, which would now BLOCK a listener-bun.js change with no test/bun test). Invariant release: bump core/server/cli versions, honest engines fields #11 in any new prose.

Acceptance criteria

  • bunIdleTimeout is exported and unit-tested (ms to seconds, the >= 25s clamp, the default), so the mapping runs under the Bun matrix.
  • A cross-runtime test (test/bun/listener.mjs extension or test/bun/timeouts.mjs) asserts the Bun shell applies the configured requestTimeoutMs to Bun.serve idleTimeout.
  • The new test fails if the mapping is reverted (counterfactual).
  • Runs green on both node and bun.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions