Skip to content

Function: renderSpec()

API / @xmachines/play-dom / renderSpec

function renderSpec(spec, store, registry, options?): Node | null;

Defined in: @xmachines/json-render-dom

Render a Spec tree into DOM nodes using the provided DomRegistry.

Traverses the spec from spec.root, evaluates visibility, resolves all prop expressions (including $state, $bindState, $computed, $template, etc.), and calls the matching DomComponentRenderer for each visible element.

Event wiring and child rendering are handled inside the component wrapper built by defineRegistry — this function only orchestrates the traversal.

Parameters

ParameterTypeDescription
specSpecThe json-render Spec describing the UI tree.
storeStateStoreLive StateStore bound to spec.state.
registryDomRegistryMap of element type names → DomComponentRenderer.
options?RenderSpecOptionsNamed options — see RenderSpecOptions.

Returns

Node | null

The root DOM Node, or null if the root is invisible or has no registered renderer.

Remarks

Devtools isolation in tests: The module-level devtoolsActive flag is a singleton that persists for the lifetime of the module. In test environments, any call to markDevtoolsActive() MUST be paired with a release() call inside a try/finally block. Failing to do so leaves devtoolsActive = true for all subsequent tests, causing false positives in devtools-conditional rendering paths (e.g. data-jr-key wrapper spans).

const release = markDevtoolsActive();
try {
// test code
} finally {
release();
}

Example

const { registry, handlers } = defineRegistry(catalog, { components, actions });
const resolvedHandlers = handlers(
() => undefined,
() => ({}),
);
const node = renderSpec(spec, store, registry, {
send: actor.send.bind(actor),
handlers: resolvedHandlers,
});
if (node) container.appendChild(node);