Skip to content

HTTP Usability: Router + improved exec#71

Merged
cs01 merged 5 commits intomainfrom
http-usability
Mar 2, 2026
Merged

HTTP Usability: Router + improved exec#71
cs01 merged 5 commits intomainfrom
http-usability

Conversation

@cs01
Copy link
Owner

@cs01 cs01 commented Feb 28, 2026

HTTP Usability: Router + improved exec

Adds a Hono-style Router class and makes re.exec() work correctly for runtime-constructed regex patterns (previously fell back to a hardcoded group count of 9).

What's new

Router (src/router.ts)

Express/Hono-style router that compiles all routes into a single combined regex at first dispatch. Supports :param segments and * wildcards.

import { Router, Context } from "./src/router";

const app = new Router();

app.get("/api/users/:id", (c: Context) => {
  const id = c.req.param("id");
  return c.json('{"id":"' + id + '"}');
});

app.post("/api/users", (c: Context) => {
  c.status(201);
  return c.text("Created");
});

app.notFound((c: Context) => c.status(404).text("Not Found"));

httpServe(3000, (req) => app.handle(req));

Router methods: get, post, put, delete, all, notFound, handle, compile

Context API:

  • c.req.param(name) — URL param
  • c.req.header(name) — request header
  • c.req.method, .path, .body, .contentType
  • c.status(code) — chainable
  • c.header(name, value) — chainable
  • c.text(body) / c.json(body) / c.html(body) / c.redirect(url)

HTTP utilities (src/http-utils.ts)

import { getHeader, parseQueryString, parseCookies } from "./src/http-utils";

getHeader(req.headers, "Authorization");  // "Bearer abc"
parseQueryString("a=1&b=2");              // Map { a→1, b→2 }
parseCookies("session=abc; user=bob");    // Map { session→abc, user→bob }

re.exec() now works for runtime-constructed patterns

Previously exec on a new RegExp(str) pattern used a hardcoded group count of 9. Now it reads re_nsub from the compiled regex at runtime via cs_regex_exec_dyn in c_bridges/regex-bridge.c — correct for any pattern regardless of how it was constructed.

const re = new RegExp("([a-z]+)/([0-9]+)");
const m = re.exec("rooms/42");  // ["rooms/42", "rooms", "42"]

Native compiler: lambda type propagation fix

Fixed a bug in src/parser-native/transformer.ts where lambda parameters passed to class methods didn't get types propagated from the call site. This caused router handler callbacks ((c: Context) => HttpResponse) to fail in the native compiler.

Files changed

File Change
src/router.ts New — Router and Context classes
src/http-utils.ts New — getHeader, parseQueryString, parseCookies
c_bridges/regex-bridge.c Add cs_regex_exec_dyn
src/codegen/types/objects/regex.ts Add generateRegexExecDyn
src/codegen/expressions/method-calls.ts Route exec through dynamic C bridge, remove static group count
src/codegen/expressions/calls.ts Lambda type propagation
src/parser-native/transformer.ts Fix lambda param types in method calls
tests/fixtures/network/router-params.ts Router test fixture
tests/fixtures/regex/regex-exec-dynamic.ts exec with runtime pattern test

Test plan

  • npm test — router-params and regex-exec-dynamic fixtures pass
  • npm run verify — full self-hosting chain passes
  • Manual: chad run examples/http-server.ts — param routes respond correctly

@cs01 cs01 changed the title add execDyn: dynamic regex exec returning string[] via c bridge HTTP Usability: Router + execDyn Mar 2, 2026
@cs01 cs01 changed the title HTTP Usability: Router + execDyn HTTP Usability: Router + improved exec Mar 2, 2026
@cs01 cs01 merged commit 0a13a00 into main Mar 2, 2026
12 checks passed
@cs01 cs01 deleted the http-usability branch March 2, 2026 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant