The FBP Language
The FBP Language
A FBPX program is a graph, described in a plain-text file with an .fbp extension. The file declares the nodes that make up the flow, the links that connect them, the initial information packets (IIPs) that seed them, and a provider that says where the node definitions come from.
Because the whole program is text, your architecture is versioned, reviewed, and diffed like any other source code. The same file is parsed into a data model by the @fbpx/fbpx parser and executed by the @fbpx/flow runtime.
The four primitives
| Primitive | Syntax | Meaning |
|---|---|---|
| Node | Name(ns/name) |
An instance of a node of kind ns/name, called Name in this flow |
| Link | A out -> in B |
Packets from A's out port flow to B's in port |
| IIP | 'value' -> in B |
An initial packet with a literal value, fed directly into a port |
| Provider | provider ./{ns}.{name}.yml |
How node definitions are resolved |
The arrows
Every arrow in the language has a specific meaning, and several are more than a plain link:
| Arrow | Name | Effect |
|---|---|---|
-> |
link / IIP | A normal connection, or an initial packet when a literal sits on the left |
-> @port |
context feed | Stores data on the node as context instead of wiring a link |
=> |
cyclic | Splits an array packet into one delivery per element — a loop feed |
>= |
collect | Buffers a stream and emits it as one array when the batch closes |
~> |
include | Reads a file (or URL) into a data value; trailing ! JSON-parses it |
-(/path)> |
mask | Extracts an object-path from each packet on the wire |
-> in:Ext |
export | Declares an external input port on the flow (graph-as-a-node) |
<- out:Ext |
export | Declares an external output port on the flow |
^ |
persist | Keeps a port's last value so read() can be called again |
[index] |
extraction | Pulls one element (or property) out of a packet at the source |
*out |
pointer | Parsed for compatibility — inert at runtime (see control) |
in[Origin] |
sync | Parsed for compatibility — inert at runtime (see control) |
Each arrow is documented in full in its own page:
- Nodes & providers —
Name(ns/name), theproviderline, node definitions, subgraphs - Links & data — links, IIPs, context feeds,
^,[index], masks, exports, chains - Streams —
=>and>=, batches, and end-of-stream - Includes & data — the
~>include arrow - Control & virtual ports —
:start,:complete,:shutdown,@fn, and the inert surface
Reading a flow
A flow line is one of four shapes, distinguished by its left-hand side:
Name(ns/name)— a node declaration'value'(or a JSON literal) on the left of->— an IIP- a process name + port on the left of
->— a link ->or<-with nothing on the left — an export declarationkey: valueat the top of the file — flow meta (title,ns,name)
The whole grammar is unambiguous about these, so a flow both reads and parses mechanically.
Compiling and running
The parser turns a .fbp file into a data model. You can inspect that model with the CLI, and run it with the runtime:
$ fbpx convert hello.fbp --yaml # inspect the parsed graph
$ fbpx graph hello.fbp # render as a dot graph
$ fbpx run hello.fbp # execute the flow
Everything from here on is syntax. The runtime structures behind it — nodes, ports, links, packets, flows — are documented in the API section.