Repository navigation
MESH v0.15.0
MESH v0.15.0 release notes
Prepared 2026-10-23 (not yet published: v0.14.0 is the latest release).
v0.15 gives a component state of its own for one occurrence of it: whether a disclosure is open, which tab is chosen. A manifest, a program and a snapshot that use none of it compile and render as they did in 0.14.0: the same templates, the same render trees byte for byte, the same patches.
Highlights
- A component's
unit."unit": { "state": { "open": { "type": …, "default": false } }, "commands": { "toggle": { "parameters": [] } } }in a component's manifest entry. The state names join the component's scope (read-only) and the commands join its commands, so a template readsopenand runstoggle()like anything else and checking needs nothing new. A name that is already taken ismanifest-unit-clash. See the manifest reference. - The state is an input beside the snapshot.
render,update,updateChangesanddispatchtake the state the host holds for the occurrences it has changed (render_units,update_with_units,update_changes_units,dispatch_from_unitsin Rust;unitsin JavaScript). An occurrence with no entry has the defaults, which is also what the first render on a server and in a browser use, so they agree. The runtime holds none of it, so a render is still a function of its inputs and the equivalence law ofupdateholds with units in it. See Units. - A render lists the occurrences it met (
render.instances: the key, the component, the state the template saw, the fields the caller owned), so a host can keep the state of the occurrences that exist and let go of the rest. An occurrence's key is its place in the program, by the item's declared key inside a repeat: a re-sorted list keeps the state with the row; hiding and showing, or a changed key, is a new occurrence. - A unit's command names its occurrence. The intent gains
instanceand, when the caller owns a field,controlled. The host runs the unit's transition on the occurrence's state and renders again. controllablefields. A prop of the same name, when the caller writes it, is the value, and the unit's change to it is not applied: one copy of the value, owned by whoever wants it.raise(render, instance, event, payload)resolves an event a unit announces to the handler its caller bound to it.- An update does not keep a part that a unit under it has changed. The state of the units below a part is one of its inputs.
- New diagnostics:
manifest-unit-clash,runtime-unknown-instance,runtime-unknown-event. - Conformance vectors:
units/, with a committed tree and list of occurrences for each step, run natively and through the package.
Compatibility
- API: additive. The Rust
Intentgains two fields, andComponentgainsunit(both were open to growth:Componentisnon_exhaustive). - Manifest: a manifest with a
unitis refused by an older MESH (manifest-unknown-property); one without is read as before.manifest-v1still means what it meant. - render-v1, render-patch-v1, template-v1/v2: unchanged.
- WebAssembly: the module's exports are internal and changed (units in, occurrences out,
mesh_raise);@valancex/mesh-runtimeand its module are one version, as always. - Size: the module grows about 3.5 percent (gzipped 234,818 to about 243,000 bytes).
Release order
MESH 0.15.0 (its nine packages), NEXUS 0.14.0, PORT unchanged, then the VALANCE packages, which depend on MESH 0.15 and NEXUS 0.14 for units.
Verification
cargo test --workspace, cargo clippy --all-targets -- -D warnings, cargo fmt --check; the runtime package's tests (including the browser test with MESH_CHROMIUM), the compiler package's tests, and the conformance package's. Each new rule was shown failing against a deliberate wrong value: the update that keeps a part when a unit under it changed (the test fails when the check is removed), a reorder (the committed vectors), a clash of names (the fixture), and a state the manifest forbids (the diagnostic).