NoFlo: Flow-based programming for JavaScript
NoFlo is an implementation of flow-based programming for JavaScript running on both Node.js and the browser. From WikiPedia:
In computer science, flow-based programming (FBP) is a programming paradigm that defines applications as networks of "black box" processes, which exchange data across predefined connections by message passing, where the connections are specified externally to the processes. These black box processes can be reconnected endlessly to form different applications without having to be changed internally. FBP is thus naturally component-oriented.
Developers used to the Unix philosophy should be immediately familiar with FBP:
This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.
It also fits well in Alan Kay's original idea of object-oriented programming:
I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages (so messaging came at the very beginning -- it took a while to see how to do messaging in a programming language efficiently enough to be useful).
NoFlo has been written in CoffeeScript for simplicity. The system is heavily inspired by J. Paul Morrison's book Flow-Based Programming.
Read more at http://noflojs.org/.
Requirements and installing
NoFlo is available for Node.js via NPM, so you can install it with:
$ npm install -g noflo
You can customize and download the browser version of NoFlo at http://noflojs.org/download/.
Installing from Git
NoFlo requires a reasonably recent version of Node.js, and some npm packages. Ensure you have the grunt-cli
package installed (grunt
command should be available on command line) and NoFlo checked out from Git. Build NoFlo with:
$ grunt build
You can also build NoFlo only for the desired target platform with either grunt build:nodejs or grunt build:browser.
Then you can install everything needed by a simple:
$ npm link
NoFlo is available from GitHub under the MIT license.
Changes
Please refer to the Release Notes and the CHANGES.md document.
Usage
Please refer to http://noflojs.org/documentation/.
Development
NoFlo development happens on GitHub. Just fork the main repository, make modifications and send a pull request.
We have an extensive suite of tests available for NoFlo. Run them with:
$ grunt test
or:
$ npm test
Platform-specific tests
By default, the tests are run for both Node.js and the browser. You can also run only the tests for a particular target platform:
$ grunt test:nodejs
or:
$ grunt test:browser
Running tests automatically
The build system used for NoFlo is also able to watch for changes in the filesystem and run the tests automatically when something changes. To start the watcher, run:
$ grunt watch
To quit thew watcher, just end the process with Ctrl-C.
Discussion
Flow-based programming in general, including NoFlo can be discussed on the Flow Based Programming Google group.
There is also an IRC channel #fbp
on FreeNode.
0.5.1 (May 8th 2014)
- Custom component loaders can be registered programmatically using the
registerLoader
method of NoFlo's ComponentLoader contains
method for buffered inports returns the number of data packets the buffer has- Call stack exhaustion on very large graphs has been fixed
- The
error
outport of AsyncComponents now sends the group information of the original input together with the error - The
error
method of regular ports can now also handle groups as a second parameter - Ports can now list their attached sockets (by array index) via the
listAttached
method function
is now an accepted datatype for ports- There is now initial support for making connections to and from addressable ports with a specified index
In the FBP format, these can be specified with the bracket syntax:
SomeNode OUT[2] -> IN OtherNode
'foo' -> OPTS[1] OtherNode
In the JSON file these are defined in connections by adding a integer to the index
key of the src
or tgt
definition.
The NoFlo Graph class provides these with the following methods:
addEdgeIndex(str outNode, str outPort, int outIndex, str inNode, str inPort, int inIndex, obj metadata)
addInitiaIndex(mixed data, str inNode, str inPort, int inIndex, obj metadata)
If indexes are not specified, the fall-back behavior is to automatically index the connections based on next available slot in the port.