# Getting Started with Statum ## What is Statum Statum is a stateful web application framework for Vala, built on top of [Astralis](https://github.com/search/astralis) (HTTP server), [Invercargill](https://github.com/search/invercargill) (data structures / JSON), and [Inversion](https://github.com/search/inversion) (dependency injection). It provides: - **Server-rendered HTML pages** composed from templates and fragments at build time (`statum-mkpstm`), precompressed with gzip/zstd/brotli and served with encoding negotiation and ETags. - **Client-carried state** — signed and (for private data) encrypted snapshots that the browser holds and sends back, so the server is stateless between requests (no session store, no database for ephemeral state). - **Entrypoint hydration** — after a page loads, a lightweight JS client fetches directives that set the initial slot data and bind the DOM. - **GUID actions** — POST/GET handlers auto-mapped to `/_statum/action/{guid}`, invoked from the client via `stm-action` attributes, carrying strongly-typed private data. - **Realtime updates** — a SharedWorker-backed SSE channel pushes slot changes to subscribed tabs. ### Architecture at a glance ``` Browser Server ─────── ────── GET / ──────────────────────► StatumPage (precompressed HTML) page loads, statum.js boots GET /_statum/entrypoint ────► StatumEntrypoint → directives (set/clear/...) client applies directives client binds stm-* attributes POST /_statum/action/{guid} ► StatumAction → directives (with X-Statum-Slot headers) (mutate state, push to channels) ``` --- ## Quick Start Examples ### 1. A page with an entrypoint **`home.html`** — the page template, composed with a layout: ```html / main

Counter: 0

``` **`main.html`** — the layout template: ```html main My App

My App

``` **`HomeEntrypoint.vala`** — hydrates the page: ```vala public class CounterPublic : Object { public int value { get; set; } public Model.ActionDto bump { get; set; } } public class HomeEntrypoint : StatumEntrypoint { public override async DirectiveBuilder handle() throws GLib.Error { var counter = new CounterPublic(); counter.value = 0; counter.bump = action_registry.author_private(new BumpPrivate()); return directives().set_typed("counter", Scope.PAGE, counter); } } ``` **`Main.vala`** — wires it all up: ```vala void main(string[] args) { var app = new WebApplication(8080); app.add_module(); var statum = app.configure_with(); statum.add_page(); // route from statum.action(); // GUID auto-assigned app.run(); } ``` ### 2. A guarded page ```html /dashboard main ``` The guard redirects unauthenticated visitors to `/` before the entrypoint loads. --- ## HTML Templates Statum pages are HTML files processed at build time by `statum-mkpstm`. ### Build-time directives (`pstm-*`) All `pstm-*` elements **must appear inside ``** (except `pstm-content` and `pstm-fragment`, which live in ``). | Directive | Where | Purpose | |---|---|---| | `/path` | head | The page's route. **Required.** Supports templates: `/cats/{species}`. | | `main` | head | Wraps this page in the named template (by ``). | | `main` | head | Names this file so pages/fragments can reference it. | | `` | head | Page title, merged up the template chain. | | `` | body (template) | The outlet where the child page's body is inserted. | | `` | body | Inlines a fragment (component) by name. | | `pstm-materialise-as="div"` | `` attr | When this body is composited into a template or fragment, it is wrapped in the named element. | | `pstm-res-src="logo.png"` | any attr | Rewrites to `src="/_statum/resource/logo.png"`. Also `pstm-res-href`, etc. | ### Head merging When a page is composed into a template (or a fragment is inlined), the child's `` children are **merged** into the parent's ``. This lets pages, templates, and fragments each declare their own `