Reconciler ↔ Template interop

Three patterns — which ones work and why.

Pattern 1 — Reconciler component hosts a template SAFE

The reconciler renders a <div> and holds a useRef to it. A useEffect mounts a Vertex.template into that div. The reconciler owns the wrapper node; the template owns only the innerHTML inside it. They never touch each other's DOM.

Data flows reconciler → template by calling tmpl.update() inside an effect whenever state changes. Data flows template → reconciler via the template's on('change', …) event, which calls a setState dispatcher. Fully bidirectional.

Pattern 2 — Side-by-side, shared JS state SAFE

The reconciler and template live in completely separate DOM regions. A plain JS object acts as the shared store. When either side mutates it, the other is notified via a tiny event emitter — no framework coupling at all. The template calls tmpl.update(store); the reconciler calls its setState dispatcher.

Reconciler side
Template side (reads same store)
Pattern 3 — Template hosts a reconciler mount point UNSAFE — do not use

If a template renders a <div id="sub"> and you call Vertex.render(component, subDiv) into it, the next time the template calls this._el.innerHTML = … it destroys every DOM node the reconciler placed inside it. The reconciler's fiber.dom references now point to detached, garbage-collected nodes. The reconciler doesn't know this happened — it will continue patching ghost nodes that are no longer in the document, silently producing no visible output.

The template's innerHTML = is a full DOM nuke. Any foreign state (reconciler fiber tree, third-party widgets, canvas contexts) inside that element is irrecoverably lost.