Files
yawn/vendor/fxnode/docs/learn/tutorials/first-node.md
T

3.3 KiB

Your first node

What you will build

A Canvas editor containing one numeric value node, matching the repository's executable minimal example.

Prerequisites

Install fxnode. Give the canvas non-zero CSS dimensions (the attributes also provide a useful fallback), then prepare a browser host that measures it and forwards input:

<canvas id="graph" width="1000" height="560" style="width: 100%; height: 560px"></canvas>

The repository's small host implementation contains viewport, resize, and input wiring; see browser host for its contract.

Checkpoint

Your canvas has non-zero CSS dimensions and your host has produced initialViewport.

1. Prepare application-owned definitions

theme, minimalStyles, numberSocket, and valueNode below are application-owned definitions, not fxnode globals. The socket and node are exported as [id, definition] tuples so they can be passed directly to the composition methods. Define or import them before bootstrap; the executable definition file is the compact reference.

2. Bootstrap in dependency order

Create the shared root first, then install composition dependencies in order: theme, header styles, sockets, nodes, and finally graph state. Attach the canvas view after that bootstrap.

import { createFxNode } from "fxnode";

const root = await createFxNode({
  applicationId: "my.first.editor",
  applicationVersion: 1,
  resources: {},
});
await root.setTheme(theme);
await root.setHeaderStyles(minimalStyles);
await root.composeSocket(...numberSocket);
await root.composeNode(...valueNode);
await root.setState({ graphId: "first", catalogVersion: 1, nodes: [], links: [], metadata: {} });
const view = await root.attachView({ canvas, viewport: host.initialViewport });
host.attach(root, view);
await view.addNode({ nodeId: "value", typeId: valueNode[0], viewPosition: { x: 360, y: 190 } });
await view.whenRendered();

Checkpoint: a “Number Value” node is visible. The host is attached only after setup, and the view's whenRendered() confirms the committed node reached a frame.

Why this order?

The worker validates every definition against current authority. setState is last so known nodes bind against the complete composition. Host attachment follows bootstrap so input cannot race setup.

3. Clean up

Remove application listeners, call host.destroy(), await view.detach(), then call root.destroy() on unmount or pagehide. Also destroy a late-created root if teardown wins a startup race. The complete source demonstrates that guard.

Complete example

The complete executable source is examples/minimal/main.ts, with its definition.ts.

Composition and worker authority.

Relevant API

createFxNode, FxNode, and FxNodeView.

Next

Build a richer Color Balance node.