wooter
@bronti/wooter
Section titled “@bronti/wooter”[!WARNING] wooter is beta and WIP. Core ideas are implemented, but rough edges still exist. Avoid high-impact production usage until
v100.0.0.
[!NOTE] wooter uses epoch semver.
wooter is a TypeScript router with a different mental model than Express-like routers.
Why Wooter
Section titled “Why Wooter”- Promise-separated response lifecycle: your handler execution and the request response are tracked separately.
- Fetch-native runtime model: use
router.fetch(request)anywhere the Fetch API exists. - Structural routing with
chemin: routes are patterns, not path strings. - Cooperative middleware pipeline: middleware composition is explicit and type-safe.
Quick Start
Section titled “Quick Start”import { c, Wooter } from "@bronti/wooter"
const router = new Wooter()
router.route(c.chemin(), "GET", ({ resp }) => { resp(new Response("hi"))})
router.route(c.chemin("user", c.pNumber("id")), "GET", ({ params, resp }) => { resp.json({ id: params.get("id") })})
router.route(c.chemin("after"), "GET", async ({ resp }) => { resp(new Response("sent")) await Promise.resolve() console.log("this runs after responding")})
export default routerCore Concepts
Section titled “Core Concepts”-
Structural routing with
chemin: Route definitions are composed from typed path pieces. Matching and parameter typing come from the pattern itself. -
Execution and response are separate: A handler must resolve exactly one response with
ctx.resp()before completion. You can still perform work after response resolution. -
Middleware must be cooperative: Middleware should call
.next()or.forward()unless it resolves a response itself. It should not swallow errors it does not handle. -
safeExit()is a control-flow signal: Usectx.safeExit()only afterctx.resp()when you intentionally want to stop execution immediately.
Lifecycle And Error Timing
Section titled “Lifecycle And Error Timing”Errors before response resolution reject router.fetch() and belong to the request lifecycle.
Errors after response resolution cannot be attached to the request anymore and are routed to the router catchStrayErrors sink.
By default, stray errors are rethrown, which may crash your process if unhandled.
Middleware Rules Of Thumb
Section titled “Middleware Rules Of Thumb”- Do not drop the chain: call
.next()or.forward(), or respond explicitly. - Do not hoard errors: if you catch an error and do not fully handle it, rethrow it.
- Prefer
ctx.safeExit()over throwingControlFlowBreakdirectly in middleware libraries.