Skip to main content

Module app

Module app 

Source
Expand description

The library-tier dev entry point — serve_app, the counterpart to mesofact::serve_app for a consumer whose routes are Rust handlers.

This is the mesofact_dev::serve(app::router()) that W225 §2’s Consumer DX sketch promised and that nothing implemented (R832-T1). The two thin bin targets a library-tier project carries differ by one identifier:

ⓘ
// src/bin/yah-dashboard.rs      — the binary CI ships
mesofact::serve_app(yah_dashboard::router(), addr).await

// src/bin/yah-dashboard-dev.rs  — the binary you run locally
mesofact_dev::serve_app(yah_dashboard::router(), addr).await

§What the dev half of a library-tier consumer actually is

R832-T1 existed because this was an open design question, and the answer is narrower than the standalone tier’s dev binary. Recorded here rather than in a doc, because the next person to add a dev affordance needs it:

The watcher and live-reload do not carry over, and cannot. Both are functions of a built dist/ tree: crate::Watcher re-runs the bundler and rotates dist into .mesofact-dev/gen-N, and the SSR pool is re-spawned against the new generation. A library-tier consumer has no such tree — its routes are Rust functions, and the only edit that changes one is a .rs edit, which requires re-linking the very process that would have to perform the reload. No in-process affordance can close that loop. The loop is cargo watch -x 'run --bin <name>-dev', and it lives outside the binary by necessity, not by omission.

The dev object store does carry over, and is the whole of the difference. A handler that reads or writes R2 builds its store from environment coordinates. In prod those point at Cloudflare R2; in dev a running yah camp supplies a local dev-tier S3 driver and injects its coordinates (R584-T1, W265) — precisely the “local pond emulation” W225 §2 puts in this crate to avoid re-deriving per consumer. DevServer::start resolves the store (DevStore::resolve — the camp’s when a camp injected one, an embedded surface otherwise), DevServer::export_env republishes them under the R2_* names this process’s own handlers expect, and .mesofact-dev/s3.json carries them for out-of-process tooling (aws s3 --endpoint-url …, a test harness).

So mesofact_dev::serve_app is mesofact::serve_app plus a local R2 and a banner. The smallness is the finding, not a shortfall. What the two-bin pattern buys is the link-graph boundary (W225 §2, “always-release, two-binary pattern”) — prod clean by construction because its dependency closure cannot reach this crate — and that boundary is worth having on day one, when the dev side adds a single service. Every dev affordance added here later reaches consumers without any of them changing a line.

Not implemented, and deliberately not stubbed: permissive CORS and verbose error overlays. W225 §2 lists both among the dev affordances, but neither exists anywhere in mesofact today (no tower_http::cors use in either crate), so there is nothing to lift — writing them here would be new product, not an entry point over existing behaviour.

@arch:see(.yah/docs/working/W225-mesofact-consumer-deployment-model.md)

Structs§

DevServer
The dev-tier ambient services, started and ready to serve a caller’s Router.

Constants§

DEV_STATE_DIR
Directory, relative to a project root, that holds dev-only scratch state — the S3 surface’s backing store and its discovery file. The standalone tier’s mes dev uses the same name, so a project that starts standalone and grows a Rust half keeps one .gitignore line.

Functions§

serve_app
Start the dev-tier services, publish their coordinates into the environment, and serve app until Ctrl+C or SIGTERM. The dev counterpart of mesofact::serve_app, and the whole body of a library-tier project’s src/bin/<name>-dev.rs.