Repository navigation
A small feature release with one job: WebSocket endpoints on the app's own
port. RestServer.upgrade() lets a ws endpoint live beside the REST routes
on the same port and origin, without reading a private field or opening a
second listener (#60).
It is opt-in — an app that registers no upgrade path behaves exactly as it did
on 0.12.0.
✨ New
RestServer.upgrade(path, handler, {close?}) — @agentback/rest
Node never routes an HTTP Upgrade request through the request handler; it
emits a separate 'upgrade' event on the server with the raw socket, and
RestServer kept that server private. upgrade() is now the supported seam,
on both the Express and native listeners:
import {WebSocketServer} from 'ws';
const server = await app.restServer;
const wss = new WebSocketServer({noServer: true});
server.upgrade(
'/ws',
(req, socket, head) => {
// Authenticate here: no REST middleware, auth or rate limiting runs.
wss.handleUpgrade(req, socket, head, ws => wss.emit('connection', ws, req));
},
{close: () => wss.close()},
);
await app.start();- Exact pathname match (query ignored,
basePathnot applied). Register
beforestart()— afterwards it throws. It returns a remover, which
works at any time. - Nothing changes until you register a path. The
'upgrade'listener is
installed only when at least one path exists; with none, Node keeps
downgrading upgrade requests to plain requests, as before. - Once a path is registered, an upgrade on another path gets
404and a
malformed request-target400. Both are parsed inside atry/catch,
because a throw escaping an'upgrade'listener is an uncaught exception
that would kill the process before any auth ran. - A handler that throws or rejects loses its socket; the error is logged
and the process stays up. stop()awaits eachclosehook, then destroys every accepted socket
still open. An upgraded socket is no longer an HTTP connection, so without
that sweepserver.close()was measured to wait on it forever. A test pins
the sweep and fails when it is removed.- Handlers are not middleware — authentication is theirs.
- Node listener only: nothing is accepted under
listen: falseor on a
fetch host (fetchHandler(), Workers, Bun, Deno).
New exported types: UpgradeHandler and UpgradeOptions. ws is a
devDependency of @agentback/rest (for its tests) — bring your own
WebSocket library; no runtime or peer dependency was added.
No other package changed behavior in this release; the lockstep bump carries
them at 0.13.0 unchanged.