17019bc Aug 29, 2016
@bergie @trustmaster @jonnor @aretecode
642 lines (475 sloc) 30.2 KB

NoFlo ChangeLog

0.8.0 (git master)

  • Added callback for Network.stop
  • Outmost brackets are no longer automatically converted to connect and disconnect events. Instead, connect and disconnect are injected as needed, but only for subscribers of the legacy events
  • Added deprecation warnings for APIs that will be removed by NoFlo 1.0. These can be made fatal by setting the NOFLO_FATAL_DEPRECATED environment variable. These include:
    • noflo.AsyncComponent: should be ported to Process API
    • noflo.helpers.MapComponent: should be ported to Process API
    • noflo.ArrayPort: should be ported to noflo.In/OutPort with addressable: true
    • noflo.Port: should be ported to noflo.In/OutPort
    • Calling Network.start or Network.stop without a callback
    • noflo.InPort process option: should be ported to Process API or use the handle option
    • noflo.InPort receive method: replaced by the get method
    • noflo.InPort contains method: replaced by the has method
    • noflo.Graph exports: use specific inport or outport instead
    • Additionally builds warn about deprecation in favor of webpack with helpful automation available in grunt-noflo-browser
  • Added IP object scope support to WirePattern to make WirePattern components more concurrency-friendly
  • Removed receiveStreams option from WirePattern
  • Graph JSON schema has been moved to, and updated with tests.
  • Added stream helpers for Process API input. hasStream checks if an input buffer contains a complete stream (matching brackets and data, or only data), getStream returns a complete stream of packets. These require forwardBrackets to be disabled for the port.
  • babel-core was removed as a dependency. Install separately for projects needing ES6 component support
  • underscore.js was removed as a dependency
  • input.getData() in Process API has been changed to fetch only packets of data type skipping and dropping brackets inbetween
  • IP objects are strictly required to be of noflo.IP type

0.7.8 (June 10th 2016)

  • Added input buffer manipulation methods
  • Added support for falsy IP object scopes
  • Added support for sending values out directly with output.send if there is only one non-error outport
  • InternalSocket no longer re-wraps already-wrapped errors coming from downstream
  • Switched NoFlo's default browser builder to webpack

0.7.7 (June 8th 2016)

  • input.has now accepts a validation callback function as the last argument. All packets in buffer will be passed to this function, and has will return false only if something returns true for each port specified
  • Removed dropEmptyBrackets option which was conflicting with asynchronous components. This results into empty brackets being forwarded to error outport, so make sure error handling components don't make false alerts on those.
  • ComponentLoader was refactored to allow easier injection of custom loaders when dealing with bundling tools like Browserify and Webpack

0.7.6 (June 2nd 2016)

  • Fixed ComponentLoader caching on Node.js
  • Added support for stream datatype in ports, allowing streams to be passed as data packets
  • NoFlo Graphs now support case sensitive mode, which is possible to trigger via options

0.7.5 (May 2nd 2016)

  • Added automatic bracket forwarding via forwardBrackets option. Enabled from in port to out and error ports by default.
  • Empty brackets are not forwarded to ports in dropEmptyBrackets list (defaults to ['error']).
  • IP metadata can easily be forwarded in simple components by using output.pass() instead of output.sendDone().

0.7.4 (April 7th 2016)

  • Minor network starting improvement

0.7.3 (April 7th 2016)

  • Fixed error handling on broken FBP manifest data
  • Fixed network start callback when there are no defaults in a graph
  • Network uptime is now calculated from the first start event, not from initialization

0.7.2 (April 1st 2016)

  • Fixed FBP manifest caching
  • Fixed non-triggering property being applied on triggering ports
  • Fixed input.getData() crash on ports which have no packets yet

0.7.1 (March 31st 2016)

  • Fixed NoFlo subgraph component in build

0.7.0 (March 31st 2016)

  • Switched component discovery and caching from read-installed to FBP manifest. fbp.json files can be generated using noflo-cache-preheat. This also changes behavior related to components or graphs in custom locations. The fbp-manifest tool only finds them from the default components/ and graphs/ subdirectories of the project base directory.
  • Component Loader listComponents can now return errors as first callback argument
  • Control ports don't receive bracket IPs, only data
  • NoFlo's InternalSocket now always handles information packets as IP Objects, with conversion to/from legacy packet events done automatically. Use socket.on('ip', function (ip) {}) to receive IP object

0.6.1 (March 30th 2016)

  • NoFlo's IP Objects are now available via noflo.IP

0.6.0 (March 29th 2016)

  • Removed the noflo executable in favor of noflo-nodejs
  • NoFlo createNetwork and loadFile methods can return errors as the first callback argument
  • New IP Objects feature allowing bundling and handling of groups and packet data together
  • New option to enable cloning of packets when sending to multiple outbound connections
  • New Process API which replaces WirePattern and makes NoFlo component programming closer to Classical FBP
  • Graph-level request isolation via IP.scope property
  • Removed the deprecated LoggingComponent baseclass

0.5.21 (December 3rd 2015)

  • Made NoFlo component cache keep Component Loader paths also relative

0.5.20 (December 2nd 2015)

  • NoFlo network instances now default to debug mode, meaning that errors thrown by components are available via the process-error event
  • If there are no listeners for the network process-error events or socket error event, then they are thrown
  • This change of behavior fixes issues with stale state in WirePattern networks caused by downstream exceptions
  • Debug mode can be disabled with network.setDebug(false)

0.5.18 (November 30th 2015)

  • Make NoFlo component cache paths relative to project root

0.5.17 (November 27th 2015)

  • Added a new noflo-cache-preheat tool that can be used for improving start-up times in Node.js projects with large lists of dependencies. Can be used as a postinstall script

0.5.16 (November 27th 2015)

  • Update the read-installed package to support scoped dependencies

0.5.15 (November 26th 2015)

0.5.14 (September 25th 2015)

  • EcmaScript 6 support in Component Loader
  • Node.js 4.x compatibility (setSource requires components/ directory to exist in base directory to work)

0.5.13 (April 22nd 2015)

  • Custom componentloader support when cache mode is enabled
  • Optional support for coffee-cache when using --cache

0.5.12 (April 19th 2015)

  • Add support for io.js
  • Add componentName property for components telling the component name
  • Socket events now include edge metadata
  • Node.js: component list can be cached for faster start-up time. Cache file is stored in $BASEDIR/.noflo.json

0.5.11 (October 23rd 2014)

  • On Node.js ComponentLoader setSource now loads components virtually from <baseDir>/components to support relative module loading
  • Subgraphs don't get unattached ports implicitly exported any longer. Register in/outports in the graph to make them available from the outside
  • Added safeties for restarted networks to WirePattern

0.5.10 (October 23rd 2014)

  • Port names are now validated to only contain lowercase alphanumeric characters or underscores
  • ComponentLoader.load method now calls its callback with the Node.js style error, instance signature to allow catching component loading issues
  • Graph merging support via the graph journal
  • getSource now returns correct type for graphs
  • Subgraph networks are started when the main network starts, instead of automatically on their own timing. As a fallback they will also start when any of their ports receives a connect
  • Networks can now be stopped and restarted at will using the stop and start methods
  • The running state of a NoFlo network can be now queried with the isRunning method
  • NoFlo networks support FBP protocol debugging via the setDebug and getDebug methods
  • Ports.add is now chainable
  • The start port was removed from subgraphs

These changes mean that in situations where a subgraph is used standalone without a network around it, you need to call component.start() manually. This is typical especially in unit tests.

0.5.9 (August 5th 2014)

  • Hotfix reverting backwards-incompatible changes in subgraph loading, see #229.

0.5.8 (August 4th 2014)

  • Fixed several issues in connections and data synchronization
  • Updated read-installed to the latest version
  • Updated JSON Schema for NoFlo graph definition format
  • Low-level functions to add and remove graph inports at run-time, see #242
  • Fixes for default port values and IIPs in subgraphs.
  • Added dropInput option for WirePattern to drop premature data while parameters not yet received. See #239
  • Addressable ports support in WirePattern. See details.

0.5.7 (July 23rd 2014)

  • Ports now default to not required. Set the port option required: true the port needs to be connected in order for the component to work
  • MultiError pattern is enabled by default when using WirePattern and supports forwardGroups option for error packets.
  • WirePattern components now deal more consistently with groups and disconnect events

0.5.6 (June 23rd 2014)

  • Custom icon support for subgraphs via the icon key in graph properties
  • Parameter support for WirePattern components, allowing them to have configuration parameters that need to be set only once. Example:
component = new noflo.Component
component.inPorts.add 'path',
  datatype: 'string'
  required: true
component.inPorts.add 'delay',
  datatype: 'int'
  required: false
component.inPorts.add 'line',
  datatype: 'string'
component.inPorts.add 'repeat',
  datatype: 'int'
component.outPorts.add 'out',
  datatype: 'object'
component.outPorts.add 'error',
  datatype: 'object'

noflo.helpers.WirePattern component,
  in: ['line', 'repeat']
  out: 'out'
  params: ['path', 'delay']
  async: true
, (data, groups, out, callback) ->
  path = component.params.path
  delay = if component.params.delay then component.params.delay else 0
  doSomeThing path, delay, data.line, data.repeat, (err, res) ->
    return callback err if err
    out.send res

0.5.5 (June 20th 2014)

  • Fixed an issue with StreamSender affecting WirePattern components dealing with multiple levels of grouping
  • New CustomizeError helper for passing information with Error objects in NoFlo. For example:
# Instantiate an error object
err = new Error 'Something went wrong'

# Add metadata to it. Usually this should include groups and other machine-readable information
noflo.helpers.CustomizeError err,
  groups: groups
  foo: 'bar'

# Send it to error port
c.error err

0.5.4 (June 11th 2014)

  • The new noflo-api-updater tool assists in updating components to the latest NoFlo API
  • GroupedInput helper has been renamed to WirePattern due to a bigger collection of synchronization options.
  • The WirePattern helper has a new ordered option for choosing whether the output should be in same order as the incoming packets
  • Options group and forwardGroups of WirePattern are made independent, so make sure to use forwardGroups: true if you need this feature together with group: true.
  • Added support for multiple outputs and reading/writing substreams as solid objects in WirePattern.
  • Added load outport handing in WirePattern to make it a complete replacement for AsyncComponent.
  • Added helpers for advanced error handling, see #185.
  • Added caching option for OutPorts that makes them re-send their latest value to any newly-added connections, see #151 for example use cases.

0.5.3 (May 31st 2014)

  • integer is accepted as an alias for the int datatype for ports
  • buffer is now an accepted port datatype
  • The Continuous Integration setup for NoFlo now runs on both Linux and Windows
  • Fixed a bug with ComponentLoader getSource method when invoked early on in execution
  • New component helpers for easier authoring

The MapComponent helper is usable for synchronous components that operate on a single inport-outport combination:

c = new noflo.Component
      datatype: 'number'
      datatype: 'number'
noflo.helpers.MapComponent c, (data, groups, out) ->
  out.send data * 2

The GroupedInput helper assists in building components that need to synchronize multiple inputs by groups:

c = new noflo.Component
      datatype: 'number'
      datatype: 'number'
      datatype: 'number'

noflo.helpers.GroupedInput c,
  in: ['x', 'y']
  out: 'radius'
, (data, groups, out) ->
  out.send Math.sqrt(data.x**2 + data.y**2)

GroupedInput can also synchronize via specific fields of object-type packets:

helpers.GroupedInput c,
  in: ['user', 'message']
  out: 'signedMessage'
  field: 'request'
, (data, groups, out) ->
    request: data.request
    text: data.message.text

user.send {request: 123, id: 42, name: 'John'}
message.send {request: 123, id: 17, text: 'Hello world'}

# Result:
{ request: 123, user: 'John', text: 'Hello world'}

0.5.2 (May 8th 2014)

  • Fixed a minor packaging issue

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.

0.5.0 (March 28th 2014)

  • Support for setting the default baseDir of Node.js NoFlo environment with NOFLO_PROJECT_ROOT env var (defaults to current working directory)
  • Support for loading graph definitions via AJAX on browser-based NoFlo
  • Support for delayed initialization of Subgraph components via ComponentLoader
  • Component instances now get the node's metadata passed to the getComponent function
  • New methods for manipulating Graph metadata:
    • setProperties
    • setInportMetadata
    • setOutportMetadata
    • setGroupMetadata
    • setNodeMetadata
    • setEdgeMetadata
  • Graph exports can now be renamed, and emit addExport, removeExport, and renameExport events
  • New Graph transaction API for grouping graph changes. Transactions can be observed
    • startTransaction
    • endTransaction
  • New Journal class, for following Graph changes and restoring earlier revisions. Currently supports undo and redo
  • New port API allowing better addressability and metadata
  • Graph's published ports are now declared in two separate inports and outports arrays to reduce ambiguity

With the new API component ports can be declared with:

@inPorts = new noflo.InPorts
@inPorts.add 'in', new noflo.InPort
  datatype: 'object'
  type: ''
  description: 'Persons to be processed'
  required: true
  buffered: true

The noflo.Ports objects emit add and remove events when ports change. They also support passing port information as options:

@outPorts = new noflo.OutPorts
  out: new noflo.OutPort
    datatype: 'object'
    type: ''
    description: 'Processed person objects'
    required: true
    addressable: true

The input ports also allow passing in an optional processing function that gets called on information packets events.

  • New component API allowing simpler component definition in both CoffeeScript and JavaScript:
var noflo = require('noflo');

exports.getComponent = function() {
  var c = new noflo.Component();

  c.inPorts.add('in', function(event, payload) {
    if (packet.event !== 'data')
    // Do something with the packet, then


  return c;
  • Support for dealing with component source code via ComponentLoader setSource and getSource methods

0.4.4 (February 4th 2014)

  • Support for CoffeeScript 1.7.x on Node.js

0.4.3 (December 6th 2013)

  • ArrayPorts with attached sockets now return true for isAttached checks. There is a separate canAttach method for checking whether more can be added
  • Icon support was added for both libraries and components using the set from Font Awesome
    • For libraries, register via the noflo.icon key in your package.json (Node.js libraries) or component.json (browser libraries)
    • For components, provide via the icon attribute
  • Subgraphs now support closing their internal NoFlo network via the shutdown method
  • Component Loader is able to load arbitrary graphs outside of the normal package manifest registration via the loadGraph method
  • Component Loader of the main NoFlo network is now carried across subgraphs instead of instantiating locally
  • Libraries can provide a custom loader for their components by registering a noflo.loader key in the manifest pointing to a CommonJS module
  • Exported ports can now contain metadata
  • It is possible to create named groups of nodes in a NoFlo graph, which can be useful for visual editors
  • Components have an error helper method for sending errors to the error outport, or throwing them if that isn't attached

0.4.2 (September 28th 2013)

  • Easier debugging: port errors now contain the name of the NoFlo graph node and the port

0.4.1 (September 25th 2013)

  • NoFlo components can now implement a shutdown method which is called when they're removed from a network
  • Graphs can contain additional metadata in the properties key
  • NoFlo networks have now a start and a stop method for starting and stopping execution

0.4.0 (July 31st 2013)

Browser support:

  • The NoFlo engine has been made available client-side via the Component system
  • New BDD tests written with Mocha that can be run on both browser and server

Changes to components:

Development tools:

  • Grunt scaffold for easily creating NoFlo component packages including cross-platform test automation

File format support:

  • NoFlo's internal FBP parser was removed in favor of the fbp package
  • The display property of nodes in the JSON format was removed in favor of the more flexible metadata object


  • Support for renaming nodes in a NoFlo graph via the renameNode method
  • Adding IIPs to a graph will now emit a addInitial event instead of an addEdge event
  • Graph's removeEdge method allows specifying both ends of the connection to prevent ambiguity
  • IIPs can now be removed using the removeInitial method, which fires a removeInitial event instead of removeEdge
  • NoFlo Networks now support delayed starting
  • The isBrowser method on the main NoFlo interface tells whether NoFlo is running under browser or Node.js
  • Support for running under Node.js on Windows

0.3.4 (July 5th 2013)


  • New LoggingComponent base class for component libraries

0.3.3 (April 9th 2013)


  • Build process was switched from Cake to Grunt
  • NoFlo is no longer tested against Node.js 0.6

0.3.2 (April 9th 2013)

NoFlo internals:

  • Ports now support optional type information, allowing editors to visualize compatible port types

    @inPorts =
      in: new noflo.ArrayPort 'object'
      times: new noflo.Port 'int'
    @outPorts =
      out: new noflo.Port 'string'
  • NoFlo ComponentLoader is now able to register new components and graphs and update package.json files accordingly

    loader = new noflo.ComponentLoader __dirname
    loader.registerComponent 'myproject', 'SayHello', './components/SayHello.json', (err) ->
      console.error err if err

New libraries:

  • noflo-test provides a framework for testing NoFlo components

0.3.1 (February 13th 2013)

NoFlo internals:

  • The NoFlo .fbp parser now guards against recursion on inline subgraphs
  • NoFlo subgraphs now inherit the directory context for component loading from the NoFlo process that loaded them
  • Exported ports in NoFlo graphs are now supported also in NoFlo-generated JSON files
  • Nodes in NoFlo graphs can now contain additional metadata to be used for visualization purposes. For example, in FBP format graphs:

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

    will cause both the Read and the Display node to contain a metadata.routes field with an array containing foo. Multiple routes can be specified by separating them with commas

New component libraries:

0.3.0 (December 19th 2012)

User interface:

  • NoFlo's web-based user interface has been moved to a separate noflo-ui repository
  • The noflo shell command now uses STDOUT for debug output (when invoked with --debug) instead of STDERR
    • Events from subgraphs are also visible when the noflo command is used with the additional -s switch
    • Contents of packets are shown when the noflo command is used with the additional -v switch
    • Shell debug output is no colorized for easier reading
  • DOT language output from NoFlo was made more comprehensive
  • NoFlo graphs can now alias their internal ports to more user-friendly names when used as subgraphs. When aliases are used, the other free ports are not exposed via the Graph component. This works in both FBP and JSON formats:

    For FBP format graphs:


    For JSON format graphs:

      "exports": [
          "private": "INTERNALPROCESS.PORT",
          "public": "EXTERNALPORT"

NoFlo internals:

  • All code was migrated from 4 spaces to 2 space indentation as recommended by CoffeeScript style guide. Our CI environment safeguards this via CoffeeLint
  • Events emitted by ArrayPorts now contain the socket number as a second parameter
  • Initial Information Packet sending was delayed by process.nextTick to ensure possible subgraphs are ready
  • The debug flag was removed from NoFlo Network class, and the networks were made EventEmitters for more flexible monitoring
  • The isSubgraph method tells whether a Component is a subgraph or a regular code component
  • Subgraphs loaded directly by ComponentLoader no longer expose their graph port
  • The addX methods of Graph now return the object that was added to the graph
  • NoFlo networks now emit start and end events
  • Component instances have the ID of the node available at the nodeId property
  • Empty strings and other falsy values are now allowed as contents of Initial Information Packets

Changes to core components:

  • ReadGroup now sends the group to a group outport, and original packet to out port
  • GetObjectKey can now send packets that don't contain the specified key to a missed port instead of dropping them
  • SetPropertyValue provides the group hierarchy received via its in port when sending packets out
  • Kick can now optionally send out the packet it received via its data port when receiving a disconnect on the in port. Its out port is now an ArrayPort
  • Concat only clears its buffers on disconnect when all inports have connected at least once
  • SplitStr accepts both regular expressions (starting and ending with a /) and strings for splitting
  • ReadDir and Stat are now AsyncComponents that can be throttled

New core components:

  • MakeDir creates a directory at a given path
  • DirName sends the directory name for a given file path
  • CopyFile copies the file behind the path received via the source port to the path received via the destination port
  • FilterPacket allows filtering packets by regular expressions sent to the regexp port. Non-matching packets are sent to the missed port
  • FirstGroup allows you to limit group hierarchies of packets to a single level
  • LastPacket sends the last packet it received when getting a disconnect to the inport
  • MergeGroups collects grouped packets from its inports, and sends them out together once each inport has sent data with the same grouping
  • SimplifyObject simplifies the object structures outputted by the CollectGroups component
  • CountSum sums together numbers received from different inports and sends the total out
  • SplitInSequence sends each packet to only one of its outports, going through them in sequence
  • CollectUntilIdle collects packets it receives, waits a given time if there are new packets, and if not, sends them out

New component libraries:

0.2.0 (November 13th 2012)

The main change in 0.2 series was component packaging support and the fact that most component with external dependencies were moved to their own NPM packages:

To use the components, install the corresponding NPM package and change the component's name in your graph to include the package namespace. For example, yaml/ParseYaml for the ParseYaml component in the noflo-yaml package

User interface:

  • The noflo command-line tool now has a new list command for listing components available for a given directory, for example: $ noflo list .

NoFlo internals:

  • New ComponentLoader to support loading components and subgraphs to installed NPM modules
  • NoFlo's own codebase was moved to direct requires making the NPM installation simpler
  • daemon dependency was removed from NoFlo's command-line tools

Changes to core components:

  • Merge only disconnects once all of its inports have disconnected
  • Concat only disconnects once all of its inports have disconnected
  • CompileString's in port is now an ArrayPort
  • GroupByObjectKey also supports boolean values for the matched keys
  • ReadDir disconnects after reading a directory

New core components:

  • Drop allows explicitly dropping packets in a graph. The component performs no operations on the data it receives