Build a Pack or Expand node's ports from a struct variable

The port editor gets 'From variable' next to '+ Field': pick a struct variable
of the behavior and its fields land as ports. It only adds - a field the node
already declares stays as it is, because it may carry an edge - and the entry
is disabled once there is nothing left to add. A list of structs counts too:
it declares the shape of every item, which is exactly the bundle a Pack builds
for it. A color field arrives as a number port; the graph has no color type.

AddPortsCommand is new underneath: adding five ports had to be one undo step,
and it checks every key before it appends a single one, so a collision does
not leave half the list behind. AddPortCommand is a three-line subclass of it,
which leaves its sixteen call sites untouched.
This commit is contained in:
root committed 2026-09-10 21:35:30 +02:00
1 parent 2218046738
commit 14f542365e
10 files changed
+346 -22

No files matched your search

+5 -2
View File
@@ -163,7 +163,10 @@ shown on the node and editable in the inspector.
- **Structs**: several named values travelling as one, so a bundle needs one edge instead of one
per part. `Pack` declares its fields as inputs, `Expand` reads them back out as outputs, a
behavior port may be declared `struct` – which is how a bundle crosses a call – and a
**variable** may be one, which is how a bundle is stored. Writing a struct variable keeps the
**variable** may be one, which is how a bundle is stored. A `Pack`/`Expand` can take its fields
from a variable that already declares the shape (**From variable**, a struct variable or the item
shape of a list of structs) instead of having them typed again; that adds the fields it does not
have yet as one undo step and leaves the ones it has alone. Writing a struct variable keeps the
fields it declares: what arrives fills the ones it names, the rest stay put (`mergeStruct`), so
one node can set part of a bundle without erasing it – "the same piece, one row lower" is a
`Pack` of that one field. Depth is bounded by the *declaration*, not by convention: a list says
@@ -604,7 +607,7 @@ npm run check # typecheck + lint + format:check + tests, what CI would ru
# code is lost (tail's is reported), so a red run reads as green
npm run build # writes dist/ and regenerates index.html
export GM_REMOTE=user@host # optional: run the browser elsewhere; see below
node tools/seed-e2e.mjs && node tools/e2e.mjs # 496 editor checks, screenshots in /tmp/gm-e2e-*.png
node tools/seed-e2e.mjs && node tools/e2e.mjs # 502 editor checks, screenshots in /tmp/gm-e2e-*.png
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 – a subset while working on one step
./e2e.sh start [GM_STEPS] # the same run detached, see below
./e2e.sh status # live progress, or the last run's result