mesofact 0.8.29

mesofact — Rust-native web framework facade. Default = lean V8-free Rust-handler harness (bind/serve + /__mesofact/health + graceful shutdown); opt into render/ssr/build via features. Re-exports mesofact-core (serve/proxy engine).
Documentation
# __PROJECT_NAME__

A mesofact project. Two binaries, no package manager, no Node.

## Run it

```sh
mesofact-dev . --port 3000
```

That is the whole loop. `mesofact-dev` builds the project in-process on
startup, serves it, and rebuilds on every edit under `src/`. The first build
materializes `node_modules/` from the committed `bun.lock` — it fetches
tarballs from the npm registry and verifies each against the sha512 integrity
in the lock, which is why it needs no `npm`, `bun`, `pnpm` or `node` anywhere
on `PATH`.

```sh
curl -s localhost:3000/                        # static — identical every time
curl -s 'localhost:3000/api/hello?name=you'    # {"hello":"you","at":…,"method":"GET"}
curl -s -X PUT localhost:3000/api/hello        # 405 — the handler owns its status
```

## The version pin

`.mesofact-version` selects which mesofact this project builds and serves
with. The shim on your `PATH` reads it on every invocation, so `mesofact` and
`mesofact-dev` in this directory are always the pair that version names —
switch with `mesofact-vm use <version>`, or per-project by editing that file.

The pin covers the **JS set too**. A mesofact version pins react, react-dom,
the `@mesofact/runtime` barrel and the matching `@types/*` at exact versions,
tested together per release, which is why `bun.lock` is committed and was
never resolved on your machine. One dial, honest for the binaries and for the
app they serve.

Reaching outside that set — adding an arbitrary npm package — is supported but
carries no compatibility promise. It is the escape hatch, not the main road.

## Layout

| path | what it is |
|---|---|
| `mesofact.routes.ts` | The whole routing surface. A **build input**, not runtime config: it decides what is prerendered, what is bundled for the server, and which prefixes SSR owns. Changing a route's mode means rebuilding. |
| `src/home.tsx` | `mode: "static"` — exports `render: RenderFn`, runs at build time, returns `{ html, cache }`. |
| `src/api.ts` | `mode: "ssr"` — a Fetch handler run per request in a V8 isolate. Owns status, headers, body. |
| `src/Page.tsx` | The shared component both modes render through. |
| `bun.lock` | The shipped, pre-resolved lock. Nothing on this path resolves. |
| `vendor/mesofact-runtime/` | `@mesofact/runtime` **types**, vended at your mesofact version. The barrel that runs is compiled into the binary; imports of it stay external through every bundler path. |
| `workload.toml` | Read by the deploy path only. The local loop ignores it. |

## Typechecking

`npm run typecheck` (or `bun run typecheck`) runs `tsc --noEmit`. TypeScript
is in the curated set and installs with everything else — but running it does
need a JS runtime, so this is the one command in this README that wants `node`
or `bun` present. The build and the dev server do not.