ControlledGraph API
ControlledGraph declares your application the canonical owner of line
topology. It renders nothing.
| Prop | Meaning |
|---|---|
onLineChangeRequest | Receives one atomic LineChangeRequest per gesture and returns the line list that should now be canonical |
onDiagnosticsChanged | Receives the current ReconciliationError[] when it changes |
There is no lines prop. The handler’s return value is the channel, so a
typical graph is one line:
<script lang="ts">
import { applyLineChange } from "@snap-engine/snapline";
let lines = $state.raw<LineRecord[]>([]);
</script>
<ControlledGraph
onLineChangeRequest={(request) => (lines = applyLineChange(lines, request))}
/> The assignment updates your state and evaluates to the array the bridge
needs. Reject by returning the list unchanged (return lines) — the staged
line is then discarded. The return type is required, so forgetting to return
is a type error rather than an accidental rejection. The handler must be
synchronous.
A LineChangeRequest carries an intent ("connect" | "disconnect" | "replace" | "reconnect") plus add (ProposedLine[] with SnapLine-minted ids), remove (LineId[]), and update (endpoint retargets). Adopting a proposed id settles the staged line
in place, with no flicker and the same mirror.
For changes no request asked for — loading a saved graph, undo/redo, a collaborator’s edit — take a component reference and push:
<ControlledGraph bind:this={graph} onLineChangeRequest={...} /> graph.setLines(records) replaces the canonical document; graph.flush() runs any pending reconciliation synchronously.
ReconciliationError.code is one of "duplicate-id" (a record id appears
twice in the snapshot), "capacity-exceeded" (a record violates a
connector’s maxIncoming), or "connection-rejected" (an endpoint’s isValidConnection vetoed the record). Errored records stay in your document
and are retried when relevant state changes; records whose endpoints are not
mounted stay silently latent.