FBP flow definition language parser
CoffeeScript JavaScript HTML
Latest commit 2e5589f Jan 31, 2017 @bergie bergie committed on GitHub Merge pull request #72 from flowbased/greenkeeper-grunt-noflo-browser…

grunt-noflo-browser@1.2.0 breaks build 🚨
Failed to load latest commit information.
bin Implement fixes from @jonnor Jul 4, 2016
browser Webpack build setup Dec 6, 2016
lib remove cs, add json test to phantomjs runner. Jul 6, 2016
schema schema: Allow index in connections, for arrayports May 24, 2016
schemata schema: Allow index in connections, for arrayports May 24, 2016
spec remove cs, add json test to phantomjs runner. Jul 6, 2016
.gitignore Webpack build setup Dec 6, 2016
.travis.yml Adding JSON to FBP support Jul 3, 2016
CHANGES.md Bump 1.5.0 Jul 6, 2016
Gruntfile.coffee Use default webpack config Jan 31, 2017
appveyor.yml Update Windows CI config Jan 3, 2017
component.json Bump 1.3.0 May 24, 2016
package.json chore(package): update grunt-noflo-browser to version 1.2.0 Jan 31, 2017


FBP flow definition language parser Build Status Build status

The fbp library provides a parser for a domain-specific language for flow-based-programming (FBP), used for defining graphs for FBP programming environments like NoFlo, MicroFlo and MsgFlo.


You can use the FBP parser in your JavaScript code with the following:

var parser = require('fbp');

// Some FBP syntax code
var fbpData = "'hello, world!' -> IN Display(Output)";

// Parse into a Graph definition JSON object
var graphDefinition = parser.parse(fbpData, {caseSensitive: true});

When caseSensitive is false the parser will convert port names to lowercase. This is currently the default behavior, but in future releases the default will change to preserve case. It is therefore recommended that you always specify the caseSensitive option to make your code future-proof.


The fbp package also provides a command-line tool for converting FBP files into JSON:

$ fbp somefile.fbp [--case-sensitive] > somefile.json

And for converting JSON files into FBP:

$ fbp somefile.json [--case-sensitive] > somefile.fbp

Language for Flow-Based Programming

FBP is a Domain-Specific Language (DSL) for easy graph definition. The syntax is the following:

  • 'somedata' -> PORT Process(Component) sends initial data somedata to port PORT of process Process that runs component Component
  • A(Component1) X -> Y B(Component2) sets up a connection between port X of process A that runs component Component1 and port Y of process B that runs component Component2

You can connect multiple components and ports together on one line, and separate connection definitions with a newline or a comma (,).

Components only have to be specified the first time you mention a new process. Afterwards, simply use the process name.


'somefile.txt' -> SOURCE Read(ReadFile) OUT -> IN Split(SplitStr)
Split OUT -> IN Count(Counter) COUNT -> IN Display(Output)
Read ERROR -> IN Display

The syntax also supports blank lines and comments. Comments start with the # character.

Example with the same graph than above :

# Read the content of "somefile.txt" and split it by line
'somefile.txt' -> SOURCE Read(ReadFile) OUT -> IN Split(SplitStr)

# Count the lines and display the result
Split() OUT -> IN Count(Counter) COUNT -> IN Display(Output)

# The read errors are also displayed
Read() ERROR -> IN Display()

Exporting ports

When FBP-defined graphs are used as subgraphs in other flows, it is often desirable to give more user-friendly names to their available ports. In the FBP language this is done by INPORT and OUTPORT statements.


Read(ReadFile) OUT -> IN Display(Output)

This line would export the IN port of the Read node as FILENAME.

Node metadata

It is possible to append metadata to Nodes when declaring them by adding the metadata string to the Component part after a colon (:).


'somefile.txt' -> SOURCE Read(ReadFile:main)
Read() OUT -> IN Split(SplitStr:main)
Split() OUT -> IN Count(Counter:main)
Count() COUNT -> IN Display(Output:main)
Read() ERROR -> IN Display()

In this case the route leading from Read to Display through Split and Count would be identified with the string main. You can also provide arbitrary metadata keys with the = syntax:

Read() OUT -> IN Split(SplitStr:foo=bar,baz=123)

In this case the Split node would contain the metadata keys foo and baz with values bar and 123.