writeonce/docs/examples/writeonce-framework
shoney.arickathil a1f521ba9f feat(examples): framework skeleton + web-app scaffold (iter 16 Task 1)
- docs/examples/writeonce-framework: library project (no fn main) — wo.toml,
  README (what it is + the honest v1 limits + the proxy TLS/h2 story), and
  http/types.wo: pub Req/Resp records + the response builders (ok_text/
  ok_json/created/not_found/bad_request/unauthorized/conflict/server_error/
  redirect). Typechecks + emits entry-less via woc --emit (1767-byte image).
- docs/examples/web-app: manifest with the real [deps] entry (future GitHub
  URL as documentation; the gate substitutes a file:// remote) + README
  (routes table, run instructions, nginx h2-in-front sketch). Code lands
  with Task 4.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:43:19 +02:00
..
http feat(examples): framework skeleton + web-app scaffold (iter 16 Task 1) 2026-08-19 19:43:19 +02:00
README.md feat(examples): framework skeleton + web-app scaffold (iter 16 Task 1) 2026-08-19 19:43:19 +02:00
wo.toml feat(examples): framework skeleton + web-app scaffold (iter 16 Task 1) 2026-08-19 19:43:19 +02:00

writeonce-framework

A web framework written in writeonce, consumed as a [deps] dependency (iteration 15). Spec: docs/superpowers/specs/2026-08-18-web-framework-design.md §B.

[deps]
writeonce-framework = { git = "https://github.com/shoneyj/writeonce-framework", rev = "v0.1.0" }

What it is

  • HTTP/1.1 keep-alive server core (http/): request parsing (Content-Length bodies), response serialization, a blocking serve loop that answers 400 to malformed requests, 500 to trapping handlers (and survives), closes every fd, and honors SIGTERM.
  • Router (router/): method + path table with :param captures into req.params; first match wins; no match is the framework's 404.
  • Handlers without closures: the language has no function values by doctrine, so a route handler is a class satisfying the Handler interface (fn handle(req: Req) -> Resp), dispatched structurally — a non-conforming handler is a compile error (WO-E205). Middleware is its own interface (fn before(req: Req) -> ?Resp; nil = continue, a Resp short-circuits).
  • Data layer for free: handlers use @table + the query surface directly — durable, compiler-checked persistence in the same binary. No ORM, no database server.

Honest limits (v1, all deliberate)

  • Single-threaded, blocking — one request at a time. Concurrency arrives underneath this same surface with the shard/fiber iterations (8/11).
  • TLS: none, anywhere. Deploy behind nginx/caddy; the proxy terminates TLS+ALPN and gives browsers HTTP/2 while this backend speaks HTTP/1.1 keep-alive. See the web-app sample's README for the nginx sketch.
  • Content-Length bodies only (no chunked encoding), no WebSockets/SSE, JSON-first (no templates).

The consuming sample

docs/examples/web-app — a small storefront importing this framework through [deps]. Its acceptance (just web-app) exercises the whole chain: fetch → lock → build → serve → durable restart.