Precompiled Resumable UI
Precompiled Resumable UI is Fuzor's native rendering model. It combines compiler optimizations, server components, resumability and independently managed interactivity. Framework Islands are integrations with third-party UI runtimes. Native interaction needs no island wrapper or custom element.
Precompile what you can. Resume when needed. Structure and handler references are prepared ahead of time; dynamic data and browser/server work still run at runtime.
A managed native counter
A component remains an HTML file. Its optional module script comes first. Use
JavaScript or add lang="ts" for TypeScript:
<script type="module" lang="ts">
import { defineNative } from "fuzor/runtime/native"
defineNative({
id: "counter",
version: 1,
state: { count: 0 },
bindings: [
{ selector: "button", state: "count", kind: "text", prefix: "Count: " }
],
events: [
{ selector: "button", type: "click", handler: context => {
context.set("count", Number(context.get("count")) + 1)
} }
]
})
</script>
<button id="counter" type="button">Count: 0</button>
The compiler extracts each handler into a lazy module. Initial activation adopts existing DOM and restores declared state through Effect Atom. It does not execute handlers or render the HTML again. Handler dependencies load with the handler, including relative imports from the original HTML file. Stylesheet imports can remain with the declaration.
The same declaration can live in a page module script scoped to its parent or the route outlet. There is no requirement to create a component file.
Managed scripts contain imports, optional TypeScript type declarations and one
defineNative({...}) expression. Metadata and initial state use static JSON
literals. Handlers take one context parameter; imports and browser globals can be
used, but arbitrary outer captures are rejected. Use context.get/set for retained
state and context.props for current adapter props. An ordinary script remains
available for imperative editors, effects and other browser initialization.
Ownership, identity and lifetime
- Bindings own specific DOM properties, not every descendant. Selectors cannot cross a Framework Island, Fuzor UI root or an already active child native root. Competing owners of the same binding are rejected.
ididentifies the behavior;versiondeclares state compatibility. The generated instance key includes the route and its host'sdata-fuzor-keyorid, falling back to the behavior ID. Repeated instances of one definition in one route need distinct host keys. State is never restored by DOM position.- Moving a live keyed host keeps its state and handlers. Removing it from its route disposes its script resources. Ordinary route changes create new route instances; this does not promise persistent layouts across navigation.
- Independent script hosts activate concurrently. Nested hosts wait for their parent, and consecutive scripts on one host retain order. A failed initializer or script import releases that instance's resources and leaves independent siblings usable.
- Initialization, handlers and registered cleanup have asynchronous deadlines. Cancellation prevents late managed state writes. These deadlines cannot interrupt a synchronous JavaScript loop or undo arbitrary external side effects.
The script runtime's returned cleanup function also exposes status(host),
retry(host) and dehydrate(). Custom hosts can use mountPageScripts with an
onError callback and checkpoint option. Normal Fuzor builds generate registries.
State and DOM bindings
state is bounded, finite, acyclic JSON. Each handler receives get(name),
set(name, value), element, a captured event summary, current props and an abort
signal. Read and write through those APIs; mutating a returned object does not
update retained state.
Supported bindings are:
| Kind | Target |
|---|---|
text | Scalar text in an element with no child elements; optional prefix/suffix |
value | Scalar form-field value |
checked | Boolean checkbox state |
attribute | aria-*, data-*, title, hidden or disabled |
Text is written as text, not HTML. Unsafe attribute bindings are rejected. Text input and checkbox edits made before activation are adopted instead of overwritten by stale initial state.
Supported events are click, input, change, keydown, keyup, submit,
focusin, focusout, pointerdown and pointerup. Events queue in order per
instance while code loads. preventDefault: true is explicit; native browser
behavior otherwise remains available. Delayed handlers cannot recreate trusted
user activation for permission prompts, popups or other protected browser actions.
The optional activation policy controls handler code preloading:
interaction (default), load, idle or visible. It does not execute handlers.
Where visibility observation is unavailable, interaction still loads the handler.
Inline SPA builds embed the modules, while handler execution remains deferred.
The inline loader uses an embedded ESM module map and local Blob URLs, preserving
module evaluation order and import failures without external code requests. Its
bootstrap uses browser import maps; hosting CSP must permit the inline bootstrap
and Blob module sources.
Module-relative JavaScript resource URLs (such as separate worker files) require
an inline-aware adapter and are rejected instead of producing a broken offline artifact.
Explicit checkpoints
Persistence across reloads is opt-in. Fuzor does not automatically put application state in local storage:
import { snapshotNative, restoreNative } from "fuzor/runtime/native"
const saved = snapshotNative(document)
// Later, while matching instances are live:
restoreNative(document, saved)
restoreNative validates matching identities, versions, state names and binding
value types before restoring live instances. It neither mounts components nor
runs handlers. For initial adoption, custom script hosts can pass a checkpoint to
mountPageScripts; createNativeCheckpointStore supports explicit native adapters.
A version/schema mismatch is an error. Migrate your saved JSON deliberately or reset it before restoration. Browser resources, arbitrary closures and imported libraries' internal state are not checkpointed by this API. Store only state you intend to persist, and partition stores by application/session/tenant. Persistent server adapters also namespace instance keys by the renderer's scope.
Server components and compatible updates
nativeClient(definition, { store?, initialState? }) provides a native persistent client adapter
for Fuzor server-component boundaries. Its host must already contain the binding
markup, or the surrounding adapter must create that markup before mounting it.
Compatible server updates call update(props) on the retained native instance;
state and DOM identity remain intact. Changed server component identities are
replaced and disposed by the server-view renderer.
An optional initialState(props) callback supplies server-provided defaults for
declared cells when a new instance has no checkpoint. It is skipped on checkpoint
restoration; later prop updates do not overwrite retained user state.
An explicit server boundary contains client preparation/mount/update failures. It releases its affected children and displays a local fallback; a subsequent server update retries. Healthy sibling boundaries remain alive. This is not an atomic rollback of effects performed by a failing external library.
Static native interaction needs no backend. Server components require one, but can update inside a SPA without request-rendering the initial document.
Guarantees by path
| Path | Adoption/state | Activation | Lifetime/updates |
|---|---|---|---|
| Static HTML | Precompiled content | No native behavior initialization | Document/route lifetime |
| Managed native declarations | Explicit Atom state and validated checkpoints | Extracted lazy handlers | Scoped script lifetime; persistent adapter updates when used |
| Fuzor UI components | UI and machine checkpoint contracts | Lazy UI behavior | UI ownership and cleanup contracts |
| Compiled server fragments | Keyed fragment state and supported captures | Delegated lazy handlers | Compatible keyed updates and explicit failure boundaries |
| Imperative HTML scripts | Arbitrary locals are not resumable | Per-instance initialization | Abort/cleanup and local script failures |
| Framework Islands | Defined by the framework/adapter | Mounting or hydration | Framework host isolation and adapter cleanup |
Production tests qualify managed HTML counters, cold handlers, independent import failures, keyed live restoration, native UI/React coexistence, navigation cleanup, MPA delivery and inline file delivery in Chromium, Firefox and WebKit. Native persistent clients also retain state and node identity through streamed SPA updates. Broader existing UI and server-component tests remain their own evidence; this does not claim every third-party library is resumable.