Renderer and block registry
This page describes the shipped surface of @nubbin/react: the
Renderer server component,
defineRegistry,
loadBlocks, and the
BlockComponent,
BlockRegistry,
RendererProps,
HoleContext and
HoleResolver types — every one of them
declared where it is defined, and generated from there. The package renders an artifact tree
against a registry of blocks and evaluates nothing the artifact carries — why that boundary
exists is Artifacts contain data, never code.
What a render does
Renderer loads the blocks the artifact names — Object.keys(artifact.blockVersions) — then
walks artifact.tree, rendering each node, and wraps the results in a Fragment. A block is
invoked and its root element cloned rather than wrapped, which is what obliges it to be a
server component: Blocks are server components.
A node fills its holes before its block is invoked, because a block reads a hole as an ordinary
prop. A node that declares holes and was given no resolveHole refuses, naming the node —
rendering the placeholder instead would put a compile-time artefact in front of a visitor with
nothing to notice it.
Holes
The renderer decides where a resolved value lands; the resolver the consumer supplies decides
what it is. It receives the hole's spec and never a value, and mapping a declared lifecycle onto
a caching layer belongs to the framework binding — @nubbin/next's
holeFetchOptions is that mapping for Next.