npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xlaunch/host-webserver

v0.2.0-beta.1

Published

Web route-registration plugin: HTTP and upgrade routes, index transform taps, and static dist fallback; knows no harness concepts

Readme


description: "The web GUI host's HTTP server: named-route and upgrade registration, index transforms, and the single fallback seat that serves the Web shell's SPA dist." kind: "package-reference"

@xlaunch/host-webserver

Summary

Browsers reach the web GUI over HTTP through xlaunch-host-webserver: a node:http server where other plugins register named routes, upgrade routes, index startup inputs, and one fallback handler. It knows no harness concepts and serves no files — the /api bridge, plugin bundles, the HMR event stream, and the SPA dist belong to the plugins that register them. Route matching is fixed: exact over the whole table, then longest prefix, then the fallback handler. It serves browsers only; Electron loads dist over file:// and carries fetch over an IPC bridge.

Table of Contents


Use this package

Compose the webserver as the HTTP transport of a browser-facing host, then let the feature plugins claim their routes. Activation listens immediately; registration order carries no request-facing semantics because named routes compose to be disjoint.

Minimal configuration

- name: '@xlaunch/host-webserver'
  config:
    host: 127.0.0.1
    port: 3000

host accepts exactly two values: 127.0.0.1 (default posture, loopback only) and 0.0.0.0 (deliberate network exposure — the server carries no TLS, authentication, or origin policy of its own). port 0 requests an OS-assigned port; ctx.webServer.port reads the listening port afterwards.

Set compression: 'gzip' to wrap eligible socket-backed responses without changing route APIs. The client must accept gzip and the media type must be compressible; known response lengths below compressionThresholdBytes remain uncompressed, while unknown-length streams are eligible immediately. Existing encodings, Cache-Control: no-transform, range responses, SSE, ZIP, and the packaged .gz Worker image remain unchanged. The shipped Web bundle uses compression level 1 with a 1024-byte threshold; other compositions default to no compression.

Registering routes

register(route) adds a named exact or prefix HTTP route, registerUpgrade(route) adds an upgrade route for an exact pathname, and both return a disposer that removes the registration. A duplicate path within either table throws — route patterns are a composition-level contract, so a collision is a misconfiguration. HTTP matching is exact over the whole table, then longest prefix, then the fallback handler; upgrades match exactly and unmatched connections are closed.

The fallback seat

registerFallback(handler) claims the one handler for every request no named route matches. A second registration throws; while no fallback is registered the server answers 404. In the shipped Web composition the SPA dist server owns the seat and calls renderIndex on every index response it renders.

Index startup inputs are two layers. collectIndexInjections() gathers a fresh injection table — one webserver/index-inject emit per call, each subscriber pushing its current rows — and renderIndex(html) renders those rows into the index.html body before applying the raw tapIndex(transform) transforms in registration order. A script-preload row renders an advisory classic-script preload link. Static deployments carry the same rows in their boot payload. applyIndexTaps(html) applies only the raw transforms; it is the escape hatch for markup no row expresses.

Behavior under failure

A listen failure (for example EADDRINUSE) rejects plugin initialization with the bind diagnostic. An HTTP request whose handler throws is answered 400 — or the socket destroyed when headers are already out — and logged as a warning; it never exits the process. An upgrade-handler exception or upgraded-socket transport error logs a warning and destroys its socket.


Understand the implementation

Design concept

The package is a plain route registry with no harness vocabulary: WebServer extends Cordis Service and holds three route tables plus the fallback slot, the raw index-tap list, and the webserver/index-inject event the index renderer gathers rows through. Index rendering composes two layers per response: renderIndex renders the fresh injection table, including advisory script-preload rows, into the body, then applies the raw taps in registration order; applyIndexTaps runs the taps alone. The upgrade handler owns the protocol handshake and connection contents; the webserver only delivers the raw socket and request. host and port getters expose composition-time facts other plugins adapt to (for example the directory-picker chooser).

Matching and lifecycle

match(pathname) consults the exact table first, then walks the prefix table for the longest match, then the fallback. Activation ([Service.init]) listens immediately; disposal starts close() and closeAllConnections(), destroys every tracked upgraded socket, and returns only after the server and those sockets have closed. Node does not include upgraded sockets in closeAllConnections(), so the service tracks them explicitly.

Source map

| File | Role | |---|---| | src/index.ts | WebServer service: route tables, fallback seat, index rendering, matching, lifecycle | | — | No runtime invariant companion is published; route registration and disposal mutate one route table through the same service, so a register/dispose probe only re-executes the implementation. Real routing and HMR tests own the behavior. | | src/injections.ts | Structured IndexInjection rows and renderIndexInjections row rendering |


Further Exploration

Read these when the server contract is not enough: the subsystem reference, then the fallback owner and the layering decision behind who registers which route.


Model Experience

None, as the HTTP carrier bridges browser and API handler and registers nothing model-facing.

KV Cache effect

None; this package neither assembles nor sends a provider request.

Known Limitations and Deferred Work

These limits define where the server is intentionally minimal. They are current package constraints, not a task backlog.

  • No server-wide TLS, authentication, or origin policy — route owners such as xlaunch-client-connection enforce their own request policy. Binding a non-loopback address still exposes unprotected routes and static assets to that network.
  • Socket options are fixed — config selects the bind host and port, while backlog and other socket settings remain internal until a deployment needs them.

Dev Note

None.