ux-web
The WEB RENDERER of the UX projection (EXPERIMENTAL x/ tier;
#787): one of two peers over cx-x/ux's semantic vocabulary, not the
privileged one. It lowers a semantic tree to HTML/htmx, is the SOLE author
of htmx attributes — restricted to a pinned, fixture-enforced subset with
hx-on excluded permanently, which is what keeps the kernel replaceable
and strict CSP possible — and derives every one of them from a semantic
declaration plus the render context, so no htmx spelling appears in a
semantic tree. Escaping is structural: fragments compose as CXDM trees and
serialize once through the html pack, so there is no interpolation surface.
It also owns the token theme's compilation to a generated stylesheet, the
page shell and its strict CSP, the vendored kernel's SRI manifest, the
out-of-band lowering of the core's semantic patch operations, and the
readback from its own output to the common content normal form on which the
two renderings are asserted to agree.
Experimental x/ tier — imported as cx-x/ux-web. Bundled and gated in-tree like any other module, but EXEMPT from the frozen-surface stability promise (std-lib README, decision D3): a semver-breaking change is allowed here while the surface settles, and the frozen-surface canary never counts it. Pin behaviour you depend on with your own fixtures.
ux-web:htmx-subset
[$ux-web:htmx-subset] () -> [sequence string] — The pinned, normative htmx attribute set the emitter may author; additions are individual rulings and hx-on is excluded permanently.
ux-web:htmx-allowed
[$ux-web:htmx-allowed] ($attr::string) -> bool — Is one attribute name on the pinned htmx subset?
ux-web:lower
[$ux-web:lower] ($el::any $c0::map) -> any — Lower a semantic tree to its HTML element tree — the rendering, before serialization.
ux-web:render
[$ux-web:render] ($el::any $ctx::map) -> string | [err …] — Project one semantic tree to HTML text, or refuse with one [err …] naming every violation — never a partial render. Runs the SHARED semantic gate first, so a tree this renderer accepts and the terminal renderer rejects cannot exist.
ux-web:render-fragment
[$ux-web:render-fragment] ($el::any $f::element $rctx::any) -> string | [err …] — Project one semantic tree addressed by an explicit fragment address — the swap-target form the intent round trip returns.
ux-web:lower-ops
[$ux-web:lower-ops] ($ops::any $ctx::map) -> any — Lower the core's semantic patch operations to out-of-band HTML — the ONLY place hx-swap-oob is authored, with every container id derived from the op's element path by the same frag-id that minted it.
ux-web:render-rows
[$ux-web:render-rows] ($rows-el::any $ctx::map) -> string | [err …] — A row container's contents as bytes — what an innerHTML swap at the collection expects, and the one parse context in which a
ux-web:render-ops
[$ux-web:render-ops] ($ops::any $ctx::map) -> string | [err …] — The serialized out-of-band payload one ∂ script becomes — through the same subset and CSP scans as a page, so a live update cannot skip the invariants.
ux-web:unbound-filter-refusals
[$ux-web:unbound-filter-refusals] ($el::any $rctx::any) -> [sequence element] — Refuse a filter whose affected collection has no fragment endpoint bound — a control that renders and does nothing passes every server-side gate.
ux-web:input-kind-of
[$ux-web:input-kind-of] ($kind::string) -> string — Map a declared CX kind to its HTML control type; decimal and bigint stay text because they ride string carriers and a number input would corrupt them. Renderer-private — the terminal renderer maps the same kinds to its own editors.
ux-web:off-subset-attrs
[$ux-web:off-subset-attrs] ($html::string) -> [sequence element] — Scan serialized emitter output and refuse every hx-*/sse-* attribute that is not on the pinned subset.
ux-web:csp-violations
[$ux-web:csp-violations] ($html::string) -> [sequence element] — Scan serialized emitter output for the strict-CSP invariants: no inline style=, no inline script, no event-handler attribute.
ux-web:content-of-html
[$ux-web:content-of-html] ($h::any) -> element — Read the lowered HTML tree back to the common content normal form — the WEB side of the equivalence assertion, taken from the tree this renderer actually serializes.
ux-web:content-repr-html
[$ux-web:content-repr-html] ($el::any $ctx::map) -> string — The canonical bytes the web rendering contributes to the equivalence assertion.
ux-web:token-value-safe
[$ux-web:token-value-safe] ($v::string) -> bool — Is a theme token value safe to place in a generated stylesheet — the CSS analogue of the emitter's escaping invariant?
ux-web:theme-refusals
[$ux-web:theme-refusals] ($theme::element) -> [sequence element] — Every unsafe token value in one theme document.
ux-web:theme-css
[$ux-web:theme-css] ($theme::element) -> string | [err …] — Compile a token theme document to the generated stylesheet — custom properties plus the component rule table; an unsafe token refuses the whole sheet.
ux-web:component-rules
[$ux-web:component-rules] () -> [sequence element] — The pack-owned .ux-* rule table as structured data; every declaration references a theme token, so no color, size, or font is hard-coded.
ux-web:join-str
[$ux-web:join-str] ($parts::any) -> string — Concatenate a sequence of strings as a pure, total fold.
ux-web:csp-header
[$ux-web:csp-header] ($assets::any) -> string — The strict Content-Security-Policy value, pinning each vendored script by the SRI digest of the bytes actually served.
ux-web:page-html
[$ux-web:page-html] ($title::string $assets::any $el::any $ctx::map) -> string | [err …] — The served bytes for one route: doctype, token stylesheet, hash-pinned kernel, and the lowered body — refused whole on any violation.
ux-web:asset-manifest
[$ux-web:asset-manifest] ($dir::string $names::any) -> [sequence element] | [err …] — Read the vendored kernel's bytes and derive each asset's SRI digest, so script-src and integrity= can never drift from what is served; a missing asset refuses.
ux-web:font-value-safe
[$ux-web:font-value-safe] ($v::string) -> bool — The token-value-safe allowlist widened by exactly one character: '+' — a unicode-range is written U+0000-00FF and there is no other way to spell it; admitted here and nowhere else.
ux-web:theme-vars
[$ux-web:theme-vars] ($theme::element) -> string — The theme's tokens as CSS custom properties: shared tokens and the default palette on :root, each non-default palette re-stated under its prefers-color-scheme condition (P0-104).