Links & Data
Links & Data
Links
A link connects one node's output port to another node's input port:
A out -> in B
Packets written to A's out port travel the link and arrive on B's in port. Links can be chained on a single line by continuing the right-hand side:
A out -> in B out -> in C out -> in D
This is the same as three separate links, and chains up to four hops per line parse the same way.
Initial information packets (IIPs)
An IIP is a literal value fed directly into a port — no source node:
'Hello World!' -> msg Log(console/log)
The left-hand side can be a quoted string or a JSON literal:
{"title": "test"} -> in MyProc
["a", "b", "c"] -> in MyProc
An IIP is not a link: it appears in the flow model as initial data, delivered when the flow starts.
Context feeds
Prepending @ to the target port turns the data into context — config stored on the node, not a wired link:
'Hello World!' -> @msg Log(console/log)
Now the value travels inside the flow definition itself (it shows up under nodes[].context in the compiled model), and the node's input is fulfilled by context, so the node starts without any link. This is how a flow distributes configuration that should live with the definition rather than with the wiring.
$ fbpx convert hello.fbp --yaml
nodes:
- id: Log
ns: console
name: log
context:
msg: Hello World!
Link modifiers
A few modifiers attach to the arrow or the ports to change how data travels.
^ — persist
A ^ before a target port keeps the port's last value, so the node can re-read it on every run without new data:
Test out -> ^IN SomeNode
The port holds its last packet and read() returns a fresh clone of it after it has been drained.
[index] — extraction
A [N] (or [name]) after a source port pulls one element out of the packet before it travels:
GetCommands out [0] -> in BuildPath
Message event [srcElement] -> msg Log
[0] extracts element zero from an array packet; [srcElement] extracts the named property from an object packet. This is data extraction on the wire — the downstream node receives the single element, not the whole structure.
Masks
A -(/path)> arrow extracts an object path from each packet:
{"title": "my title"} -> in MyProc out -(/title)> in Proc2
Each packet that crosses the link is masked down to the value at /title. Masks take either an object mapping names to paths or a single path.
=> and >= — streams
Two arrows change how a whole batch of packets behaves rather than a single packet. They are documented in full on the Streams page:
["a", "b", "c"] => in Echo(stream/echo) # one delivery per element
Echo out >= in Collect(console/log) # one array when the batch closes
Export declarations
A -> or <- with nothing on the left is not an IIP or a link — it declares an external port on the flow itself:
-> in:ExtName Process
<- out:ExtName Process
-> in:ExtName Processdeclares an external input portExtName, wired toProcess'sinport.<- out:ExtName Processdeclares an external output portExtName, fed byProcess'soutport.
The colon renames the port for the outside world (in:command exposes command). The rename is optional:
-> in Process # external port named "in"
<- out Click # external port named "out"
Exports land in the flow's input/output ports, which is exactly what lets a flow be used as a node elsewhere — the subgraph's exports are its ports.
A chain can pass through an export:
-> in d(utils/dummy) out -> in Click
declares d's in as an external input, then links d.out onward to Click.