Commit Graph
27 Commits
Author SHA1 Message Date
Chris Tate a8484aea07 Address review feedback on request-body streaming 2026-10-23 05:22:01 -05:00
Chris Tate 952e01d2ed Stream request bodies in the Node server adapter 2026-10-23 05:03:12 -05:00
Malte UblandClaude Opus 5.5 9ab876faa9 Compile the @hono/node-server shim under any program's stream types
The shim compiles inside each program that imports the package, and under
some lib and @types/node settings ReadableStreamReadResult<Uint8Array>
lowered as unknown while reader.read() produced a record, so the
buffered-read path refused (SC2003). The shim spells out its read-result
record and types the body reader.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:15:30 -07:00
Chris Tate 1940e06304 Cancel streamed bodies on disconnect and type Response.json headers
A response whose client disconnects while its body streams now cancels the
body's stream when the response closes, as the package does, so the
producer stops instead of being read until it ends. A response that fails
closes too and is cancelled the same way.

Response.json(data, { headers }) with init headers is written from its
Headers, as the package's Response.json passes them on as a Headers object
with the JSON content type added when they lack one. Before, the cached
path wrote only the init record and sent no Content-Type.

The hono-node-server case covers both: Response.json with and without an
init content type, and a client that destroys the response after the first
chunk of an endless stream.
2026-10-22 19:32:49 -07:00
Malte UblandClaude Opus 5.5 9bf76af974 Build @hono/node-server 2.x into scriptc
@hono/node-server replaces the global Request and Response with
lightweight objects and reparents prototypes, tricks that only pay off
under V8 and that native compilation cannot follow. scriptc now compiles
the package from a built-in implementation (shims/hono-node-server/v2.ts)
over node:http and the native Request/Response/Headers: serve,
createAdaptorServer, getRequestListener and RequestError.

Responses are written the way the package writes them, byte for byte on
the wire: the general path (header record in Headers order, Set-Cookie
gathered, default content type, content length for bodies that finish
within the first reads, streamed bodies, error responses) and the
package's cached-response path for a Response that is still exactly its
constructor arguments. The runtime tracks that lightweight state on each
constructed Response (header form, raw plain-record headers, body length;
cleared by body and metadata reads, turned into Headers form by a headers
read) and exposes it to the shim through scriptcResponseLight.

The declaration entry of a shimmed package may now be a .d.mts/.d.cts
file. The npm case hono-node-server drives buffered, streamed, cookie,
header-form, HEAD, error-handler and URL cases against the real package
under Node.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 19:32:49 -07:00
Chris Tate ccfca67aec Fix chalk builder field calls and hot-shots send failures and tcp completion 2026-10-22 10:30:56 -05:00
Malte UblandClaude Opus 5.5 2e297caf99 Log hot-shots' failed final flush through an unknown value
Programs whose Error subclasses define accessors still compile the shim's
close logging.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 05:33:34 -07:00
Malte UblandClaude Opus 5.5 8c9f5cfc9f Free hot-shots' unclosed udp and tcp transports at exit
The socket's error listener captured the transport, so a client that is
never closed (mock mode) kept a cycle the RC audit reports at exit; it
now captures only the listener list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 05:33:30 -07:00
Malte UblandClaude Opus 5.5 88f9ba91eb Format the shims and scope the chalk declaration-merge lint exception
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 05:33:29 -07:00
Malte UblandClaude Opus 5.5 284517accb Call chalk builders with one string through a typed method
A callable class's %call1 method takes a single string argument directly,
skipping the variadic closure's checked-dynamic call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 05:33:29 -07:00
Malte UblandClaude Opus 5.5 cab61904fd Send hot-shots uds metrics through a native Unix datagram socket
Where unix-dgram is installed beside hot-shots, the shim's entry sends
through runtime AF_UNIX datagram calls with the addon's semantics; without
it, uds reports the addon missing as hot-shots does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 05:33:28 -07:00
Malte UblandClaude Opus 5.5 750c817649 Compile hot-shots 8 from a built-in typed StatsD shim
udp over node:dgram (TypeScript may use the send completion-callback
form), tcp over node:net, mock mode, child clients, tags, checks and
events; uds reports the missing unix-dgram addon as hot-shots does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 05:33:18 -07:00
Malte UblandClaude Opus 5.5 51b9bdca11 Compile chalk 5 from a built-in shim with a callable builder class
A class whose merged interface carries a call signature stores its call
behavior in a '%call' field; calls and function-slot coercions read it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 05:33:18 -07:00
Malte UblandClaude Opus 5.5 fc551c4a8b Key weak collections by net sockets and servers, and carry the socket in undici client diagnostics
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 20:06:28 -07:00
Chris Tate 1f4f7d822f Merge main 2026-10-20 19:27:58 -05:00
Chris Tate f284f94827 Merge main 2026-10-20 12:31:50 -05:00
Chris Tate 8c40f92019 Merge main 2026-10-20 11:00:03 -05:00
Chris Tate 8aca6d653d Abort the request of a redirect that fetch follows or rejects
A redirect fetch followed or rejected was marked to drain: its body was
read and dropped until the server ended it, and the abort listener was
already removed. A body that never ends kept the connection busy after
cancellation and stalled a pool of one connection. Following or
rejecting a redirect now aborts its request, so the connection closes.
undici 7 leaves that connection open with its body paused, which stalls
the same pool; the follow-up request here gets a new connection.
2026-10-20 10:48:36 -05:00
Chris Tate 313a984066 Keep regular destination files when fs-extra's copy meets a symlink source
copy and copySync now follow fs-extra's onLink: only a destination that
is itself a symlink is replaced; over a regular file or directory the
symlink call fails with EEXIST and the destination is kept, whatever
overwrite says. The fs-extra corpus program covers both forms.
2026-10-20 10:36:00 -05:00
Malte UblandClaude Opus 5.5 4470bab308 Give the undici shim's Dispatcher an explicit constructor
The implicit constructor forwarded its arguments to EventEmitter's options-taking constructor, which compiles to a deferred runtime fence. Dispatcher takes no options, so it calls super() directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 07:58:16 -07:00
Chris Tate 12221ad7f8 Merge opt/npm-polyfill-shims and apply modes and inode checks in the fs-extra shim
- writeFile and outputFile with byte data and a mode open the file with
  that mode, and writeJsonSync and outputJsonSync pass the mode.
- copySync and moveSync compare source and destination inodes and walk
  the destination's parents, as copy and move do.
- The resolver parity sweep skips the project-import comparison for
  shimmed packages.
- The JSON reader writes the byte order mark as an escape.
2026-10-20 04:52:44 -05:00
Chris Tate 15ae146267 Keep builtin aliases off local bindings and unloaded packages, and validate Host values
- A builtin alias whose replacement starts with a global the file
  declares (`process`, `Array`) keeps the package's own module: the
  replacement would read the local binding.
- A polyfill package the project marks unloaded has no builtin alias, so
  its require throws MODULE_NOT_FOUND.
- The undici shim rejects a Host header value with characters outside
  the header value set (CR, LF and other controls) with `invalid <key>
  header`, as undici 5.19.1 and later and 7.x do, before the client
  writes it into the request head.
- Format lowerer.ts and type-mapper.ts.
2026-10-20 03:51:29 -05:00
Malte UblandClaude Opus 5.5 071024ff56 Hoist classes of an initializer declared last in a shared var statement
build-utils declares its error module's bindings and initializer in one
statement (`var NowBuildError, mapTypoToSuggestion, init_errors = __esm(…)`).
The split pieces follow the statement, so the initializer only needs to be
its last declarator.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 23:17:04 -07:00
Malte UblandClaude Opus 5.5 655ba77eaa Compile the fs-extra shim under @types/node as well
Date-only utimes, literal mkdir recursion and promise-backed readFile
callbacks: the forms that compile natively with either type world.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:51:07 -07:00
Malte UblandClaude Opus 5.5 78f713e572 Implement fs-extra 8-11 as a built-in package
fs-extra builds its exports at load time (computed keys over graceful-fs,
universalify wrappers), which the static CommonJS model cannot follow, so
programs reading its members through the default import failed. The
package-shim registry now maps fs-extra 8.x-11.x to a TypeScript
implementation over node:fs: fs's members re-exported, the wrapped methods
following universalify's callback-or-promise rule over fs.promises, and
the extras (copy, move, remove, emptyDir, mkdirs, ensureFile, pathExists,
outputFile, the JSON helpers and their aliases) with fs-extra's messages.
Its declarations stand in for @types/fs-extra, including the default
import, and a namespace import resolves to the shim. What it does not
implement is not declared, so using it is a type error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:44:48 -07:00
Chris Tate 87895c340e Test the undici shims against a peer that sends malformed responses
The undici5 and undici7 npm cases now also run peers.ts against Node with
the vendored undici: header values with CR or LF, chunk-size lines that
are valid, malformed, overflowing or 1 MiB long, and fetch bodies that
are endless (read once, then cancelled), gzipped, truncated, empty,
corrupt, cut off, aborted after the headers, redirected while endless,
or carry six content codings. The undici5 case leaves out the Host
values, which undici 5.12 writes into the request head, and the two
fetch cases where undici 5.12 differs (six codings, and an endless
redirect, which fails with a TypeError in 5.12).

package-shims.test.ts compiles two programs in copies of the cases: one
reads 64 MiB chunk-size lines and 64 MiB plain and gzipped fetch bodies
from a separate Node peer and checks that RSS stays under 48 MiB (plain
lane), the other checks that the 5.x profile rejects a Host value with
CR or LF with undici 5.29.0's error.
2026-10-19 22:08:08 -05:00
Malte UblandClaude Opus 5.5 a6003ec011 Implement undici 5.x and 7.x as a built-in package
A TypeScript implementation over node:net, node:tls and node:events:
Dispatcher, Client (HTTP/1.1 with keep-alive), Pool, Agent,
buildConnector, request(), errors, the global dispatcher, fetch, Headers
and the diagnostics_channel publications, with per-version behavior.
Differential npm cases run the vendored real undici under Node.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 17:31:38 -07:00