# Statum Model ## Statum Frames A statum frame consists of a JSON object with three keys: - `content`: a string containing the literal content of the frame. - `signer`: a string containing a signer ID. - `signature`: a base64 encoded signature verifying the content authored by the signer. ## Statum Slot - `key`: a server issued ID for the slot. - `scope`: a string value that can be one of: - `"device"`: persists between browser sessions. - `"session"`: persists within the browser session (e.g. between tabs). - `"flow"`: persists only within the current tab, while the tab remains on the site (e.g. persits on between navigation) - `"page"`: persists only while the current page is loaded (e.g. clears on navigate). - `"transient"`: does not persist, will never get sent back to the server - random or `null` key each time. - `type`: an application defined type name. ## Statum Snapshot A statum snapshot captures an aspect of the application state at a particular point-in-time. It is usually wrapped in a frame, which must be retained if it is to be sent back to the server after the `transmit_after` time. It contains: - `as_at`: an ISO 8601 string representing the time the snapshot was authored. - `slot`: a slot object (above) - `transmit_after`: an ISO 8601 string representing the time the slot will no longer be cached by the server and the application will need to send the snapshot. `undefined` if this is a unidirectional snapshot that never needs to be sent to the server. If it equals `as_at`, then the snapshot must always be sent. - `invalid_after`: an IOS 8601 string representing the time this snapshot should be considered invalid and not used. - `private`: a base64 encoded string of data only readable by the application server. - `public`: a JSON object with application-defines key/values. ## Statum Action - `uri`: The URI to request. - `method`: The HTTP verb to use. - `private`: A base64 encoded string of data only readable by the application server (can be `undefined`) ## Statum Directive - `type`: One of - `"navigate"`: Used to redirect the frontend to a new URI. - `"post"`: Used to cause the frontend to POST some data to a URI. - `"set"`: Used to set a slot to a new snapshot. - `"clear"`: Used to clear a slot. Depending on the type, it will have other properties. ### Navigate Directive - `uri`: The URI to navigate to. ### Post Directive - `uri`: The URI to perform a form post to. - `data`: Key/value pairs for form data. ### Set Directive - `snapshot_frame`: A frame containing a snapshot. ### Clear Directive - `slot_id`: The ID of the slot to clear. # Statum HTTP API ## Entrypoint Endpoint `GET /_statum/entrypoint`: Get initial diretives based on the URL. has query param `uri` set to the browsers current `window.location`. Returns a JSON array of Statum Directives. ## Slot Post Endpoint `POST /_statum/slots`: Send a saved state snapshots frame to the server once it has reached its `transmit_after` time window. Sent as a JSON array of Statum Frames. Returns a JSON array of Statum Directives. ## Action Endpoints The URLs of action endpoints are entirely defined by the action iteself (in the `uri` property). An additional `X-Statum-Private` header should contain the `private` data of the action if present. Returns a JSON array of Statum Directives. ## Request Headers All HTTP API requests must have a `X-Statum-Slot` header for each relevant slot snapshot in scope. There are two variations of this header: - For slots that have a snapshot that are within the `transmit_after` time window, an `as_at` timestamp is sent, e.g. `X-Statum-Slot: key=d3cceb88-c211-41ee-a0b1-6a93f3b6331b; as_at=2026-07-06T07:33:02.332Z`. - For slots that have a snapshot which has a `transmit_after` timestamp equal to its `as_at` timestamp, the frame is sent in base64, e.g. `X-Statum-Slot: eyAiY29udGVudCI6ICIuLi4uIiwgInNpZ25lciI6ICJzMSIsICJzaWduYXR1cmUiOiAiZXlBaVkyOXVkR1Z1ZENJNklDSXVMaTR1SWl3Z0luTnBaMjVsY2lJNklDSnpNU0lzSUNKemFXZHVZWFIxY21VaU9pQWlJbjA9In0=` Before an HTTP request is sent, if one or more slot snapshots's `transmit_after` timestamp is in the past, and it is not equal to its `as_at` timestamp, a pre-flight request should be made to the slot post endpoint, which will in turn provide updated snapshots and a new `as_at` timestamp. # Javascript API The Javascript API provides access to the state and actions via the global `statum` object. It automatically handles pre-flight requests, headers, and executing directives from the server. ## Managing State State snapshots can be cleaned up via `statum.clear("typeName")`. All snapshots can be cleared via `statum.clear()`. ## Reading State State can be read via `statum.read("typeName")` which returns the snapshot object currently associated with the type "typeName". To get the current frame of a type, use `statum.getFrame("typeName")` which will return the frame object that encapsulates the snapshot. A full state object can be generated via `statum.state()` which returns a javascript object containing properties named after each type name that currently has a state, thier values being the current snapshot object, e.g. `{ "typeName": {"as_at": "...`. ## Performing an Action To perform an action, use `statum.act(action)` where `action` is a Statum action. Use `statum.act(action, data)` to send parameters along with the request. This is encoded as query params when `action.method` == `GET`, or encoded as form encoded otherwise. `statum.act` returns a promise which resolves when the request has completed and all directives have been run. The act function can also be used with a string referring to an action name ## Reacting to State Callbacks can be attached to statum using `statum.addStateListener("typeName", callback)` which calls `callback` with an object containing: - `type`: the type name - `frame`: the frame (can be `null` if state has been cleared) - `snapshot`: the snapshot object (can be `null` if state has been cleared). It is fired whenever a state of the specified type is set or cleared. # HTML API The Javascript library also has some functionality inspired by HTMX using attributes prefixed with `stm-`. Ususally their values refer to something along the JSON object path of the current `statum.state()`. The following attributes are supported: ## Text binding The attribute `stm-text` binds the element's `innerText` to the specified state value, e.g. ``. ## HTML binding The attribute `stm-html` binds the element's `innerHTML` to the specified state value. ## Conditional display The attribute `stm-if` adds or removes the element from the DOM depending on the expression inside the statement, e.g. `
` or `
` The attribute `stm-else-if` can only exist as the next sibling of an element with either `stm-if` or `stm-else-if` and has the same type of value as `stm-if`. The attribute `stm-else` can exist only as the next sibling of an element with `stm-if` or `stm-else-if`. ## Conditional classes The attribute `stm-class.x` where `x` is any class name can be used to toggle classes on or off with a predicate, e.g. `
`. ## Actions The attribute `stm-action` binds the elements primary action (e.g. `onclick` for buttons, or `onsubmit` for forms), overriding their default behaviour to instead perform the statum action referenced (via state path). For example ``. It can be used with `stm-data` to also provide additional data to the action, e.g. ``. The attribute will also disable the element (and any children) while the action is being processed, and restore the original state once completed (or on error). In addition to this, the attribute `stm-busy-class` can be used to specify one or more css classes to apply during this time. When used on a form, any form inputs are sent in the JSON or query string of the action, bound by their `name`, as they would for a regular native form submission. ## Loops the attribute `stm-for-x-in=` attribute (where `x` can be anything) repeats the *current* element multuple times for each item in the referenced array, and makes available the specified variable name in all `stm-` attributes in its children, and for all other `stm-` attributes on itself. For example: ```html

```