Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

noflo

Package Overview
Dependencies
Maintainers
1
Versions
91
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

noflo - npm Package Compare versions

Comparing version 1.1.3 to 1.2.0

.eslintrc.json

12

CHANGES.md
NoFlo ChangeLog
===============
## 1.2.0 (August 28th 2020)
* Ported NoFlo from CoffeeScript to ES6
* Deprecated constructing networks with `new noflo.Network`. Use `noflo.createNetwork` instead, with the following options available:
- `subscribeGraph: true`: Uses `LegacyNetwork` which modifies network topology based on changes in graph. This can cause some types of errors to be silent.
- `subscribeGraph: false`: Uses `Network`: network topology can be changed with network's methods (`addNode`, `removeEdge`, etc) and will be also written to the graph.
For backwards compatibility reasons, `subscribeGraph` defaults to `true`. Adapt your applications to use `false` instead and start utilizing Network methods for any changes to a running graph.
* Added support for a more standard `noflo.createNetwork(graph, options, callback)` signature, with backwards compatibility for the legacy `noflo.createNetwork(graph, callback, options)` signature
* Removed support for `noflo.WirePattern`. WirePattern has been deprecated since 1.0, and all code using it should be migrated to the latest Process API
* Removed support for changing component icon and description statically (on class level) at run-time (i.e. `ComponentName::icon = 'new-icon'`). Component icon and description should be set in class constructor or in `getComponent` instead. Changing icon and description for a specific instance (process) is not affected and is fully supported
* Added optional `networkCallback` option for `noflo.asCallback` to provide access to the network instance for debugging purposes
## 1.1.3 (April 12th 2018)

@@ -5,0 +17,0 @@

512

components/Graph.js

@@ -0,1 +1,25 @@

"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
// NoFlo - Flow-Based Programming for JavaScript

@@ -6,20 +30,30 @@ // (c) 2013-2017 Flowhub UG

// The Graph component is used to wrap NoFlo Networks into components inside
/* eslint-disable
class-methods-use-this,
import/no-unresolved,
*/
var noflo = require('../lib/NoFlo'); // The Graph component is used to wrap NoFlo Networks into components inside
// another network.
var Graph, noflo;
noflo = require("../lib/NoFlo");
Graph = class Graph extends noflo.Component {
constructor(metadata) {
super();
this.metadata = metadata;
this.network = null;
this.ready = true;
this.started = false;
this.starting = false;
this.baseDir = null;
this.loader = null;
this.load = 0;
this.inPorts = new noflo.InPorts({
var Graph = /*#__PURE__*/function (_noflo$Component) {
_inherits(Graph, _noflo$Component);
var _super = _createSuper(Graph);
function Graph(metadata) {
var _this;
_classCallCheck(this, Graph);
_this = _super.call(this);
_this.metadata = metadata;
_this.network = null;
_this.ready = true;
_this.started = false;
_this.starting = false;
_this.baseDir = null;
_this.loader = null;
_this.load = 0;
_this.inPorts = new noflo.InPorts({
graph: {

@@ -31,231 +65,315 @@ datatype: 'all',

});
this.outPorts = new noflo.OutPorts;
this.inPorts.graph.on('ip', (packet) => {
_this.outPorts = new noflo.OutPorts();
_this.inPorts.graph.on('ip', function (packet) {
if (packet.type !== 'data') {
return;
}
return this.setGraph(packet.data, (err) => {
_this.setGraph(packet.data, function (err) {
// TODO: Port this part to Process API and use output.error method instead
if (err) {
// TODO: Port this part to Process API and use output.error method instead
return this.error(err);
_this.error(err);
}
});
});
return _this;
}
setGraph(graph, callback) {
this.ready = false;
if (typeof graph === 'object') {
if (typeof graph.addNode === 'function') {
// Existing Graph object
this.createNetwork(graph, callback);
_createClass(Graph, [{
key: "setGraph",
value: function setGraph(graph, callback) {
var _this2 = this;
this.ready = false;
if (_typeof(graph) === 'object') {
if (typeof graph.addNode === 'function') {
// Existing Graph object
this.createNetwork(graph, callback);
return;
} // JSON definition of a graph
noflo.graph.loadJSON(graph, function (err, instance) {
var inst = instance;
if (err) {
callback(err);
return;
}
inst.baseDir = _this2.baseDir;
_this2.createNetwork(inst, callback);
});
return;
}
// JSON definition of a graph
noflo.graph.loadJSON(graph, (err, instance) => {
var graphName = graph;
if (graphName.substr(0, 1) !== '/' && graphName.substr(1, 1) !== ':' && process && process.cwd) {
graphName = "".concat(process.cwd(), "/").concat(graphName);
}
noflo.graph.loadFile(graphName, function (err, instance) {
var inst = instance;
if (err) {
return callback(err);
callback(err);
return;
}
instance.baseDir = this.baseDir;
return this.createNetwork(instance, callback);
inst.baseDir = _this2.baseDir;
_this2.createNetwork(inst, callback);
});
return;
}
if (graph.substr(0, 1) !== "/" && graph.substr(1, 1) !== ":" && process && process.cwd) {
graph = `${process.cwd()}/${graph}`;
}
return noflo.graph.loadFile(graph, (err, instance) => {
if (err) {
return callback(err);
}, {
key: "createNetwork",
value: function createNetwork(graph, callback) {
var _this3 = this;
this.description = graph.properties.description || '';
this.icon = graph.properties.icon || this.icon;
var graphObj = graph;
if (!graphObj.name) {
graphObj.name = this.nodeId;
}
instance.baseDir = this.baseDir;
return this.createNetwork(instance, callback);
});
}
createNetwork(graph, callback) {
this.description = graph.properties.description || '';
this.icon = graph.properties.icon || this.icon;
if (!graph.name) {
graph.name = this.nodeId;
}
graph.componentLoader = this.loader;
return noflo.createNetwork(graph, (err, network1) => {
this.network = network1;
if (err) {
return callback(err);
}
this.emit('network', this.network);
// Subscribe to network lifecycle
this.subscribeNetwork(this.network);
// Wire the network up
return this.network.connect((err) => {
var name, node, ref;
graphObj.componentLoader = this.loader;
noflo.createNetwork(graphObj, {
delay: true,
subscribeGraph: false
}, function (err, network) {
_this3.network = network;
if (err) {
return callback(err);
callback(err);
return;
}
ref = this.network.processes;
for (name in ref) {
node = ref[name];
// Map exported ports to local component
this.findEdgePorts(name, node);
_this3.emit('network', _this3.network); // Subscribe to network lifecycle
_this3.subscribeNetwork(_this3.network); // Wire the network up
_this3.network.connect(function (err2) {
if (err2) {
callback(err2);
return;
}
Object.keys(_this3.network.processes).forEach(function (name) {
// Map exported ports to local component
var node = _this3.network.processes[name];
_this3.findEdgePorts(name, node);
}); // Finally set ourselves as "ready"
_this3.setToReady();
callback();
});
});
}
}, {
key: "subscribeNetwork",
value: function subscribeNetwork() {
var _this4 = this;
var contexts = [];
this.network.on('start', function () {
var ctx = {};
contexts.push(ctx);
return _this4.activate(ctx);
});
return this.network.on('end', function () {
var ctx = contexts.pop();
if (!ctx) {
return;
}
// Finally set ourselves as "ready"
this.setToReady();
return callback();
_this4.deactivate(ctx);
});
}, true);
}
}
}, {
key: "isExportedInport",
value: function isExportedInport(port, nodeName, portName) {
// First we check disambiguated exported ports
var keys = Object.keys(this.network.graph.inports);
subscribeNetwork(network) {
var contexts;
contexts = [];
this.network.on('start', () => {
var ctx;
ctx = {};
contexts.push(ctx);
return this.activate(ctx);
});
return this.network.on('end', () => {
var ctx;
ctx = contexts.pop();
if (!ctx) {
return;
}
return this.deactivate(ctx);
});
}
for (var i = 0; i < keys.length; i += 1) {
var pub = keys[i];
var priv = this.network.graph.inports[pub];
isExportedInport(port, nodeName, portName) {
var priv, pub, ref;
ref = this.network.graph.inports;
// First we check disambiguated exported ports
for (pub in ref) {
priv = ref[pub];
if (!(priv.process === nodeName && priv.port === portName)) {
continue;
}
return pub;
if (priv.process === nodeName && priv.port === portName) {
return pub;
}
} // Component has exported ports and this isn't one of them
return false;
}
// Component has exported ports and this isn't one of them
return false;
}
}, {
key: "isExportedOutport",
value: function isExportedOutport(port, nodeName, portName) {
// First we check disambiguated exported ports
var keys = Object.keys(this.network.graph.outports);
isExportedOutport(port, nodeName, portName) {
var priv, pub, ref;
ref = this.network.graph.outports;
// First we check disambiguated exported ports
for (pub in ref) {
priv = ref[pub];
if (!(priv.process === nodeName && priv.port === portName)) {
continue;
}
return pub;
for (var i = 0; i < keys.length; i += 1) {
var pub = keys[i];
var priv = this.network.graph.outports[pub];
if (priv.process === nodeName && priv.port === portName) {
return pub;
}
} // Component has exported ports and this isn't one of them
return false;
}
// Component has exported ports and this isn't one of them
return false;
}
}, {
key: "setToReady",
value: function setToReady() {
var _this5 = this;
setToReady() {
if (typeof process !== 'undefined' && process.execPath && process.execPath.indexOf('node') !== -1) {
return process.nextTick(() => {
this.ready = true;
return this.emit('ready');
});
} else {
return setTimeout(() => {
this.ready = true;
return this.emit('ready');
}, 0);
if (typeof process !== 'undefined' && process.execPath && process.execPath.indexOf('node') !== -1) {
process.nextTick(function () {
_this5.ready = true;
return _this5.emit('ready');
});
} else {
setTimeout(function () {
_this5.ready = true;
return _this5.emit('ready');
}, 0);
}
}
}
}, {
key: "findEdgePorts",
value: function findEdgePorts(name, process) {
var _this6 = this;
findEdgePorts(name, process) {
var inPorts, outPorts, port, portName, targetPortName;
inPorts = process.component.inPorts.ports;
outPorts = process.component.outPorts.ports;
for (portName in inPorts) {
port = inPorts[portName];
targetPortName = this.isExportedInport(port, name, portName);
if (targetPortName === false) {
continue;
}
this.inPorts.add(targetPortName, port);
this.inPorts[targetPortName].on('connect', () => {
// Start the network implicitly if we're starting to get data
if (this.starting) {
var inPorts = process.component.inPorts.ports;
var outPorts = process.component.outPorts.ports;
Object.keys(inPorts).forEach(function (portName) {
var port = inPorts[portName];
var targetPortName = _this6.isExportedInport(port, name, portName);
if (targetPortName === false) {
return;
}
if (this.network.isStarted()) {
_this6.inPorts.add(targetPortName, port);
_this6.inPorts[targetPortName].on('connect', function () {
// Start the network implicitly if we're starting to get data
if (_this6.starting) {
return;
}
if (_this6.network.isStarted()) {
return;
}
if (_this6.network.startupDate) {
// Network was started, but did finish. Re-start simply
_this6.network.setStarted(true);
return;
} // Network was never started, start properly
_this6.setUp(function () {});
});
});
Object.keys(outPorts).forEach(function (portName) {
var port = outPorts[portName];
var targetPortName = _this6.isExportedOutport(port, name, portName);
if (targetPortName === false) {
return;
}
if (this.network.startupDate) {
// Network was started, but did finish. Re-start simply
this.network.setStarted(true);
return;
}
// Network was never started, start properly
return this.setUp(function() {});
_this6.outPorts.add(targetPortName, port);
});
return true;
}
for (portName in outPorts) {
port = outPorts[portName];
targetPortName = this.isExportedOutport(port, name, portName);
if (targetPortName === false) {
continue;
}
this.outPorts.add(targetPortName, port);
}, {
key: "isReady",
value: function isReady() {
return this.ready;
}
return true;
}
}, {
key: "isSubgraph",
value: function isSubgraph() {
return true;
}
}, {
key: "isLegacy",
value: function isLegacy() {
return false;
}
}, {
key: "setUp",
value: function setUp(callback) {
var _this7 = this;
isReady() {
return this.ready;
}
this.starting = true;
isSubgraph() {
return true;
}
if (!this.isReady()) {
this.once('ready', function () {
_this7.setUp(callback);
});
return;
}
isLegacy() {
return false;
}
if (!this.network) {
callback(null);
return;
}
setUp(callback) {
this.starting = true;
if (!this.isReady()) {
this.once('ready', () => {
return this.setUp(callback);
this.network.start(function (err) {
if (err) {
callback(err);
return;
}
_this7.starting = false;
callback();
});
return;
}
if (!this.network) {
return callback(null);
}
return this.network.start((err) => {
if (err) {
return callback(err);
}
}, {
key: "tearDown",
value: function tearDown(callback) {
this.starting = false;
return callback();
});
}
tearDown(callback) {
this.starting = false;
if (!this.network) {
return callback(null);
}
return this.network.stop(function(err) {
if (err) {
return callback(err);
if (!this.network) {
callback(null);
return;
}
return callback();
});
}
};
this.network.stop(function (err) {
if (err) {
callback(err);
return;
}
exports.getComponent = function(metadata) {
callback();
});
}
}]);
return Graph;
}(noflo.Component);
exports.getComponent = function (metadata) {
return new Graph(metadata);
};
};

@@ -0,25 +1,32 @@

"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
// NoFlo - Flow-Based Programming for JavaScript
// (c) 2017-2018 Flowhub UG
// NoFlo may be freely distributed under the MIT license
var ComponentLoader, Graph, IP, Network, getType, internalSocket, normalizeOptions, normalizeOutput, prepareInputMap, prepareNetwork, runNetwork, sendOutputMap;
ComponentLoader = require('./ComponentLoader').ComponentLoader;
/* eslint-disable
no-param-reassign,
*/
var _require = require('fbp-graph'),
Graph = _require.Graph;
Network = require('./Network').Network;
var _require2 = require('./ComponentLoader'),
ComponentLoader = _require2.ComponentLoader;
IP = require('./IP');
var _require3 = require('./Network'),
Network = _require3.Network;
internalSocket = require('./InternalSocket');
var IP = require('./IP');
Graph = require('fbp-graph').Graph;
// ## asCallback embedding API
var internalSocket = require('./InternalSocket'); // ## asCallback embedding API
//
// asCallback is a helper for embedding NoFlo components or
// graphs in other JavaScript programs.
//
// By using the `noflo.asCallback` function, you can turn any
// NoFlo component or NoFlo Graph instance into a regular,
// Node.js-style JavaScript function.
//
// Each call to that function starts a new NoFlo network where

@@ -29,8 +36,7 @@ // the given input arguments are sent as IP objects to matching

// from the network will be sent to the callback function.
//
// If there was anything sent to an `error` outport, this will
// be provided as the error argument to the callback.
// ### Option normalization
//
// Here we handle the input valus given to the `asCallback`

@@ -40,101 +46,111 @@ // function. This allows passing things like a pre-initialized

// baseDir context.
normalizeOptions = function(options, component) {
function normalizeOptions(options, component) {
if (!options) {
options = {};
}
if (!options.name) {
options.name = component;
}
if (options.loader) {
options.baseDir = options.loader.baseDir;
}
if (!options.baseDir && process && process.cwd) {
options.baseDir = process.cwd();
}
if (!options.loader) {
options.loader = new ComponentLoader(options.baseDir);
}
if (!options.raw) {
options.raw = false;
}
return options;
};
// ### Network preparation
} // ### Network preparation
//
// Each invocation of the asCallback-wrapped NoFlo graph
// creates a new network. This way we can isolate multiple
// executions of the function in their own contexts.
prepareNetwork = function(component, options, callback) {
function prepareNetwork(component, options, callback) {
// If we were given a graph instance, then just create a network
var network;
// If we were given a graph instance, then just create a network
if (typeof component === 'object') {
if (_typeof(component) === 'object') {
component.componentLoader = options.loader;
network = new Network(component, options);
// Wire the network up
network.connect(function(err) {
network = new Network(component, options); // Wire the network up
network.connect(function (err) {
if (err) {
return callback(err);
callback(err);
return;
}
return callback(null, network);
callback(null, network);
});
return;
}
// Start by loading the component
return options.loader.load(component, function(err, instance) {
var def, graph, inPorts, nodeName, outPorts, port;
} // Start by loading the component
options.loader.load(component, function (err, instance) {
if (err) {
return callback(err);
}
// Prepare a graph wrapping the component
graph = new Graph(options.name);
nodeName = options.name;
graph.addNode(nodeName, component);
// Expose ports
inPorts = instance.inPorts.ports;
outPorts = instance.outPorts.ports;
for (port in inPorts) {
def = inPorts[port];
callback(err);
return;
} // Prepare a graph wrapping the component
var graph = new Graph(options.name);
var nodeName = options.name;
graph.addNode(nodeName, component); // Expose ports
var inPorts = instance.inPorts.ports;
var outPorts = instance.outPorts.ports;
Object.keys(inPorts).forEach(function (port) {
graph.addInport(port, nodeName, port);
}
for (port in outPorts) {
def = outPorts[port];
});
Object.keys(outPorts).forEach(function (port) {
graph.addOutport(port, nodeName, port);
}
// Prepare network
}); // Prepare network
graph.componentLoader = options.loader;
network = new Network(graph, options);
// Wire the network up and start execution
return network.connect(function(err) {
if (err) {
return callback(err);
network = new Network(graph, options); // Wire the network up and start execution
network.connect(function (err2) {
if (err2) {
callback(err2);
return;
}
return callback(null, network);
callback(null, network);
});
});
};
// ### Network execution
} // ### Network execution
//
// Once network is ready, we connect to all of its exported
// in and outports and start the network.
//
// Input data is sent to the inports, and we collect IP
// packets received on the outports.
//
// Once the network finishes, we send the resulting IP
// objects to the callback.
runNetwork = function(network, inputs, options, callback) {
var inPorts, inSockets, outPorts, outSockets, received;
function runNetwork(network, inputs, options, callback) {
// Prepare inports
inPorts = Object.keys(network.graph.inports);
inSockets = {};
// Subscribe outports
received = [];
outPorts = Object.keys(network.graph.outports);
outSockets = {};
outPorts.forEach(function(outport) {
var portDef, process;
portDef = network.graph.outports[outport];
process = network.getNode(portDef.process);
var inSockets = {}; // Subscribe outports
var received = [];
var outPorts = Object.keys(network.graph.outports);
var outSockets = {};
outPorts.forEach(function (outport) {
var portDef = network.graph.outports[outport];
var process = network.getNode(portDef.process);
outSockets[outport] = internalSocket.createSocket();

@@ -146,78 +162,104 @@ process.component.outPorts[portDef.port].attach(outSockets[outport]);

};
return outSockets[outport].on('ip', function(ip) {
var res;
res = {};
outSockets[outport].on('ip', function (ip) {
var res = {};
res[outport] = ip;
return received.push(res);
received.push(res);
});
});
// Subscribe network finish
network.once('end', function() {
var port, socket;
// Clear listeners
for (port in outSockets) {
socket = outSockets[port];
}); // Subscribe to process errors
var onEnd = null;
var onError = null;
onError = function onError(err) {
callback(err.error);
network.removeListener('end', onEnd);
};
network.once('process-error', onError); // Subscribe network finish
onEnd = function onEnd() {
// Clear listeners
Object.keys(outSockets).forEach(function (port) {
var socket = outSockets[port];
socket.from.process.component.outPorts[socket.from.port].detach(socket);
}
});
outSockets = {};
inSockets = {};
return callback(null, received);
});
// Start network
return network.start(function(err) {
var i, inputMap, len, port, portDef, process, results, value;
callback(null, received);
network.removeListener('process-error', onError);
};
network.once('end', onEnd); // Start network
network.start(function (err) {
if (err) {
return callback(err);
}
// Send inputs
results = [];
for (i = 0, len = inputs.length; i < len; i++) {
inputMap = inputs[i];
results.push((function() {
var results1;
results1 = [];
for (port in inputMap) {
value = inputMap[port];
if (!inSockets[port]) {
portDef = network.graph.inports[port];
process = network.getNode(portDef.process);
inSockets[port] = internalSocket.createSocket();
process.component.inPorts[portDef.port].attach(inSockets[port]);
}
callback(err);
return;
} // Send inputs
for (var i = 0; i < inputs.length; i += 1) {
var inputMap = inputs[i];
var keys = Object.keys(inputMap);
for (var j = 0; j < keys.length; j += 1) {
var port = keys[j];
var value = inputMap[port];
if (!inSockets[port]) {
var portDef = network.graph.inports[port];
var _process = network.getNode(portDef.process);
inSockets[port] = internalSocket.createSocket();
_process.component.inPorts[portDef.port].attach(inSockets[port]);
}
try {
if (IP.isIP(value)) {
inSockets[port].post(value);
continue;
} else {
inSockets[port].post(new IP('data', value));
}
results1.push(inSockets[port].post(new IP('data', value)));
} catch (e) {
callback(e);
network.removeListener('process-error', onError);
network.removeListener('end', onEnd);
return;
}
return results1;
})());
}
}
return results;
});
};
}
getType = function(inputs, network) {
var key, maps, value;
if (typeof inputs !== 'object') {
// Scalar values are always simple inputs
function getType(inputs, network) {
// Scalar values are always simple inputs
if (_typeof(inputs) !== 'object') {
return 'simple';
}
if (Array.isArray(inputs)) {
maps = inputs.filter(function(entry) {
var maps = inputs.filter(function (entry) {
return getType(entry, network) === 'map';
});
}); // If each member if the array is an input map, this is a sequence
if (maps.length === inputs.length) {
// If each member if the array is an input map, this is a sequence
return 'sequence';
}
// Otherwise arrays must be simple inputs
} // Otherwise arrays must be simple inputs
return 'simple';
}
if (!Object.keys(inputs).length) {
// Empty objects can't be maps
} // Empty objects can't be maps
var keys = Object.keys(inputs);
if (!keys.length) {
return 'simple';
}
for (key in inputs) {
value = inputs[key];
for (var i = 0; i < keys.length; i += 1) {
var key = keys[i];
if (!network.graph.inports[key]) {

@@ -227,36 +269,38 @@ return 'simple';

}
return 'map';
};
}
prepareInputMap = function(inputs, inputType, network) {
var inPort, map;
function prepareInputMap(inputs, inputType, network) {
// Sequence we can use as-is
if (inputType === 'sequence') {
// Sequence we can use as-is
return inputs;
}
} // We can turn a map to a sequence by wrapping it in an array
if (inputType === 'map') {
// We can turn a map to a sequence by wrapping it in an array
return [inputs];
}
// Simple inputs need to be converted to a sequence
inPort = Object.keys(network.graph.inports)[0];
if (network.graph.inports.in) {
// If we have a port named "IN", send to that
} // Simple inputs need to be converted to a sequence
var inPort = Object.keys(network.graph.inports)[0]; // If we have a port named "IN", send to that
if (network.graph.inports["in"]) {
inPort = 'in';
}
map = {};
var map = {};
map[inPort] = inputs;
return [map];
};
}
normalizeOutput = function(values, options) {
var current, i, len, packet, previous, result;
function normalizeOutput(values, options) {
if (options.raw) {
return values;
}
result = [];
previous = null;
current = result;
for (i = 0, len = values.length; i < len; i++) {
packet = values[i];
var result = [];
var previous = null;
var current = result;
values.forEach(function (packet) {
if (packet.type === 'openBracket') {

@@ -267,91 +311,113 @@ previous = current;

}
if (packet.type === 'data') {
current.push(packet.data);
}
if (packet.type === 'closeBracket') {
current = previous;
}
}
});
if (result.length === 1) {
return result[0];
}
return result;
};
}
sendOutputMap = function(outputs, resultType, options, callback) {
var errors, i, key, len, map, mappedOutputs, outputKeys, packets, port, result, val, withValue;
function sendOutputMap(outputs, resultType, options, callback) {
// First check if the output sequence contains errors
errors = outputs.filter(function(map) {
var errors = outputs.filter(function (map) {
return map.error != null;
}).map(function(map) {
}).map(function (map) {
return map.error;
});
if (errors.length) {
return callback(normalizeOutput(errors, options));
callback(normalizeOutput(errors, options));
return;
}
if (resultType === 'sequence') {
return callback(null, outputs.map(function(map) {
var key, res, val;
res = {};
for (key in map) {
val = map[key];
callback(null, outputs.map(function (map) {
var res = {};
Object.keys(map).forEach(function (key) {
var val = map[key];
if (options.raw) {
res[key] = val;
continue;
return;
}
res[key] = normalizeOutput([val], options);
}
});
return res;
}));
}
// Flatten the sequence
mappedOutputs = {};
for (i = 0, len = outputs.length; i < len; i++) {
map = outputs[i];
for (key in map) {
val = map[key];
return;
} // Flatten the sequence
var mappedOutputs = {};
outputs.forEach(function (map) {
Object.keys(map).forEach(function (key) {
var val = map[key];
if (!mappedOutputs[key]) {
mappedOutputs[key] = [];
}
mappedOutputs[key].push(val);
}
}
outputKeys = Object.keys(mappedOutputs);
withValue = outputKeys.filter(function(outport) {
});
});
var outputKeys = Object.keys(mappedOutputs);
var withValue = outputKeys.filter(function (outport) {
return mappedOutputs[outport].length > 0;
});
if (withValue.length === 0) {
// No output
return callback(null);
callback(null);
return;
}
if (withValue.length === 1 && resultType === 'simple') {
// Single outport
return callback(null, normalizeOutput(mappedOutputs[withValue[0]], options));
callback(null, normalizeOutput(mappedOutputs[withValue[0]], options));
return;
}
result = {};
for (port in mappedOutputs) {
packets = mappedOutputs[port];
var result = {};
Object.keys(mappedOutputs).forEach(function (port) {
var packets = mappedOutputs[port];
result[port] = normalizeOutput(packets, options);
}
return callback(null, result);
};
});
callback(null, result);
}
exports.asCallback = function(component, options) {
exports.asCallback = function asCallback(component, options) {
options = normalizeOptions(options, component);
return function(inputs, callback) {
return prepareNetwork(component, options, function(err, network) {
var inputMap, resultType;
return function (inputs, callback) {
prepareNetwork(component, options, function (err, network) {
if (err) {
return callback(err);
callback(err);
return;
}
resultType = getType(inputs, network);
inputMap = prepareInputMap(inputs, resultType, network);
return runNetwork(network, inputMap, options, function(err, outputMap) {
if (err) {
return callback(err);
if (options.networkCallback) {
options.networkCallback(network);
}
var resultType = getType(inputs, network);
var inputMap = prepareInputMap(inputs, resultType, network);
runNetwork(network, inputMap, options, function (err2, outputMap) {
if (err2) {
callback(err2);
return;
}
return sendOutputMap(outputMap, resultType, options, callback);
sendOutputMap(outputMap, resultType, options, callback);
});
});
};
};
};

@@ -0,15 +1,28 @@

"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
// NoFlo - Flow-Based Programming for JavaScript
// (c) 2018 Flowhub UG
// NoFlo may be freely distributed under the MIT license
var Component, getParams;
var getParams = require('get-function-params');
getParams = require('get-function-params');
({Component} = require('./Component'));
// ## asComponent generator API
var _require = require('./Component'),
Component = _require.Component; // ## asComponent generator API
//
// asComponent is a helper for turning JavaScript functions into
// NoFlo components.
//
// Each call to this function returns a component instance where

@@ -19,11 +32,14 @@ // the input parameters of the given function are converted into

// results of the function execution.
//
// Variants supported:
// * Regular synchronous functions: return value gets sent to `out`. Thrown errors get sent to `error`
// * Functions returning a Promise: resolved promises get sent to `out`, rejected promises to `error`
// * Functions taking a Node.js style asynchronous callback: `err` argument to callback gets sent to `error`, result gets sent to `out`
//
// * Regular synchronous functions: return value gets sent to `out`.
// Thrown errors get sent to `error`
// * Functions returning a Promise: resolved promises get sent to `out`,
// rejected promises to `error`
// * Functions taking a Node.js style asynchronous callback: `err` argument
// to callback gets sent to `error`, result gets sent to `out`
//
// Usage example:
//
// exports.getComponent = function () {

@@ -34,11 +50,11 @@ // return noflo.asComponent(Math.random, {

// };
//
// ### Wrapping built-in functions
// Built-in JavaScript functions don't make their arguments introspectable. Because of this, these
// cannot be directly converted to components. You'll have to provide a wrapper JavaScript function to make
// the arguments appear as ports.
//
// Built-in JavaScript functions don't make their arguments introspectable.
// Because of this, these cannot be directly converted to components.
// You'll have to provide a wrapper JavaScript function to make the arguments appear as ports.
//
// Example:
//
// exports.getComponent = function () {

@@ -52,33 +68,38 @@ // return noflo.asComponent(function (selector) {

// };
//
// ### Default values
//
// Function arguments with a default value are supported in ES6 environments.
// The default arguments are visible via the component's port interface.
//
// However, ES5 transpilation doesn't work with default values.
// In these cases the port with a default won't be visible. It is
// recommended to use default values only with components that don't need to run in legacy browsers.
// Function arguments with a default value are supported in ES6 environments. The default arguments are visible via the component's
// port interface.
// However, ES5 transpilation doesn't work with default values. In these cases the port with a default won't be visible. It is
// recommended to use default values only with components that don't need to run in legacy browsers.
exports.asComponent = function(func, options) {
var c, hasCallback, i, len, p, params, portOptions;
hasCallback = false;
params = getParams(func).filter(function(p) {
exports.asComponent = function asComponent(func, options) {
var hasCallback = false;
var params = getParams(func).filter(function (p) {
if (p.param !== 'callback') {
return true;
}
hasCallback = true;
return false;
});
c = new Component(options);
for (i = 0, len = params.length; i < len; i++) {
p = params[i];
portOptions = {
var c = new Component(options);
params.forEach(function (p) {
var portOptions = {
required: true
};
if (typeof p.default !== 'undefined') {
portOptions.default = p.default;
if (typeof p["default"] !== 'undefined') {
portOptions["default"] = p["default"];
portOptions.required = false;
}
c.inPorts.add(p.param, portOptions);
c.forwardBrackets[p.param] = ['out', 'error'];
}
});
if (!params.length) {

@@ -89,9 +110,12 @@ c.inPorts.add('in', {

}
c.outPorts.add('out');
c.outPorts.add('error');
c.process(function(input, output) {
var j, len1, res, values;
c.process(function (input, output) {
var values;
if (params.length) {
for (j = 0, len1 = params.length; j < len1; j++) {
p = params[j];
for (var i = 0; i < params.length; i += 1) {
var p = params[i];
if (!input.hasData(p.param)) {

@@ -101,3 +125,4 @@ return;

}
values = params.map(function(p) {
values = params.map(function (p) {
return input.getData(p.param);

@@ -109,22 +134,28 @@ });

}
input.getData('in');
values = [];
}
if (hasCallback) {
// Handle Node.js style async functions
values.push(function(err, res) {
values.push(function (err, res) {
if (err) {
return output.done(err);
output.done(err);
return;
}
return output.sendDone(res);
output.sendDone(res);
});
res = func.apply(null, values);
func.apply(void 0, _toConsumableArray(values));
return;
}
res = func.apply(null, values);
if (res && typeof res === 'object' && typeof res.then === 'function') {
var res = func.apply(void 0, _toConsumableArray(values));
if (res && _typeof(res) === 'object' && typeof res.then === 'function') {
// Result is a Promise, resolve and handle
res.then(function(val) {
res.then(function (val) {
return output.sendDone(val);
}, function(err) {
}, function (err) {
return output.done(err);

@@ -134,5 +165,6 @@ });

}
return output.sendDone(res);
output.sendDone(res);
});
return c;
};
};

@@ -0,186 +1,260 @@

"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
// NoFlo - Flow-Based Programming for JavaScript
// (c) 2014-2017 Flowhub UG
// NoFlo may be freely distributed under the MIT license
var BasePort, EventEmitter, validTypes;
var _require = require('events'),
EventEmitter = _require.EventEmitter; // ## NoFlo Port Base class
//
// Base port type used for options normalization. Both inports and outports extend this class.
// The list of valid datatypes for ports.
({EventEmitter} = require('events'));
// ## NoFlo Port Base class
var validTypes = ['all', 'string', 'number', 'int', 'object', 'array', 'boolean', 'color', 'date', 'bang', 'function', 'buffer', 'stream'];
// Base port type used for options normalization. Both inports and outports extend this class.
function handleOptions() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
// We default to the `all` type if no explicit datatype
// was provided
var datatype = options.datatype || 'all'; // Normalize the legacy `integer` type to `int`.
// The list of valid datatypes for ports.
validTypes = ['all', 'string', 'number', 'int', 'object', 'array', 'boolean', 'color', 'date', 'bang', 'function', 'buffer', 'stream'];
if (datatype === 'integer') {
datatype = 'int';
} // By default ports are not required for graph execution
BasePort = class BasePort extends EventEmitter {
constructor(options) {
super();
// Options holds all options of the current port
this.options = this.handleOptions(options);
// Sockets list contains all currently attached
var required = options.required || false; // Ensure datatype defined for the port is valid
if (validTypes.indexOf(datatype) === -1) {
throw new Error("Invalid port datatype '".concat(datatype, "' specified, valid are ").concat(validTypes.join(', ')));
} // Ensure schema defined for the port is valid
var schema = options.schema || options.type;
if (schema && schema.indexOf('/') === -1) {
throw new Error("Invalid port schema '".concat(schema, "' specified. Should be URL or MIME type"));
}
/* eslint-disable prefer-object-spread */
return Object.assign({}, options, {
datatype: datatype,
required: required,
schema: schema
});
}
module.exports = /*#__PURE__*/function (_EventEmitter) {
_inherits(BasePort, _EventEmitter);
var _super = _createSuper(BasePort);
function BasePort(options) {
var _this;
_classCallCheck(this, BasePort);
_this = _super.call(this); // Options holds all options of the current port
_this.options = handleOptions(options); // Sockets list contains all currently attached
// connections to the port
this.sockets = [];
// Name of the graph node this port is in
this.node = null;
// Name of the port
this.name = null;
_this.sockets = []; // Name of the graph node this port is in
_this.node = null; // Name of the port
_this.name = null;
return _this;
}
handleOptions(options) {
if (!options) {
options = {};
_createClass(BasePort, [{
key: "getId",
value: function getId() {
if (!this.node || !this.name) {
return 'Port';
}
return "".concat(this.node, " ").concat(this.name.toUpperCase());
}
if (!options.datatype) {
// We default to the `all` type if no explicit datatype
// was provided
options.datatype = 'all';
}, {
key: "getDataType",
value: function getDataType() {
return this.options.datatype;
}
if (options.required === void 0) {
// By default ports are not required for graph execution
options.required = false;
}, {
key: "getSchema",
value: function getSchema() {
return this.options.schema || null;
}
if (options.datatype === 'integer') {
// Normalize the legacy `integer` type to `int`.
options.datatype = 'int';
}, {
key: "getDescription",
value: function getDescription() {
return this.options.description;
}
// Ensure datatype defined for the port is valid
if (validTypes.indexOf(options.datatype) === -1) {
throw new Error(`Invalid port datatype '${options.datatype}' specified, valid are ${validTypes.join(', ')}`);
}
// Ensure schema defined for the port is valid
if (options.type && !options.schema) {
options.schema = options.type;
delete options.type;
}
if (options.schema && options.schema.indexOf('/') === -1) {
throw new Error(`Invalid port schema '${options.schema}' specified. Should be URL or MIME type`);
}
return options;
}
}, {
key: "attach",
value: function attach(socket) {
var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var idx = index;
getId() {
if (!(this.node && this.name)) {
return 'Port';
if (!this.isAddressable() || index === null) {
idx = this.sockets.length;
}
this.sockets[idx] = socket;
this.attachSocket(socket, idx);
if (this.isAddressable()) {
this.emit('attach', socket, idx);
return;
}
this.emit('attach', socket);
}
return `${this.node} ${this.name.toUpperCase()}`;
}
/* eslint-disable class-methods-use-this */
getDataType() {
return this.options.datatype;
}
}, {
key: "attachSocket",
value: function attachSocket() {}
}, {
key: "detach",
value: function detach(socket) {
var index = this.sockets.indexOf(socket);
getSchema() {
return this.options.schema || null;
}
if (index === -1) {
return;
}
getDescription() {
return this.options.description;
}
this.sockets[index] = undefined;
attach(socket, index = null) {
if (!this.isAddressable() || index === null) {
index = this.sockets.length;
}
this.sockets[index] = socket;
this.attachSocket(socket, index);
if (this.isAddressable()) {
this.emit('attach', socket, index);
return;
}
return this.emit('attach', socket);
}
if (this.isAddressable()) {
this.emit('detach', socket, index);
return;
}
attachSocket() {}
detach(socket) {
var index;
index = this.sockets.indexOf(socket);
if (index === -1) {
return;
this.emit('detach', socket);
}
this.sockets[index] = void 0;
if (this.isAddressable()) {
this.emit('detach', socket, index);
return;
}
return this.emit('detach', socket);
}
}, {
key: "isAddressable",
value: function isAddressable() {
if (this.options.addressable) {
return true;
}
isAddressable() {
if (this.options.addressable) {
return true;
return false;
}
return false;
}
}, {
key: "isBuffered",
value: function isBuffered() {
if (this.options.buffered) {
return true;
}
isBuffered() {
if (this.options.buffered) {
return true;
return false;
}
return false;
}
}, {
key: "isRequired",
value: function isRequired() {
if (this.options.required) {
return true;
}
isRequired() {
if (this.options.required) {
return true;
return false;
}
return false;
}
}, {
key: "isAttached",
value: function isAttached() {
var socketId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
isAttached(socketId = null) {
if (this.isAddressable() && socketId !== null) {
if (this.sockets[socketId]) {
if (this.isAddressable() && socketId !== null) {
if (this.sockets[socketId]) {
return true;
}
return false;
}
if (this.sockets.length) {
return true;
}
return false;
}
if (this.sockets.length) {
return true;
}
return false;
}
}, {
key: "listAttached",
value: function listAttached() {
var attached = [];
listAttached() {
var attached, i, idx, len, ref, socket;
attached = [];
ref = this.sockets;
for (idx = i = 0, len = ref.length; i < len; idx = ++i) {
socket = ref[idx];
if (!socket) {
continue;
for (var idx = 0; idx < this.sockets.length; idx += 1) {
var socket = this.sockets[idx];
if (socket) {
attached.push(idx);
}
}
attached.push(idx);
return attached;
}
return attached;
}
}, {
key: "isConnected",
value: function isConnected() {
var socketId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
isConnected(socketId = null) {
var connected;
if (this.isAddressable()) {
if (socketId === null) {
throw new Error(`${this.getId()}: Socket ID required`);
if (this.isAddressable()) {
if (socketId === null) {
throw new Error("".concat(this.getId(), ": Socket ID required"));
}
if (!this.sockets[socketId]) {
throw new Error("".concat(this.getId(), ": Socket ").concat(socketId, " not available"));
}
return this.sockets[socketId].isConnected();
}
if (!this.sockets[socketId]) {
throw new Error(`${this.getId()}: Socket ${socketId} not available`);
}
return this.sockets[socketId].isConnected();
var connected = false;
this.sockets.forEach(function (socket) {
if (!socket) {
return;
}
if (socket.isConnected()) {
connected = true;
}
});
return connected;
}
connected = false;
this.sockets.forEach(function(socket) {
if (!socket) {
return;
}
if (socket.isConnected()) {
return connected = true;
}
});
return connected;
}
/* eslint-disable class-methods-use-this */
canAttach() {
return true;
}
}, {
key: "canAttach",
value: function canAttach() {
return true;
}
}]);
};
module.exports = BasePort;
return BasePort;
}(EventEmitter);

@@ -1,314 +0,399 @@

// NoFlo - Flow-Based Programming for JavaScript
// (c) 2013-2017 Flowhub UG
// (c) 2011-2012 Henri Bergius, Nemein
// NoFlo may be freely distributed under the MIT license
var Component, EventEmitter, IP, ProcessContext, ProcessInput, ProcessOutput, debug, debugBrackets, debugSend, ports,
boundMethodCheck = function(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new Error('Bound instance method accessed before binding'); } };
"use strict";
({EventEmitter} = require('events'));
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
ports = require('./Ports');
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
IP = require('./IP');
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
debug = require('debug')('noflo:component');
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
debugBrackets = require('debug')('noflo:component:brackets');
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
debugSend = require('debug')('noflo:component:send');
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
Component = (function() {
// ## NoFlo Component Base class
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
// The `noflo.Component` interface provides a way to instantiate
// and extend NoFlo components.
class Component extends EventEmitter {
constructor(options) {
var ref, ref1, ref2;
super();
// ### Error emitting helper
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
// If component has an `error` outport that is connected, errors
// are sent as IP objects there. If the port is not connected,
// errors are thrown.
this.error = this.error.bind(this);
if (!options) {
options = {};
}
if (!options.inPorts) {
// Prepare inports, if any were given in options.
// They can also be set up imperatively after component
// instantiation by using the `component.inPorts.add`
// method.
options.inPorts = {};
}
if (options.inPorts instanceof ports.InPorts) {
this.inPorts = options.inPorts;
} else {
this.inPorts = new ports.InPorts(options.inPorts);
}
if (!options.outPorts) {
// Prepare outports, if any were given in options.
// They can also be set up imperatively after component
// instantiation by using the `component.outPorts.add`
// method.
options.outPorts = {};
}
if (options.outPorts instanceof ports.OutPorts) {
this.outPorts = options.outPorts;
} else {
this.outPorts = new ports.OutPorts(options.outPorts);
}
if (options.icon) {
// Set the default component icon and description
this.icon = options.icon;
}
if (options.description) {
this.description = options.description;
}
// Initially the component is not started
this.started = false;
this.load = 0;
// Whether the component should keep send packets
// out in the order they were received
this.ordered = (ref = options.ordered) != null ? ref : false;
this.autoOrdering = (ref1 = options.autoOrdering) != null ? ref1 : null;
// Queue for handling ordered output packets
this.outputQ = [];
// Context used for bracket forwarding
this.bracketContext = {
in: {},
out: {}
};
// Whether the component should activate when it
// receives packets
this.activateOnInput = (ref2 = options.activateOnInput) != null ? ref2 : true;
// Bracket forwarding rules. By default we forward
// brackets from `in` port to `out` and `error` ports.
this.forwardBrackets = {
in: ['out', 'error']
};
if ('forwardBrackets' in options) {
this.forwardBrackets = options.forwardBrackets;
}
// The component's process function can either be
// passed in options, or given imperatively after
// instantation using the `component.process` method.
if (typeof options.process === 'function') {
this.process(options.process);
}
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
// NoFlo - Flow-Based Programming for JavaScript
// (c) 2013-2017 Flowhub UG
// (c) 2011-2012 Henri Bergius, Nemein
// NoFlo may be freely distributed under the MIT license
/* eslint-disable
class-methods-use-this,
no-underscore-dangle,
*/
var _require = require('events'),
EventEmitter = _require.EventEmitter;
var debug = require('debug')('noflo:component');
var debugBrackets = require('debug')('noflo:component:brackets');
var debugSend = require('debug')('noflo:component:send');
var ports = require('./Ports');
var ProcessContext = require('./ProcessContext');
var ProcessInput = require('./ProcessInput');
var ProcessOutput = require('./ProcessOutput'); // ## NoFlo Component Base class
//
// The `noflo.Component` interface provides a way to instantiate
// and extend NoFlo components.
var Component = /*#__PURE__*/function (_EventEmitter) {
_inherits(Component, _EventEmitter);
var _super = _createSuper(Component);
function Component() {
var _this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, Component);
_this = _super.call(this);
var opts = options; // Prepare inports, if any were given in options.
// They can also be set up imperatively after component
// instantiation by using the `component.inPorts.add`
// method.
if (!opts.inPorts) {
opts.inPorts = {};
}
getDescription() {
if (opts.inPorts instanceof ports.InPorts) {
_this.inPorts = opts.inPorts;
} else {
_this.inPorts = new ports.InPorts(opts.inPorts);
} // Prepare outports, if any were given in opts.
// They can also be set up imperatively after component
// instantiation by using the `component.outPorts.add`
// method.
if (!opts.outPorts) {
opts.outPorts = {};
}
if (opts.outPorts instanceof ports.OutPorts) {
_this.outPorts = opts.outPorts;
} else {
_this.outPorts = new ports.OutPorts(opts.outPorts);
} // Set the default component icon and description
_this.icon = opts.icon ? opts.icon : _this.constructor.icon;
_this.description = opts.description ? opts.description : _this.constructor.description; // Initially the component is not started
_this.started = false;
_this.load = 0; // Whether the component should keep send packets
// out in the order they were received
_this.ordered = opts.ordered != null ? opts.ordered : false;
_this.autoOrdering = opts.autoOrdering != null ? opts.autoOrdering : null; // Queue for handling ordered output packets
_this.outputQ = []; // Context used for bracket forwarding
_this.bracketContext = {
"in": {},
out: {}
}; // Whether the component should activate when it
// receives packets
_this.activateOnInput = opts.activateOnInput != null ? opts.activateOnInput : true; // Bracket forwarding rules. By default we forward
// brackets from `in` port to `out` and `error` ports.
_this.forwardBrackets = {
"in": ['out', 'error']
};
if ('forwardBrackets' in opts) {
_this.forwardBrackets = opts.forwardBrackets;
} // The component's process function can either be
// passed in opts, or given imperatively after
// instantation using the `component.process` method.
if (typeof opts.process === 'function') {
_this.process(opts.process);
}
return _this;
}
_createClass(Component, [{
key: "getDescription",
value: function getDescription() {
return this.description;
}
isReady() {
}, {
key: "isReady",
value: function isReady() {
return true;
}
isSubgraph() {
}, {
key: "isSubgraph",
value: function isSubgraph() {
return false;
}
setIcon(icon) {
}, {
key: "setIcon",
value: function setIcon(icon) {
this.icon = icon;
return this.emit('icon', this.icon);
this.emit('icon', this.icon);
}
getIcon() {
}, {
key: "getIcon",
value: function getIcon() {
return this.icon;
}
} // ### Error emitting helper
//
// If component has an `error` outport that is connected, errors
// are sent as IP objects there. If the port is not connected,
// errors are thrown.
error(e, groups = [], errorPort = 'error', scope = null) {
var group, i, j, len1, len2;
boundMethodCheck(this, Component);
}, {
key: "error",
value: function error(e) {
var _this2 = this;
var groups = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var errorPort = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'error';
var scope = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
if (this.outPorts[errorPort] && (this.outPorts[errorPort].isAttached() || !this.outPorts[errorPort].isRequired())) {
for (i = 0, len1 = groups.length; i < len1; i++) {
group = groups[i];
this.outPorts[errorPort].openBracket(group, {
groups.forEach(function (group) {
_this2.outPorts[errorPort].openBracket(group, {
scope: scope
});
}
});
this.outPorts[errorPort].data(e, {
scope: scope
});
for (j = 0, len2 = groups.length; j < len2; j++) {
group = groups[j];
this.outPorts[errorPort].closeBracket(group, {
groups.forEach(function (group) {
_this2.outPorts[errorPort].closeBracket(group, {
scope: scope
});
}
});
return;
}
throw e;
}
// ### Setup
} // ### Setup
//
// The setUp method is for component-specific initialization.
// Called at network start-up.
//
// Override in component implementation to do component-specific
// setup work.
setUp(callback) {
}, {
key: "setUp",
value: function setUp(callback) {
callback();
}
// ### Setup
} // ### Setup
//
// The tearDown method is for component-specific cleanup. Called
// at network shutdown
//
// Override in component implementation to do component-specific
// cleanup work, like clearing any accumulated state.
tearDown(callback) {
}, {
key: "tearDown",
value: function tearDown(callback) {
callback();
}
} // ### Start
//
// Called when network starts. This sets calls the setUp
// method and sets the component to a started state.
// ### Start
}, {
key: "start",
value: function start(callback) {
var _this3 = this;
// Called when network starts. This sets calls the setUp
// method and sets the component to a started state.
start(callback) {
if (this.isStarted()) {
return callback();
callback();
return;
}
this.setUp((err) => {
this.setUp(function (err) {
if (err) {
return callback(err);
callback(err);
return;
}
this.started = true;
this.emit('start');
_this3.started = true;
_this3.emit('start');
callback(null);
});
}
// ### Shutdown
} // ### Shutdown
//
// Called when network is shut down. This sets calls the
// tearDown method and sets the component back to a
// non-started state.
//
// The callback is called when tearDown finishes and
// all active processing contexts have ended.
shutdown(callback) {
var finalize;
finalize = () => {
var inPort, inPorts, portName;
}, {
key: "shutdown",
value: function shutdown(callback) {
var _this4 = this;
var finalize = function finalize() {
// Clear contents of inport buffers
inPorts = this.inPorts.ports || this.inPorts;
for (portName in inPorts) {
inPort = inPorts[portName];
var inPorts = _this4.inPorts.ports || _this4.inPorts;
Object.keys(inPorts).forEach(function (portName) {
var inPort = inPorts[portName];
if (typeof inPort.clear !== 'function') {
continue;
return;
}
inPort.clear();
}
// Clear bracket context
this.bracketContext = {
in: {},
}); // Clear bracket context
_this4.bracketContext = {
"in": {},
out: {}
};
if (!this.isStarted()) {
return callback();
if (!_this4.isStarted()) {
callback();
return;
}
this.started = false;
this.emit('end');
_this4.started = false;
_this4.emit('end');
callback();
};
// Tell the component that it is time to shut down
this.tearDown((err) => {
var checkLoad;
}; // Tell the component that it is time to shut down
this.tearDown(function (err) {
if (err) {
return callback(err);
callback(err);
return;
}
if (this.load > 0) {
if (_this4.load > 0) {
// Some in-flight processes, wait for them to finish
checkLoad = function(load) {
var checkLoad = function checkLoad(load) {
if (load > 0) {
return;
}
this.removeListener('deactivate', checkLoad);
_this4.removeListener('deactivate', checkLoad);
finalize();
};
this.on('deactivate', checkLoad);
_this4.on('deactivate', checkLoad);
return;
}
finalize();
});
}
isStarted() {
}, {
key: "isStarted",
value: function isStarted() {
return this.started;
}
} // Ensures braket forwarding map is correct for the existing ports
// Ensures braket forwarding map is correct for the existing ports
prepareForwarding() {
var i, inPort, len1, outPort, outPorts, ref, results, tmp;
ref = this.forwardBrackets;
results = [];
for (inPort in ref) {
outPorts = ref[inPort];
if (!(inPort in this.inPorts.ports)) {
delete this.forwardBrackets[inPort];
continue;
}, {
key: "prepareForwarding",
value: function prepareForwarding() {
var _this5 = this;
Object.keys(this.forwardBrackets).forEach(function (inPort) {
var outPorts = _this5.forwardBrackets[inPort];
if (!(inPort in _this5.inPorts.ports)) {
delete _this5.forwardBrackets[inPort];
return;
}
tmp = [];
for (i = 0, len1 = outPorts.length; i < len1; i++) {
outPort = outPorts[i];
if (outPort in this.outPorts.ports) {
var tmp = [];
outPorts.forEach(function (outPort) {
if (outPort in _this5.outPorts.ports) {
tmp.push(outPort);
}
}
});
if (tmp.length === 0) {
results.push(delete this.forwardBrackets[inPort]);
delete _this5.forwardBrackets[inPort];
} else {
results.push(this.forwardBrackets[inPort] = tmp);
_this5.forwardBrackets[inPort] = tmp;
}
}
return results;
}
});
} // Method for determining if a component is using the modern
// NoFlo Process API
// Method for determining if a component is using the modern
// NoFlo Process API
isLegacy() {
}, {
key: "isLegacy",
value: function isLegacy() {
// Process API
if (this.handle) {
// Process API
return false;
}
// Legacy
} // Legacy
return true;
}
} // Sets process handler function
// Sets process handler function
process(handle) {
var name, port, ref;
}, {
key: "process",
value: function process(handle) {
var _this6 = this;
if (typeof handle !== 'function') {
throw new Error("Process handler must be a function");
throw new Error('Process handler must be a function');
}
if (!this.inPorts) {
throw new Error("Component ports must be defined before process function");
throw new Error('Component ports must be defined before process function');
}
this.prepareForwarding();
this.handle = handle;
ref = this.inPorts.ports;
for (name in ref) {
port = ref[name];
((name, port) => {
if (!port.name) {
port.name = name;
}
return port.on('ip', (ip) => {
return this.handleIP(ip, port);
});
})(name, port);
}
Object.keys(this.inPorts.ports).forEach(function (name) {
var port = _this6.inPorts.ports[name];
if (!port.name) {
port.name = name;
}
port.on('ip', function (ip) {
return _this6.handleIP(ip, port);
});
});
return this;
}
} // Method for checking if a given inport is set up for
// automatic bracket forwarding
// Method for checking if a given inport is set up for
// automatic bracket forwarding
isForwardingInport(port) {
}, {
key: "isForwardingInport",
value: function isForwardingInport(port) {
var portName;
if (typeof port === 'string') {

@@ -319,12 +404,17 @@ portName = port;

}
if (portName in this.forwardBrackets) {
return true;
}
return false;
}
} // Method for checking if a given outport is set up for
// automatic bracket forwarding
// Method for checking if a given outport is set up for
// automatic bracket forwarding
isForwardingOutport(inport, outport) {
var inportName, outportName;
}, {
key: "isForwardingOutport",
value: function isForwardingOutport(inport, outport) {
var inportName;
var outportName;
if (typeof inport === 'string') {

@@ -335,2 +425,3 @@ inportName = inport;

}
if (typeof outport === 'string') {

@@ -341,43 +432,54 @@ outportName = outport;

}
if (!this.forwardBrackets[inportName]) {
return false;
}
if (this.forwardBrackets[inportName].indexOf(outportName) !== -1) {
return true;
}
return false;
}
} // Method for checking whether the component sends packets
// in the same order they were received.
// Method for checking whether the component sends packets
// in the same order they were received.
isOrdered() {
}, {
key: "isOrdered",
value: function isOrdered() {
if (this.ordered) {
return true;
}
if (this.autoOrdering) {
return true;
}
return false;
}
// ### Handling IP objects
} // ### Handling IP objects
//
// The component has received an Information Packet. Call the
// processing function so that firing pattern preconditions can
// be checked and component can do processing as needed.
handleIP(ip, port) {
var buf, context, dataPackets, e, input, output, result;
}, {
key: "handleIP",
value: function handleIP(ip, port) {
var context;
if (!port.options.triggering) {
// If port is non-triggering, we can skip the process function call
return;
}
// If port is non-triggering, we can skip the process function call
if (ip.type === 'openBracket' && this.autoOrdering === null && !this.ordered) {
// Switch component to ordered mode when receiving a stream unless
// auto-ordering is disabled
debug(`${this.nodeId} port '${port.name}' entered auto-ordering mode`);
debug("".concat(this.nodeId, " port '").concat(port.name, "' entered auto-ordering mode"));
this.autoOrdering = true;
}
// Initialize the result object for situations where output needs
} // Initialize the result object for situations where output needs
// to be queued to be kept in order
result = {};
var result = {};
if (this.isForwardingInport(port)) {

@@ -387,5 +489,6 @@ // For bracket-forwarding inports we need to initialize a bracket context

if (ip.type === 'openBracket') {
// For forwarding ports openBrackets don't fire
return;
}
// For forwarding ports openBrackets don't fire
if (ip.type === 'closeBracket') {

@@ -398,15 +501,17 @@ // For forwarding ports closeBrackets don't fire

// new closeBracket arrives
buf = port.getBuffer(ip.scope, ip.index);
dataPackets = buf.filter(function(ip) {
return ip.type === 'data';
var buf = port.getBuffer(ip.scope, ip.index);
var dataPackets = buf.filter(function (p) {
return p.type === 'data';
});
if (this.outputQ.length >= this.load && dataPackets.length === 0) {
if (buf[0] !== ip) {
return;
}
// Remove from buffer
} // Remove from buffer
port.get(ip.scope, ip.index);
context = this.getBracketContext('in', port.name, ip.scope, ip.index).pop();
context.closeIp = ip;
debugBrackets(`${this.nodeId} closeBracket-C from '${context.source}' to ${context.ports}: '${ip.data}'`);
debugBrackets("".concat(this.nodeId, " closeBracket-C from '").concat(context.source, "' to ").concat(context.ports, ": '").concat(ip.data, "'"));
result = {

@@ -418,5 +523,6 @@ __resolved: true,

this.processOutputQueue();
}
// Check if buffer contains data IPs. If it does, we want to allow
} // Check if buffer contains data IPs. If it does, we want to allow
// firing
if (!dataPackets.length) {

@@ -426,91 +532,125 @@ return;

}
}
// Prepare the input/output pair
} // Prepare the input/output pair
context = new ProcessContext(ip, this, port, result);
input = new ProcessInput(this.inPorts, context);
output = new ProcessOutput(this.outPorts, context);
var input = new ProcessInput(this.inPorts, context);
var output = new ProcessOutput(this.outPorts, context);
try {
// Call the processing function
this.handle(input, output, context);
} catch (error1) {
e = error1;
} catch (e) {
this.deactivate(context);
output.sendDone(e);
}
if (context.activated) {
return;
}
// If receiving an IP object didn't cause the component to
} // If receiving an IP object didn't cause the component to
// activate, log that input conditions were not met
if (port.isAddressable()) {
debug(`${this.nodeId} packet on '${port.name}[${ip.index}]' didn't match preconditions: ${ip.type}`);
debug("".concat(this.nodeId, " packet on '").concat(port.name, "[").concat(ip.index, "]' didn't match preconditions: ").concat(ip.type));
return;
}
debug(`${this.nodeId} packet on '${port.name}' didn't match preconditions: ${ip.type}`);
}
// Get the current bracket forwarding context for an IP object
getBracketContext(type, port, scope, idx) {
var index, name, portsList;
({name, index} = ports.normalizePortName(port));
debug("".concat(this.nodeId, " packet on '").concat(port.name, "' didn't match preconditions: ").concat(ip.type));
} // Get the current bracket forwarding context for an IP object
}, {
key: "getBracketContext",
value: function getBracketContext(type, port, scope, idx) {
var _ports$normalizePortN = ports.normalizePortName(port),
name = _ports$normalizePortN.name,
index = _ports$normalizePortN.index;
if (idx != null) {
index = idx;
}
portsList = type === 'in' ? this.inPorts : this.outPorts;
var portsList = type === 'in' ? this.inPorts : this.outPorts;
if (portsList[name].isAddressable()) {
port = `${name}[${index}]`;
name = "".concat(name, "[").concat(index, "]");
} else {
name = port;
} // Ensure we have a bracket context for the current scope
if (!this.bracketContext[type][name]) {
this.bracketContext[type][name] = {};
}
if (!this.bracketContext[type][port]) {
// Ensure we have a bracket context for the current scope
this.bracketContext[type][port] = {};
if (!this.bracketContext[type][name][scope]) {
this.bracketContext[type][name][scope] = [];
}
if (!this.bracketContext[type][port][scope]) {
this.bracketContext[type][port][scope] = [];
}
return this.bracketContext[type][port][scope];
}
// Add an IP object to the list of results to be sent in
return this.bracketContext[type][name][scope];
} // Add an IP object to the list of results to be sent in
// order
addToResult(result, port, ip, before = false) {
var idx, index, method, name;
({name, index} = ports.normalizePortName(port));
method = before ? 'unshift' : 'push';
}, {
key: "addToResult",
value: function addToResult(result, port, packet) {
var before = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var res = result;
var ip = packet;
var _ports$normalizePortN2 = ports.normalizePortName(port),
name = _ports$normalizePortN2.name,
index = _ports$normalizePortN2.index;
var method = before ? 'unshift' : 'push';
if (this.outPorts[name].isAddressable()) {
idx = index ? parseInt(index) : ip.index;
if (!result[name]) {
result[name] = {};
var idx = index ? parseInt(index, 10) : ip.index;
if (!res[name]) {
res[name] = {};
}
if (!result[name][idx]) {
result[name][idx] = [];
if (!res[name][idx]) {
res[name][idx] = [];
}
ip.index = idx;
result[name][idx][method](ip);
res[name][idx][method](ip);
return;
}
if (!result[name]) {
result[name] = [];
if (!res[name]) {
res[name] = [];
}
return result[name][method](ip);
}
// Get contexts that can be forwarded with this in/outport
res[name][method](ip);
} // Get contexts that can be forwarded with this in/outport
// pair.
getForwardableContexts(inport, outport, contexts) {
var forwardable, index, name;
({name, index} = ports.normalizePortName(outport));
forwardable = [];
contexts.forEach((ctx, idx) => {
var outContext;
}, {
key: "getForwardableContexts",
value: function getForwardableContexts(inport, outport, contexts) {
var _this7 = this;
var _ports$normalizePortN3 = ports.normalizePortName(outport),
name = _ports$normalizePortN3.name,
index = _ports$normalizePortN3.index;
var forwardable = [];
contexts.forEach(function (ctx, idx) {
// No forwarding to this outport
if (!this.isForwardingOutport(inport, name)) {
if (!_this7.isForwardingOutport(inport, name)) {
return;
}
// We have already forwarded this context to this outport
} // We have already forwarded this context to this outport
if (ctx.ports.indexOf(outport) !== -1) {
return;
}
// See if we have already forwarded the same bracket from another
} // See if we have already forwarded the same bracket from another
// inport
outContext = this.getBracketContext('out', name, ctx.ip.scope, index)[idx];
var outContext = _this7.getBracketContext('out', name, ctx.ip.scope, index)[idx];
if (outContext) {

@@ -521,811 +661,275 @@ if (outContext.ip.data === ctx.ip.data && outContext.ports.indexOf(outport) !== -1) {

}
return forwardable.push(ctx);
forwardable.push(ctx);
});
return forwardable;
}
} // Add any bracket forwards needed to the result queue
// Add any bracket forwards needed to the result queue
addBracketForwards(result) {
var context, i, ipClone, j, k, l, len1, len2, len3, len4, port, ref, ref1, ref2, ref3, ref4, ref5;
if ((ref = result.__bracketClosingBefore) != null ? ref.length : void 0) {
ref1 = result.__bracketClosingBefore;
for (i = 0, len1 = ref1.length; i < len1; i++) {
context = ref1[i];
debugBrackets(`${this.nodeId} closeBracket-A from '${context.source}' to ${context.ports}: '${context.closeIp.data}'`);
}, {
key: "addBracketForwards",
value: function addBracketForwards(result) {
var _this8 = this;
var res = result;
if (res.__bracketClosingBefore != null ? res.__bracketClosingBefore.length : undefined) {
res.__bracketClosingBefore.forEach(function (context) {
debugBrackets("".concat(_this8.nodeId, " closeBracket-A from '").concat(context.source, "' to ").concat(context.ports, ": '").concat(context.closeIp.data, "'"));
if (!context.ports.length) {
continue;
return;
}
ref2 = context.ports;
for (j = 0, len2 = ref2.length; j < len2; j++) {
port = ref2[j];
ipClone = context.closeIp.clone();
this.addToResult(result, port, ipClone, true);
this.getBracketContext('out', port, ipClone.scope).pop();
}
}
context.ports.forEach(function (port) {
var ipClone = context.closeIp.clone();
_this8.addToResult(res, port, ipClone, true);
_this8.getBracketContext('out', port, ipClone.scope).pop();
});
});
}
if (result.__bracketContext) {
if (res.__bracketContext) {
// First see if there are any brackets to forward. We need to reverse
// the keys so that they get added in correct order
Object.keys(result.__bracketContext).reverse().forEach((inport) => {
var ctx, datas, forwardedOpens, idx, idxIps, ip, ips, k, l, len3, len4, len5, m, outport, portIdentifier, results, unforwarded;
context = result.__bracketContext[inport];
Object.keys(res.__bracketContext).reverse().forEach(function (inport) {
var context = res.__bracketContext[inport];
if (!context.length) {
return;
}
results = [];
for (outport in result) {
ips = result[outport];
Object.keys(res).forEach(function (outport) {
var datas;
var forwardedOpens;
var unforwarded;
var ips = res[outport];
if (outport.indexOf('__') === 0) {
continue;
return;
}
if (this.outPorts[outport].isAddressable()) {
for (idx in ips) {
idxIps = ips[idx];
if (_this8.outPorts[outport].isAddressable()) {
Object.keys(ips).forEach(function (idx) {
// Don't register indexes we're only sending brackets to
datas = idxIps.filter(function(ip) {
var idxIps = ips[idx];
datas = idxIps.filter(function (ip) {
return ip.type === 'data';
});
if (!datas.length) {
continue;
return;
}
portIdentifier = `${outport}[${idx}]`;
unforwarded = this.getForwardableContexts(inport, portIdentifier, context);
var portIdentifier = "".concat(outport, "[").concat(idx, "]");
unforwarded = _this8.getForwardableContexts(inport, portIdentifier, context);
if (!unforwarded.length) {
continue;
return;
}
forwardedOpens = [];
for (k = 0, len3 = unforwarded.length; k < len3; k++) {
ctx = unforwarded[k];
debugBrackets(`${this.nodeId} openBracket from '${inport}' to '${portIdentifier}': '${ctx.ip.data}'`);
ipClone = ctx.ip.clone();
ipClone.index = parseInt(idx);
unforwarded.forEach(function (ctx) {
debugBrackets("".concat(_this8.nodeId, " openBracket from '").concat(inport, "' to '").concat(portIdentifier, "': '").concat(ctx.ip.data, "'"));
var ipClone = ctx.ip.clone();
ipClone.index = parseInt(idx, 10);
forwardedOpens.push(ipClone);
ctx.ports.push(portIdentifier);
this.getBracketContext('out', outport, ctx.ip.scope, idx).push(ctx);
}
_this8.getBracketContext('out', outport, ctx.ip.scope, idx).push(ctx);
});
forwardedOpens.reverse();
for (l = 0, len4 = forwardedOpens.length; l < len4; l++) {
ip = forwardedOpens[l];
this.addToResult(result, outport, ip, true);
}
}
continue;
}
// Don't register ports we're only sending brackets to
datas = ips.filter(function(ip) {
forwardedOpens.forEach(function (ip) {
_this8.addToResult(res, outport, ip, true);
});
});
return;
} // Don't register ports we're only sending brackets to
datas = ips.filter(function (ip) {
return ip.type === 'data';
});
if (!datas.length) {
continue;
return;
}
unforwarded = this.getForwardableContexts(inport, outport, context);
unforwarded = _this8.getForwardableContexts(inport, outport, context);
if (!unforwarded.length) {
continue;
return;
}
forwardedOpens = [];
for (m = 0, len5 = unforwarded.length; m < len5; m++) {
ctx = unforwarded[m];
debugBrackets(`${this.nodeId} openBracket from '${inport}' to '${outport}': '${ctx.ip.data}'`);
unforwarded.forEach(function (ctx) {
debugBrackets("".concat(_this8.nodeId, " openBracket from '").concat(inport, "' to '").concat(outport, "': '").concat(ctx.ip.data, "'"));
forwardedOpens.push(ctx.ip.clone());
ctx.ports.push(outport);
this.getBracketContext('out', outport, ctx.ip.scope).push(ctx);
}
_this8.getBracketContext('out', outport, ctx.ip.scope).push(ctx);
});
forwardedOpens.reverse();
results.push((function() {
var len6, n, results1;
results1 = [];
for (n = 0, len6 = forwardedOpens.length; n < len6; n++) {
ip = forwardedOpens[n];
results1.push(this.addToResult(result, outport, ip, true));
}
return results1;
}).call(this));
}
return results;
forwardedOpens.forEach(function (ip) {
_this8.addToResult(res, outport, ip, true);
});
});
});
}
if ((ref3 = result.__bracketClosingAfter) != null ? ref3.length : void 0) {
ref4 = result.__bracketClosingAfter;
for (k = 0, len3 = ref4.length; k < len3; k++) {
context = ref4[k];
debugBrackets(`${this.nodeId} closeBracket-B from '${context.source}' to ${context.ports}: '${context.closeIp.data}'`);
if (res.__bracketClosingAfter != null ? res.__bracketClosingAfter.length : undefined) {
res.__bracketClosingAfter.forEach(function (context) {
debugBrackets("".concat(_this8.nodeId, " closeBracket-B from '").concat(context.source, "' to ").concat(context.ports, ": '").concat(context.closeIp.data, "'"));
if (!context.ports.length) {
continue;
return;
}
ref5 = context.ports;
for (l = 0, len4 = ref5.length; l < len4; l++) {
port = ref5[l];
ipClone = context.closeIp.clone();
this.addToResult(result, port, ipClone, false);
this.getBracketContext('out', port, ipClone.scope).pop();
}
}
}
delete result.__bracketClosingBefore;
delete result.__bracketContext;
return delete result.__bracketClosingAfter;
}
// Whenever an execution context finishes, send all resolved
// output from the queue in the order it is in.
processOutputQueue() {
var idx, idxIps, ip, ips, port, portIdentifier, result, results;
results = [];
while (this.outputQ.length > 0) {
if (!this.outputQ[0].__resolved) {
break;
}
result = this.outputQ.shift();
this.addBracketForwards(result);
results.push((function() {
var i, len1, results1;
results1 = [];
for (port in result) {
ips = result[port];
if (port.indexOf('__') === 0) {
continue;
}
if (this.outPorts.ports[port].isAddressable()) {
for (idx in ips) {
idxIps = ips[idx];
idx = parseInt(idx);
if (!this.outPorts.ports[port].isAttached(idx)) {
continue;
}
for (i = 0, len1 = idxIps.length; i < len1; i++) {
ip = idxIps[i];
portIdentifier = `${port}[${ip.index}]`;
if (ip.type === 'openBracket') {
debugSend(`${this.nodeId} sending ${portIdentifier} < '${ip.data}'`);
} else if (ip.type === 'closeBracket') {
debugSend(`${this.nodeId} sending ${portIdentifier} > '${ip.data}'`);
} else {
debugSend(`${this.nodeId} sending ${portIdentifier} DATA`);
}
if (!this.outPorts[port].options.scoped) {
ip.scope = null;
}
this.outPorts[port].sendIP(ip);
}
}
continue;
}
if (!this.outPorts.ports[port].isAttached()) {
continue;
}
results1.push((function() {
var j, len2, results2;
results2 = [];
for (j = 0, len2 = ips.length; j < len2; j++) {
ip = ips[j];
portIdentifier = port;
if (ip.type === 'openBracket') {
debugSend(`${this.nodeId} sending ${portIdentifier} < '${ip.data}'`);
} else if (ip.type === 'closeBracket') {
debugSend(`${this.nodeId} sending ${portIdentifier} > '${ip.data}'`);
} else {
debugSend(`${this.nodeId} sending ${portIdentifier} DATA`);
}
if (!this.outPorts[port].options.scoped) {
ip.scope = null;
}
results2.push(this.outPorts[port].sendIP(ip));
}
return results2;
}).call(this));
}
return results1;
}).call(this));
}
return results;
}
context.ports.forEach(function (port) {
var ipClone = context.closeIp.clone();
// Signal that component has activated. There may be multiple
// activated contexts at the same time
activate(context) {
if (context.activated) { // prevent double activation
return;
}
context.activated = true;
context.deactivated = false;
this.load++;
this.emit('activate', this.load);
if (this.ordered || this.autoOrdering) {
return this.outputQ.push(context.result);
}
}
_this8.addToResult(res, port, ipClone, false);
// Signal that component has deactivated. There may be multiple
// activated contexts at the same time
deactivate(context) {
if (context.deactivated) { // prevent double deactivation
return;
_this8.getBracketContext('out', port, ipClone.scope).pop();
});
});
}
context.deactivated = true;
context.activated = false;
if (this.isOrdered()) {
this.processOutputQueue();
}
this.load--;
return this.emit('deactivate', this.load);
}
};
delete res.__bracketClosingBefore;
delete res.__bracketContext;
delete res.__bracketClosingAfter;
} // Whenever an execution context finishes, send all resolved
// output from the queue in the order it is in.
Component.prototype.description = '';
}, {
key: "processOutputQueue",
value: function processOutputQueue() {
var _this9 = this;
Component.prototype.icon = null;
var _loop = function _loop() {
if (!_this9.outputQ[0].__resolved) {
return "break";
}
return Component;
var result = _this9.outputQ.shift();
}).call(this);
_this9.addBracketForwards(result);
ProcessContext = class ProcessContext {
constructor(ip1, nodeInstance, port1, result1) {
this.ip = ip1;
this.nodeInstance = nodeInstance;
this.port = port1;
this.result = result1;
this.scope = this.ip.scope;
this.activated = false;
this.deactivated = false;
}
Object.keys(result).forEach(function (port) {
var portIdentifier;
var ips = result[port];
activate() {
// Push a new result value if previous has been sent already
if (this.result.__resolved || this.nodeInstance.outputQ.indexOf(this.result) === -1) {
this.result = {};
}
return this.nodeInstance.activate(this);
}
if (port.indexOf('__') === 0) {
return;
}
deactivate() {
if (!this.result.__resolved) {
this.result.__resolved = true;
}
return this.nodeInstance.deactivate(this);
}
if (_this9.outPorts.ports[port].isAddressable()) {
Object.keys(ips).forEach(function (index) {
var idxIps = ips[index];
var idx = parseInt(index, 10);
};
if (!_this9.outPorts.ports[port].isAttached(idx)) {
return;
}
ProcessInput = class ProcessInput {
constructor(ports1, context1) {
this.ports = ports1;
this.context = context1;
this.nodeInstance = this.context.nodeInstance;
this.ip = this.context.ip;
this.port = this.context.port;
this.result = this.context.result;
this.scope = this.context.scope;
}
idxIps.forEach(function (packet) {
var ip = packet;
portIdentifier = "".concat(port, "[").concat(ip.index, "]");
// When preconditions are met, set component state to `activated`
activate() {
if (this.context.activated) {
return;
}
if (this.nodeInstance.isOrdered()) {
// We're handling packets in order. Set the result as non-resolved
// so that it can be send when the order comes up
this.result.__resolved = false;
}
this.nodeInstance.activate(this.context);
if (this.port.isAddressable()) {
return debug(`${this.nodeInstance.nodeId} packet on '${this.port.name}[${this.ip.index}]' caused activation ${this.nodeInstance.load}: ${this.ip.type}`);
} else {
return debug(`${this.nodeInstance.nodeId} packet on '${this.port.name}' caused activation ${this.nodeInstance.load}: ${this.ip.type}`);
}
}
if (ip.type === 'openBracket') {
debugSend("".concat(_this9.nodeId, " sending ").concat(portIdentifier, " < '").concat(ip.data, "'"));
} else if (ip.type === 'closeBracket') {
debugSend("".concat(_this9.nodeId, " sending ").concat(portIdentifier, " > '").concat(ip.data, "'"));
} else {
debugSend("".concat(_this9.nodeId, " sending ").concat(portIdentifier, " DATA"));
}
// ## Connection listing
// This allows components to check which input ports are attached. This is
// useful mainly for addressable ports
attached(...args) {
var i, len1, port, res;
if (!args.length) {
args = ['in'];
}
res = [];
for (i = 0, len1 = args.length; i < len1; i++) {
port = args[i];
if (!this.ports[port]) {
throw new Error(`Node ${this.nodeInstance.nodeId} has no port '${port}'`);
}
res.push(this.ports[port].listAttached());
}
if (args.length === 1) {
return res.pop();
}
return res;
}
if (!_this9.outPorts[port].options.scoped) {
ip.scope = null;
}
// ## Input preconditions
// When the processing function is called, it can check if input buffers
// contain the packets needed for the process to fire.
// This precondition handling is done via the `has` and `hasStream` methods.
_this9.outPorts[port].sendIP(ip);
});
});
return;
}
// Returns true if a port (or ports joined by logical AND) has a new IP
// Passing a validation callback as a last argument allows more selective
// checking of packets.
has(...args) {
var i, len1, port, validate;
if (!args.length) {
args = ['in'];
}
if (typeof args[args.length - 1] === 'function') {
validate = args.pop();
} else {
validate = function() {
return true;
};
}
for (i = 0, len1 = args.length; i < len1; i++) {
port = args[i];
if (Array.isArray(port)) {
if (!this.ports[port[0]]) {
throw new Error(`Node ${this.nodeInstance.nodeId} has no port '${port[0]}'`);
}
if (!this.ports[port[0]].isAddressable()) {
throw new Error(`Non-addressable ports, access must be with string ${port[0]}`);
}
if (!this.ports[port[0]].has(this.scope, port[1], validate)) {
return false;
}
continue;
}
if (!this.ports[port]) {
throw new Error(`Node ${this.nodeInstance.nodeId} has no port '${port}'`);
}
if (this.ports[port].isAddressable()) {
throw new Error(`For addressable ports, access must be with array [${port}, idx]`);
}
if (!this.ports[port].has(this.scope, validate)) {
return false;
}
}
return true;
}
// Returns true if the ports contain data packets
hasData(...args) {
if (!args.length) {
args = ['in'];
}
args.push(function(ip) {
return ip.type === 'data';
});
return this.has.apply(this, args);
}
// Returns true if a port has a complete stream in its input buffer.
hasStream(...args) {
var dataBrackets, hasData, i, len1, port, portBrackets, validate, validateStream;
if (!args.length) {
args = ['in'];
}
if (typeof args[args.length - 1] === 'function') {
validateStream = args.pop();
} else {
validateStream = function() {
return true;
};
}
for (i = 0, len1 = args.length; i < len1; i++) {
port = args[i];
portBrackets = [];
dataBrackets = [];
hasData = false;
validate = function(ip) {
if (ip.type === 'openBracket') {
portBrackets.push(ip.data);
return false;
}
if (ip.type === 'data') {
// Run the stream validation callback
hasData = validateStream(ip, portBrackets);
if (!portBrackets.length) {
// Data IP on its own is a valid stream
return hasData;
if (!_this9.outPorts.ports[port].isAttached()) {
return;
}
// Otherwise we need to check for complete stream
return false;
}
if (ip.type === 'closeBracket') {
portBrackets.pop();
if (portBrackets.length) {
return false;
}
if (!hasData) {
return false;
}
return true;
}
};
if (!this.has(port, validate)) {
return false;
}
}
return true;
}
// ## Input processing
ips.forEach(function (packet) {
var ip = packet;
portIdentifier = port;
// Once preconditions have been met, the processing function can read from
// the input buffers. Reading packets sets the component as "activated".
if (ip.type === 'openBracket') {
debugSend("".concat(_this9.nodeId, " sending ").concat(portIdentifier, " < '").concat(ip.data, "'"));
} else if (ip.type === 'closeBracket') {
debugSend("".concat(_this9.nodeId, " sending ").concat(portIdentifier, " > '").concat(ip.data, "'"));
} else {
debugSend("".concat(_this9.nodeId, " sending ").concat(portIdentifier, " DATA"));
}
// Fetches IP object(s) for port(s)
get(...args) {
var i, idx, ip, len1, port, portname, res;
this.activate();
if (!args.length) {
args = ['in'];
}
res = [];
for (i = 0, len1 = args.length; i < len1; i++) {
port = args[i];
if (Array.isArray(port)) {
[portname, idx] = port;
if (!this.ports[portname].isAddressable()) {
throw new Error('Non-addressable ports, access must be with string portname');
}
} else {
portname = port;
if (this.ports[portname].isAddressable()) {
throw new Error('For addressable ports, access must be with array [portname, idx]');
}
}
if (this.nodeInstance.isForwardingInport(portname)) {
ip = this.__getForForwarding(portname, idx);
res.push(ip);
continue;
}
ip = this.ports[portname].get(this.scope, idx);
res.push(ip);
}
if (args.length === 1) {
return res[0];
} else {
return res;
}
}
if (!_this9.outPorts[port].options.scoped) {
ip.scope = null;
}
__getForForwarding(port, idx) {
var context, dataIp, i, ip, len1, prefix;
prefix = [];
dataIp = null;
while (true) {
// Read next packet
// Read IPs until we hit data
ip = this.ports[port].get(this.scope, idx);
if (!ip) {
// Stop at the end of the buffer
break;
}
if (ip.type === 'data') {
// Hit the data IP, stop here
dataIp = ip;
break;
}
// Keep track of bracket closings and openings before
prefix.push(ip);
}
// Forwarding brackets that came before data packet need to manipulate context
// and be added to result so they can be forwarded correctly to ports that
// need them
for (i = 0, len1 = prefix.length; i < len1; i++) {
ip = prefix[i];
if (ip.type === 'closeBracket') {
if (!this.result.__bracketClosingBefore) {
// Bracket closings before data should remove bracket context
this.result.__bracketClosingBefore = [];
}
context = this.nodeInstance.getBracketContext('in', port, this.scope, idx).pop();
context.closeIp = ip;
this.result.__bracketClosingBefore.push(context);
continue;
}
if (ip.type === 'openBracket') {
// Bracket openings need to go to bracket context
this.nodeInstance.getBracketContext('in', port, this.scope, idx).push({
ip: ip,
ports: [],
source: port
_this9.outPorts[port].sendIP(ip);
});
});
continue;
}
}
if (!this.result.__bracketContext) {
// Add current bracket context to the result so that when we send
// to ports we can also add the surrounding brackets
this.result.__bracketContext = {};
}
this.result.__bracketContext[port] = this.nodeInstance.getBracketContext('in', port, this.scope, idx).slice(0);
// Bracket closings that were in buffer after the data packet need to
// be added to result for done() to read them from
return dataIp;
}
};
// Fetches `data` property of IP object(s) for given port(s)
getData(...args) {
var datas, i, len1, packet, port;
if (!args.length) {
args = ['in'];
}
datas = [];
for (i = 0, len1 = args.length; i < len1; i++) {
port = args[i];
packet = this.get(port);
if (packet == null) {
// we add the null packet to the array so when getting
// multiple ports, if one is null we still return it
// so the indexes are correct.
datas.push(packet);
continue;
}
while (packet.type !== 'data') {
packet = this.get(port);
if (!packet) {
break;
}
}
datas.push(packet.data);
}
if (args.length === 1) {
return datas.pop();
}
return datas;
}
while (this.outputQ.length > 0) {
var _ret = _loop();
// Fetches a complete data stream from the buffer.
getStream(...args) {
var datas, hasData, i, ip, len1, port, portBrackets, portPackets;
if (!args.length) {
args = ['in'];
}
datas = [];
for (i = 0, len1 = args.length; i < len1; i++) {
port = args[i];
portBrackets = [];
portPackets = [];
hasData = false;
ip = this.get(port);
if (!ip) {
datas.push(void 0);
if (_ret === "break") break;
}
while (ip) {
if (ip.type === 'openBracket') {
if (!portBrackets.length) {
// First openBracket in stream, drop previous
portPackets = [];
hasData = false;
}
portBrackets.push(ip.data);
portPackets.push(ip);
}
if (ip.type === 'data') {
portPackets.push(ip);
hasData = true;
if (!portBrackets.length) {
// Unbracketed data packet is a valid stream
break;
}
}
if (ip.type === 'closeBracket') {
portPackets.push(ip);
portBrackets.pop();
if (hasData && !portBrackets.length) {
// Last close bracket finishes stream if there was data inside
break;
}
}
ip = this.get(port);
}
datas.push(portPackets);
}
if (args.length === 1) {
return datas.pop();
}
return datas;
}
} // Signal that component has activated. There may be multiple
// activated contexts at the same time
};
}, {
key: "activate",
value: function activate(context) {
if (context.activated) {
return;
} // prevent double activation
ProcessOutput = class ProcessOutput {
constructor(ports1, context1) {
this.ports = ports1;
this.context = context1;
this.nodeInstance = this.context.nodeInstance;
this.ip = this.context.ip;
this.result = this.context.result;
this.scope = this.context.scope;
}
// Checks if a value is an Error
isError(err) {
return err instanceof Error || Array.isArray(err) && err.length > 0 && err[0] instanceof Error;
}
context.activated = true;
context.deactivated = false;
this.load += 1;
this.emit('activate', this.load);
// Sends an error object
error(err) {
var e, i, j, len1, len2, multiple, results;
multiple = Array.isArray(err);
if (!multiple) {
err = [err];
}
if ('error' in this.ports && (this.ports.error.isAttached() || !this.ports.error.isRequired())) {
if (multiple) {
this.sendIP('error', new IP('openBracket'));
if (this.ordered || this.autoOrdering) {
this.outputQ.push(context.result);
}
for (i = 0, len1 = err.length; i < len1; i++) {
e = err[i];
this.sendIP('error', e);
}
if (multiple) {
return this.sendIP('error', new IP('closeBracket'));
}
} else {
results = [];
for (j = 0, len2 = err.length; j < len2; j++) {
e = err[j];
throw e;
}
return results;
}
}
} // Signal that component has deactivated. There may be multiple
// activated contexts at the same time
// Sends a single IP object to a port
sendIP(port, packet) {
var ip;
if (!IP.isIP(packet)) {
ip = new IP('data', packet);
} else {
ip = packet;
}
if (this.scope !== null && ip.scope === null) {
ip.scope = this.scope;
}
if (this.nodeInstance.outPorts[port].isAddressable() && ip.index === null) {
throw new Error('Sending packets to addressable ports requires specifying index');
}
if (this.nodeInstance.isOrdered()) {
this.nodeInstance.addToResult(this.result, port, ip);
return;
}
if (!this.nodeInstance.outPorts[port].options.scoped) {
ip.scope = null;
}
return this.nodeInstance.outPorts[port].sendIP(ip);
}
}, {
key: "deactivate",
value: function deactivate(context) {
if (context.deactivated) {
return;
} // prevent double deactivation
// Sends packets for each port as a key in the map
// or sends Error or a list of Errors if passed such
send(outputMap) {
var componentPorts, i, len1, mapIsInPorts, packet, port, ref, results;
if (this.isError(outputMap)) {
return this.error(outputMap);
}
componentPorts = [];
mapIsInPorts = false;
ref = Object.keys(this.ports.ports);
for (i = 0, len1 = ref.length; i < len1; i++) {
port = ref[i];
if (port !== 'error' && port !== 'ports' && port !== '_callbacks') {
componentPorts.push(port);
}
if (!mapIsInPorts && (outputMap != null) && typeof outputMap === 'object' && Object.keys(outputMap).indexOf(port) !== -1) {
mapIsInPorts = true;
}
}
if (componentPorts.length === 1 && !mapIsInPorts) {
this.sendIP(componentPorts[0], outputMap);
return;
}
if (componentPorts.length > 1 && !mapIsInPorts) {
throw new Error('Port must be specified for sending output');
}
results = [];
for (port in outputMap) {
packet = outputMap[port];
results.push(this.sendIP(port, packet));
}
return results;
}
// Sends the argument via `send()` and marks activation as `done()`
sendDone(outputMap) {
this.send(outputMap);
return this.done();
}
context.deactivated = true;
context.activated = false;
// Makes a map-style component pass a result value to `out`
// keeping all IP metadata received from `in`,
// or modifying it if `options` is provided
pass(data, options = {}) {
var key, val;
if (!('out' in this.ports)) {
throw new Error('output.pass() requires port "out" to be present');
}
for (key in options) {
val = options[key];
this.ip[key] = val;
}
this.ip.data = data;
this.sendIP('out', this.ip);
return this.done();
}
if (this.isOrdered()) {
this.processOutputQueue();
}
// Finishes process activation gracefully
done(error) {
var buf, context, contexts, ctx, ip, isLast, nodeContext, port, ref;
this.result.__resolved = true;
this.nodeInstance.activate(this.context);
if (error) {
this.error(error);
this.load -= 1;
this.emit('deactivate', this.load);
}
isLast = () => {
var len, load, pos, resultsOnly;
// We only care about real output sets with processing data
resultsOnly = this.nodeInstance.outputQ.filter(function(q) {
if (!q.__resolved) {
return true;
}
if (Object.keys(q).length === 2 && q.__bracketClosingAfter) {
return false;
}
return true;
});
pos = resultsOnly.indexOf(this.result);
len = resultsOnly.length;
load = this.nodeInstance.load;
if (pos === len - 1) {
return true;
}
if (pos === -1 && load === len + 1) {
return true;
}
if (len <= 1 && load === 1) {
return true;
}
return false;
};
if (this.nodeInstance.isOrdered() && isLast()) {
ref = this.nodeInstance.bracketContext.in;
// We're doing bracket forwarding. See if there are
// dangling closeBrackets in buffer since we're the
// last running process function.
for (port in ref) {
contexts = ref[port];
if (!contexts[this.scope]) {
continue;
}
nodeContext = contexts[this.scope];
if (!nodeContext.length) {
continue;
}
context = nodeContext[nodeContext.length - 1];
buf = this.nodeInstance.inPorts[context.source].getBuffer(context.ip.scope, context.ip.index);
while (true) {
if (!buf.length) {
break;
}
if (buf[0].type !== 'closeBracket') {
break;
}
ip = this.nodeInstance.inPorts[context.source].get(context.ip.scope, context.ip.index);
ctx = nodeContext.pop();
ctx.closeIp = ip;
if (!this.result.__bracketClosingAfter) {
this.result.__bracketClosingAfter = [];
}
this.result.__bracketClosingAfter.push(ctx);
}
}
}
debug(`${this.nodeInstance.nodeId} finished processing ${this.nodeInstance.load}`);
return this.nodeInstance.deactivate(this.context);
}
}]);
};
return Component;
}(EventEmitter);
exports.Component = Component;
Component.description = '';
Component.icon = null;
exports.Component = Component;

@@ -0,1 +1,37 @@

"use strict";
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
// NoFlo - Flow-Based Programming for JavaScript

@@ -5,18 +41,20 @@ // (c) 2013-2017 Flowhub UG

// NoFlo may be freely distributed under the MIT license
var ComponentLoader, EventEmitter, fbpGraph, platform, registerLoader;
fbpGraph = require('fbp-graph');
/* eslint-disable
class-methods-use-this,
import/no-unresolved,
*/
var fbpGraph = require('fbp-graph');
({EventEmitter} = require('events'));
var _require = require('events'),
EventEmitter = _require.EventEmitter;
registerLoader = require('./loader/register');
var registerLoader = require('./loader/register');
platform = require('./Platform');
// ## The NoFlo Component Loader
var platform = require('./Platform'); // ## The NoFlo Component Loader
//
// The Component Loader is responsible for discovering components
// available in the running system, as well as for instantiating
// them.
//
// Internally the loader uses a registered, platform-specific

@@ -29,329 +67,428 @@ // loader. NoFlo ships with a loader for Node.js that discovers

// loader using the [noflo-component-loader](https://github.com/noflo/noflo-component-loader) webpack plugin.
ComponentLoader = class ComponentLoader extends EventEmitter {
constructor(baseDir, options = {}) {
super();
this.baseDir = baseDir;
this.options = options;
this.components = null;
this.libraryIcons = {};
this.processing = false;
this.ready = false;
this.setMaxListeners(0);
}
// Get the library prefix for a given module name. This
var ComponentLoader = /*#__PURE__*/function (_EventEmitter) {
_inherits(ComponentLoader, _EventEmitter);
var _super = _createSuper(ComponentLoader);
function ComponentLoader(baseDir) {
var _this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, ComponentLoader);
_this = _super.call(this);
_this.baseDir = baseDir;
_this.options = options;
_this.components = null;
_this.libraryIcons = {};
_this.processing = false;
_this.ready = false;
_this.setMaxListeners(0);
return _this;
} // Get the library prefix for a given module name. This
// is mostly used for generating valid names for namespaced
// NPM modules, as well as for convenience renaming all
// `noflo-` prefixed modules with just their base name.
//
// Examples:
//
// * `my-project` becomes `my-project`
// * `@foo/my-project` becomes `my-project`
// * `noflo-core` becomes `core`
getModulePrefix(name) {
if (!name) {
return '';
}
if (name === 'noflo') {
return '';
}
if (name[0] === '@') {
name = name.replace(/\@[a-z\-]+\//, '');
}
return name.replace(/^noflo-/, '');
}
// Get the list of all available components
listComponents(callback) {
if (this.processing) {
this.once('ready', () => {
return callback(null, this.components);
_createClass(ComponentLoader, [{
key: "getModulePrefix",
value: function getModulePrefix(name) {
if (!name) {
return '';
}
var res = name;
if (res === 'noflo') {
return '';
}
if (res[0] === '@') {
res = res.replace(/@[a-z-]+\//, '');
}
return res.replace(/^noflo-/, '');
} // Get the list of all available components
}, {
key: "listComponents",
value: function listComponents(callback) {
var _this2 = this;
if (this.processing) {
this.once('ready', function () {
return callback(null, _this2.components);
});
return;
}
if (this.components) {
callback(null, this.components);
return;
}
this.ready = false;
this.processing = true;
this.components = {};
registerLoader.register(this, function (err) {
if (err) {
callback(err);
return;
}
_this2.processing = false;
_this2.ready = true;
_this2.emit('ready', true);
callback(null, _this2.components);
});
return;
}
if (this.components) {
return callback(null, this.components);
}
this.ready = false;
this.processing = true;
this.components = {};
registerLoader.register(this, (err) => {
if (err) {
if (callback) {
return callback(err);
} // Load an instance of a specific component. If the
// registered component is a JSON or FBP graph, it will
// be loaded as an instance of the NoFlo subgraph
// component.
}, {
key: "load",
value: function load(name, callback, metadata) {
var _this3 = this;
if (!this.ready) {
this.listComponents(function (err) {
if (err) {
callback(err);
return;
}
_this3.load(name, callback, metadata);
});
return;
}
var component = this.components[name];
if (!component) {
// Try an alias
var keys = Object.keys(this.components);
for (var i = 0; i < keys.length; i += 1) {
var componentName = keys[i];
if (componentName.split('/')[1] === name) {
component = this.components[componentName];
break;
}
}
throw err;
if (!component) {
// Failure to load
callback(new Error("Component ".concat(name, " not available with base ").concat(this.baseDir)));
return;
}
}
this.processing = false;
this.ready = true;
this.emit('ready', true);
if (callback) {
return callback(null, this.components);
if (this.isGraph(component)) {
this.loadGraph(name, component, callback, metadata);
return;
}
});
}
// Load an instance of a specific component. If the
// registered component is a JSON or FBP graph, it will
// be loaded as an instance of the NoFlo subgraph
// component.
load(name, callback, metadata) {
var component, componentName;
if (!this.ready) {
this.listComponents((err) => {
this.createComponent(name, component, metadata, function (err, instance) {
var inst = instance;
if (err) {
return callback(err);
callback(err);
return;
}
return this.load(name, callback, metadata);
if (!inst) {
callback(new Error("Component ".concat(name, " could not be loaded.")));
return;
}
if (name === 'Graph') {
inst.baseDir = _this3.baseDir;
}
if (typeof name === 'string') {
inst.componentName = name;
}
if (inst.isLegacy()) {
platform.deprecated("Component ".concat(name, " uses legacy NoFlo APIs. Please port to Process API"));
}
_this3.setIcon(name, inst);
callback(null, inst);
});
return;
}
component = this.components[name];
if (!component) {
// Try an alias
for (componentName in this.components) {
if (componentName.split('/')[1] === name) {
component = this.components[componentName];
break;
} // Creates an instance of a component.
}, {
key: "createComponent",
value: function createComponent(name, component, metadata, callback) {
var e;
var instance;
var implementation = component;
if (!implementation) {
callback(new Error("Component ".concat(name, " not available")));
return;
} // If a string was specified, attempt to `require` it.
if (typeof implementation === 'string') {
if (typeof registerLoader.dynamicLoad === 'function') {
registerLoader.dynamicLoad(name, implementation, metadata, callback);
return;
}
}
if (!component) {
// Failure to load
callback(new Error(`Component ${name} not available with base ${this.baseDir}`));
callback(Error("Dynamic loading of ".concat(implementation, " for component ").concat(name, " not available on this platform.")));
return;
}
}
if (this.isGraph(component)) {
if (!platform.isBrowser()) {
// nextTick is faster on Node.js
process.nextTick(() => {
return this.loadGraph(name, component, callback, metadata);
});
} // Attempt to create the component instance using the `getComponent` method.
if (typeof implementation.getComponent === 'function') {
try {
instance = implementation.getComponent(metadata);
} catch (error) {
e = error;
callback(e);
return;
} // Attempt to create a component using a factory function.
} else if (typeof implementation === 'function') {
try {
instance = implementation(metadata);
} catch (error1) {
e = error1;
callback(e);
return;
}
} else {
setTimeout(() => {
return this.loadGraph(name, component, callback, metadata);
}, 0);
}
return;
}
return this.createComponent(name, component, metadata, (err, instance) => {
if (err) {
return callback(err);
}
if (!instance) {
callback(new Error(`Component ${name} could not be loaded.`));
callback(new Error("Invalid type ".concat(_typeof(implementation), " for component ").concat(name, ".")));
return;
}
if (name === 'Graph') {
instance.baseDir = this.baseDir;
callback(null, instance);
} // Check if a given filesystem path is actually a graph
}, {
key: "isGraph",
value: function isGraph(cPath) {
// Live graph instance
if (_typeof(cPath) === 'object' && cPath instanceof fbpGraph.Graph) {
return true;
} // Graph JSON definition
if (_typeof(cPath) === 'object' && cPath.processes && cPath.connections) {
return true;
}
if (typeof name === 'string') {
instance.componentName = name;
}
if (instance.isLegacy()) {
platform.deprecated(`Component ${name} uses legacy NoFlo APIs. Please port to Process API`);
}
this.setIcon(name, instance);
return callback(null, instance);
});
}
// Creates an instance of a component.
createComponent(name, component, metadata, callback) {
var e, implementation, instance;
implementation = component;
if (!implementation) {
return callback(new Error(`Component ${name} not available`));
}
// If a string was specified, attempt to `require` it.
if (typeof implementation === 'string') {
if (typeof registerLoader.dynamicLoad === 'function') {
registerLoader.dynamicLoad(name, implementation, metadata, callback);
if (typeof cPath !== 'string') {
return false;
} // Graph file path
return cPath.indexOf('.fbp') !== -1 || cPath.indexOf('.json') !== -1;
} // Load a graph as a NoFlo subgraph component instance
}, {
key: "loadGraph",
value: function loadGraph(name, component, callback, metadata) {
var _this4 = this;
this.createComponent(name, this.components.Graph, metadata, function (error, graph) {
var g = graph;
if (error) {
callback(error);
return;
}
g.loader = _this4;
g.baseDir = _this4.baseDir;
g.inPorts.remove('graph');
g.setGraph(component, function (err) {
if (err) {
callback(err);
return;
}
_this4.setIcon(name, g);
callback(null, g);
});
});
} // Set icon for the component instance. If the instance
// has an icon set, then this is a no-op. Otherwise we
// determine an icon based on the module it is coming
// from, or use a fallback icon separately for subgraphs
// and elementary components.
}, {
key: "setIcon",
value: function setIcon(name, instance) {
// See if component has an icon
if (!instance.getIcon || instance.getIcon()) {
return;
} // See if library has an icon
var _name$split = name.split('/'),
_name$split2 = _slicedToArray(_name$split, 2),
library = _name$split2[0],
componentName = _name$split2[1];
if (componentName && this.getLibraryIcon(library)) {
instance.setIcon(this.getLibraryIcon(library));
return;
} // See if instance is a subgraph
if (instance.isSubgraph()) {
instance.setIcon('sitemap');
return;
}
return callback(Error(`Dynamic loading of ${implementation} for component ${name} not available on this platform.`));
instance.setIcon('gear');
}
// Attempt to create the component instance using the `getComponent` method.
if (typeof implementation.getComponent === 'function') {
try {
instance = implementation.getComponent(metadata);
} catch (error) {
e = error;
return callback(e);
}, {
key: "getLibraryIcon",
value: function getLibraryIcon(prefix) {
if (this.libraryIcons[prefix]) {
return this.libraryIcons[prefix];
}
// Attempt to create a component using a factory function.
} else if (typeof implementation === 'function') {
try {
instance = implementation(metadata);
} catch (error) {
e = error;
return callback(e);
}
} else {
callback(new Error(`Invalid type ${typeof implementation} for component ${name}.`));
return;
}
return callback(null, instance);
}
// Check if a given filesystem path is actually a graph
isGraph(cPath) {
if (typeof cPath === 'object' && cPath instanceof fbpGraph.Graph) {
// Live graph instance
return true;
return null;
}
if (typeof cPath === 'object' && cPath.processes && cPath.connections) {
// Graph JSON definition
return true;
}, {
key: "setLibraryIcon",
value: function setLibraryIcon(prefix, icon) {
this.libraryIcons[prefix] = icon;
}
if (typeof cPath !== 'string') {
return false;
}
// Graph file path
return cPath.indexOf('.fbp') !== -1 || cPath.indexOf('.json') !== -1;
}
}, {
key: "normalizeName",
value: function normalizeName(packageId, name) {
var prefix = this.getModulePrefix(packageId);
var fullName = "".concat(prefix, "/").concat(name);
// Load a graph as a NoFlo subgraph component instance
loadGraph(name, component, callback, metadata) {
this.createComponent(name, this.components['Graph'], metadata, (err, graph) => {
if (err) {
return callback(err);
if (!packageId) {
fullName = name;
}
graph.loader = this;
graph.baseDir = this.baseDir;
graph.inPorts.remove('graph');
graph.setGraph(component, (err) => {
if (err) {
return callback(err);
}
this.setIcon(name, graph);
return callback(null, graph);
});
});
}
// Set icon for the component instance. If the instance
// has an icon set, then this is a no-op. Otherwise we
// determine an icon based on the module it is coming
// from, or use a fallback icon separately for subgraphs
// and elementary components.
setIcon(name, instance) {
var componentName, library;
// See if component has an icon
if (!instance.getIcon || instance.getIcon()) {
return;
}
// See if library has an icon
[library, componentName] = name.split('/');
if (componentName && this.getLibraryIcon(library)) {
instance.setIcon(this.getLibraryIcon(library));
return;
}
// See if instance is a subgraph
if (instance.isSubgraph()) {
instance.setIcon('sitemap');
return;
}
instance.setIcon('gear');
}
return fullName;
} // ### Registering components at runtime
//
// In addition to components discovered by the loader,
// it is possible to register components at runtime.
//
// With the `registerComponent` method you can register
// a NoFlo Component constructor or factory method
// as a component available for loading.
getLibraryIcon(prefix) {
if (this.libraryIcons[prefix]) {
return this.libraryIcons[prefix];
}
return null;
}
}, {
key: "registerComponent",
value: function registerComponent(packageId, name, cPath, callback) {
var fullName = this.normalizeName(packageId, name);
this.components[fullName] = cPath;
setLibraryIcon(prefix, icon) {
return this.libraryIcons[prefix] = icon;
}
if (callback) {
callback();
}
} // With the `registerGraph` method you can register new
// graphs as loadable components.
normalizeName(packageId, name) {
var fullName, prefix;
prefix = this.getModulePrefix(packageId);
fullName = `${prefix}/${name}`;
if (!packageId) {
fullName = name;
}
return fullName;
}
}, {
key: "registerGraph",
value: function registerGraph(packageId, name, gPath, callback) {
this.registerComponent(packageId, name, gPath, callback);
} // With `registerLoader` you can register custom component
// loaders. They will be called immediately and can register
// any components or graphs they wish.
// ### Registering components at runtime
}, {
key: "registerLoader",
value: function registerLoader(loader, callback) {
loader(this, callback);
} // With `setSource` you can register a component by providing
// a source code string. Supported languages and techniques
// depend on the runtime environment, for example CoffeeScript
// components can only be registered via `setSource` if
// the environment has a CoffeeScript compiler loaded.
// In addition to components discovered by the loader,
// it is possible to register components at runtime.
}, {
key: "setSource",
value: function setSource(packageId, name, source, language, callback) {
var _this5 = this;
// With the `registerComponent` method you can register
// a NoFlo Component constructor or factory method
// as a component available for loading.
registerComponent(packageId, name, cPath, callback) {
var fullName;
fullName = this.normalizeName(packageId, name);
this.components[fullName] = cPath;
if (callback) {
return callback();
}
}
if (!registerLoader.setSource) {
callback(new Error('setSource not allowed'));
return;
}
// With the `registerGraph` method you can register new
// graphs as loadable components.
registerGraph(packageId, name, gPath, callback) {
return this.registerComponent(packageId, name, gPath, callback);
}
if (!this.ready) {
this.listComponents(function (err) {
if (err) {
callback(err);
return;
}
// With `registerLoader` you can register custom component
// loaders. They will be called immediately and can register
// any components or graphs they wish.
registerLoader(loader, callback) {
return loader(this, callback);
}
_this5.setSource(packageId, name, source, language, callback);
});
return;
}
// With `setSource` you can register a component by providing
// a source code string. Supported languages and techniques
// depend on the runtime environment, for example CoffeeScript
// components can only be registered via `setSource` if
// the environment has a CoffeeScript compiler loaded.
setSource(packageId, name, source, language, callback) {
if (!registerLoader.setSource) {
return callback(new Error('setSource not allowed'));
}
if (!this.ready) {
this.listComponents((err) => {
if (err) {
return callback(err);
}
return this.setSource(packageId, name, source, language, callback);
});
return;
}
return registerLoader.setSource(this, packageId, name, source, language, callback);
}
registerLoader.setSource(this, packageId, name, source, language, callback);
} // `getSource` allows fetching the source code of a registered
// component as a string.
// `getSource` allows fetching the source code of a registered
// component as a string.
getSource(name, callback) {
if (!registerLoader.getSource) {
return callback(new Error('getSource not allowed'));
}, {
key: "getSource",
value: function getSource(name, callback) {
var _this6 = this;
if (!registerLoader.getSource) {
callback(new Error('getSource not allowed'));
return;
}
if (!this.ready) {
this.listComponents(function (err) {
if (err) {
callback(err);
return;
}
_this6.getSource(name, callback);
});
return;
}
registerLoader.getSource(this, name, callback);
}
if (!this.ready) {
this.listComponents((err) => {
if (err) {
return callback(err);
}
return this.getSource(name, callback);
});
return;
}, {
key: "clear",
value: function clear() {
this.components = null;
this.ready = false;
this.processing = false;
}
return registerLoader.getSource(this, name, callback);
}
}]);
clear() {
this.components = null;
this.ready = false;
return this.processing = false;
}
return ComponentLoader;
}(EventEmitter);
};
exports.ComponentLoader = ComponentLoader;
exports.ComponentLoader = ComponentLoader;

@@ -0,274 +1,383 @@

"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
// NoFlo - Flow-Based Programming for JavaScript
// (c) 2014-2017 Flowhub UG
// NoFlo may be freely distributed under the MIT license
var BasePort, IP, InPort;
var BasePort = require('./BasePort'); // ## NoFlo inport
//
// Input Port (inport) implementation for NoFlo components. These
// ports are the way a component receives Information Packets.
BasePort = require('./BasePort');
IP = require('./IP');
module.exports = /*#__PURE__*/function (_BasePort) {
_inherits(InPort, _BasePort);
// ## NoFlo inport
var _super = _createSuper(InPort);
// Input Port (inport) implementation for NoFlo components. These
// ports are the way a component receives Information Packets.
InPort = class InPort extends BasePort {
constructor(options = {}) {
if (options.control == null) {
options.control = false;
function InPort() {
var _this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, InPort);
var opts = options;
if (opts.control == null) {
opts.control = false;
}
if (options.scoped == null) {
options.scoped = true;
if (opts.scoped == null) {
opts.scoped = true;
}
if (options.triggering == null) {
options.triggering = true;
if (opts.triggering == null) {
opts.triggering = true;
}
if (options.process) {
if (opts.process) {
throw new Error('InPort process callback is deprecated. Please use Process API');
}
if (options.handle) {
if (opts.handle) {
throw new Error('InPort handle callback is deprecated. Please use Process API');
}
super(options);
this.prepareBuffer();
}
// Assign a delegate for retrieving data should this inPort
attachSocket(socket, localId = null) {
// have a default value.
if (this.hasDefault()) {
socket.setDataDelegate(() => {
return this.options.default;
_this = _super.call(this, opts);
_this.prepareBuffer();
return _this;
} // Assign a delegate for retrieving data should this inPort
_createClass(InPort, [{
key: "attachSocket",
value: function attachSocket(socket) {
var _this2 = this;
var localId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
// have a default value.
if (this.hasDefault()) {
socket.setDataDelegate(function () {
return _this2.options["default"];
});
}
socket.on('connect', function () {
return _this2.handleSocketEvent('connect', socket, localId);
});
socket.on('begingroup', function (group) {
return _this2.handleSocketEvent('begingroup', group, localId);
});
socket.on('data', function (data) {
_this2.validateData(data);
return _this2.handleSocketEvent('data', data, localId);
});
socket.on('endgroup', function (group) {
return _this2.handleSocketEvent('endgroup', group, localId);
});
socket.on('disconnect', function () {
return _this2.handleSocketEvent('disconnect', socket, localId);
});
socket.on('ip', function (ip) {
return _this2.handleIP(ip, localId);
});
}
socket.on('connect', () => {
return this.handleSocketEvent('connect', socket, localId);
});
socket.on('begingroup', (group) => {
return this.handleSocketEvent('begingroup', group, localId);
});
socket.on('data', (data) => {
this.validateData(data);
return this.handleSocketEvent('data', data, localId);
});
socket.on('endgroup', (group) => {
return this.handleSocketEvent('endgroup', group, localId);
});
socket.on('disconnect', () => {
return this.handleSocketEvent('disconnect', socket, localId);
});
return socket.on('ip', (ip) => {
return this.handleIP(ip, localId);
});
}
}, {
key: "handleIP",
value: function handleIP(packet, index) {
if (this.options.control && packet.type !== 'data') {
return;
}
handleIP(ip, id) {
var buf;
if (this.options.control && ip.type !== 'data') {
return;
var ip = packet;
ip.owner = this.nodeInstance;
if (this.isAddressable()) {
ip.index = index;
}
if (ip.datatype === 'all') {
// Stamp non-specific IP objects with port datatype
ip.datatype = this.getDataType();
}
if (this.getSchema() && !ip.schema) {
// Stamp non-specific IP objects with port schema
ip.schema = this.getSchema();
}
var buf = this.prepareBufferForIP(ip);
buf.push(ip);
if (this.options.control && buf.length > 1) {
buf.shift();
}
this.emit('ip', ip, index);
}
ip.owner = this.nodeInstance;
if (this.isAddressable()) {
ip.index = id;
}, {
key: "handleSocketEvent",
value: function handleSocketEvent(event, payload, id) {
// Emit port event
if (this.isAddressable()) {
return this.emit(event, payload, id);
}
return this.emit(event, payload);
}
if (ip.datatype === 'all') {
// Stamp non-specific IP objects with port datatype
ip.datatype = this.getDataType();
}, {
key: "hasDefault",
value: function hasDefault() {
return this.options["default"] !== undefined;
}
if (this.getSchema() && !ip.schema) {
// Stamp non-specific IP objects with port schema
ip.schema = this.getSchema();
}
buf = this.prepareBufferForIP(ip);
buf.push(ip);
if (this.options.control && buf.length > 1) {
buf.shift();
}
return this.emit('ip', ip, id);
}
}, {
key: "prepareBuffer",
value: function prepareBuffer() {
if (this.isAddressable()) {
if (this.options.scoped) {
this.scopedBuffer = {};
}
handleSocketEvent(event, payload, id) {
if (this.isAddressable()) {
// Emit port event
return this.emit(event, payload, id);
}
return this.emit(event, payload);
}
this.indexedBuffer = {};
this.iipBuffer = {};
return;
}
hasDefault() {
return this.options.default !== void 0;
}
prepareBuffer() {
if (this.isAddressable()) {
if (this.options.scoped) {
this.scopedBuffer = {};
}
this.indexedBuffer = {};
this.iipBuffer = {};
return;
this.iipBuffer = [];
this.buffer = [];
}
if (this.options.scoped) {
this.scopedBuffer = {};
}
this.iipBuffer = [];
this.buffer = [];
}
}, {
key: "prepareBufferForIP",
value: function prepareBufferForIP(ip) {
if (this.isAddressable()) {
if (ip.scope != null && this.options.scoped) {
if (!(ip.scope in this.scopedBuffer)) {
this.scopedBuffer[ip.scope] = [];
}
prepareBufferForIP(ip) {
if (this.isAddressable()) {
if ((ip.scope != null) && this.options.scoped) {
if (!(ip.index in this.scopedBuffer[ip.scope])) {
this.scopedBuffer[ip.scope][ip.index] = [];
}
return this.scopedBuffer[ip.scope][ip.index];
}
if (ip.initial) {
if (!(ip.index in this.iipBuffer)) {
this.iipBuffer[ip.index] = [];
}
return this.iipBuffer[ip.index];
}
if (!(ip.index in this.indexedBuffer)) {
this.indexedBuffer[ip.index] = [];
}
return this.indexedBuffer[ip.index];
}
if (ip.scope != null && this.options.scoped) {
if (!(ip.scope in this.scopedBuffer)) {
this.scopedBuffer[ip.scope] = [];
}
if (!(ip.index in this.scopedBuffer[ip.scope])) {
this.scopedBuffer[ip.scope][ip.index] = [];
}
return this.scopedBuffer[ip.scope][ip.index];
return this.scopedBuffer[ip.scope];
}
if (ip.initial) {
if (!(ip.index in this.iipBuffer)) {
this.iipBuffer[ip.index] = [];
}
return this.iipBuffer[ip.index];
return this.iipBuffer;
}
if (!(ip.index in this.indexedBuffer)) {
this.indexedBuffer[ip.index] = [];
}
return this.indexedBuffer[ip.index];
return this.buffer;
}
if ((ip.scope != null) && this.options.scoped) {
if (!(ip.scope in this.scopedBuffer)) {
this.scopedBuffer[ip.scope] = [];
}, {
key: "validateData",
value: function validateData(data) {
if (!this.options.values) {
return;
}
return this.scopedBuffer[ip.scope];
}
if (ip.initial) {
return this.iipBuffer;
}
return this.buffer;
}
validateData(data) {
if (!this.options.values) {
return;
if (this.options.values.indexOf(data) === -1) {
throw new Error("Invalid data='".concat(data, "' received, not in [").concat(this.options.values, "]"));
}
}
if (this.options.values.indexOf(data) === -1) {
throw new Error(`Invalid data='${data}' received, not in [${this.options.values}]`);
}
}
}, {
key: "getBuffer",
value: function getBuffer(scope, index) {
var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
getBuffer(scope, idx, initial = false) {
if (this.isAddressable()) {
if ((scope != null) && this.options.scoped) {
if (!(scope in this.scopedBuffer)) {
return void 0;
if (this.isAddressable()) {
if (scope != null && this.options.scoped) {
if (!(scope in this.scopedBuffer)) {
return undefined;
}
if (!(index in this.scopedBuffer[scope])) {
return undefined;
}
return this.scopedBuffer[scope][index];
}
if (!(idx in this.scopedBuffer[scope])) {
return void 0;
if (initial) {
if (!(index in this.iipBuffer)) {
return undefined;
}
return this.iipBuffer[index];
}
return this.scopedBuffer[scope][idx];
if (!(index in this.indexedBuffer)) {
return undefined;
}
return this.indexedBuffer[index];
}
if (initial) {
if (!(idx in this.iipBuffer)) {
return void 0;
if (scope != null && this.options.scoped) {
if (!(scope in this.scopedBuffer)) {
return undefined;
}
return this.iipBuffer[idx];
return this.scopedBuffer[scope];
}
if (!(idx in this.indexedBuffer)) {
return void 0;
if (initial) {
return this.iipBuffer;
}
return this.indexedBuffer[idx];
return this.buffer;
}
if ((scope != null) && this.options.scoped) {
if (!(scope in this.scopedBuffer)) {
return void 0;
}, {
key: "getFromBuffer",
value: function getFromBuffer(scope, index) {
var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var buf = this.getBuffer(scope, index, initial);
if (!(buf != null ? buf.length : undefined)) {
return undefined;
}
return this.scopedBuffer[scope];
}
if (initial) {
return this.iipBuffer;
}
return this.buffer;
}
getFromBuffer(scope, idx, initial = false) {
var buf;
buf = this.getBuffer(scope, idx, initial);
if (!(buf != null ? buf.length : void 0)) {
return void 0;
}
if (this.options.control) {
return buf[buf.length - 1];
} else {
if (this.options.control) {
return buf[buf.length - 1];
}
return buf.shift();
}
}
} // Fetches a packet from the port
// Fetches a packet from the port
get(scope, idx) {
var res;
res = this.getFromBuffer(scope, idx);
if (res !== void 0) {
return res;
}, {
key: "get",
value: function get(scope, index) {
var res = this.getFromBuffer(scope, index);
if (res !== undefined) {
return res;
} // Try to find an IIP instead
return this.getFromBuffer(null, index, true);
}
// Try to find an IIP instead
return this.getFromBuffer(null, idx, true);
}
}, {
key: "hasIPinBuffer",
value: function hasIPinBuffer(scope, index, validate) {
var initial = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var buf = this.getBuffer(scope, index, initial);
hasIPinBuffer(scope, idx, validate, initial = false) {
var buf, i, len, packet;
buf = this.getBuffer(scope, idx, initial);
if (!(buf != null ? buf.length : void 0)) {
if (!(buf != null ? buf.length : undefined)) {
return false;
}
for (var i = 0; i < buf.length; i += 1) {
if (validate(buf[i])) {
return true;
}
}
return false;
}
for (i = 0, len = buf.length; i < len; i++) {
packet = buf[i];
if (validate(packet)) {
}, {
key: "hasIIP",
value: function hasIIP(index, validate) {
return this.hasIPinBuffer(null, index, validate, true);
} // Returns true if port contains packet(s) matching the validator
}, {
key: "has",
value: function has(scope, index, validate) {
var valid = validate;
var idx = index;
if (!this.isAddressable()) {
valid = idx;
idx = null;
}
if (this.hasIPinBuffer(scope, idx, valid)) {
return true;
}
}
return false;
}
hasIIP(idx, validate) {
return this.hasIPinBuffer(null, idx, validate, true);
}
if (this.hasIIP(idx, valid)) {
return true;
}
// Returns true if port contains packet(s) matching the validator
has(scope, idx, validate) {
if (!this.isAddressable()) {
validate = idx;
idx = null;
}
if (this.hasIPinBuffer(scope, idx, validate)) {
return true;
}
if (this.hasIIP(idx, validate)) {
return true;
}
return false;
}
return false;
} // Returns the number of data packets in an inport
// Returns the number of data packets in an inport
length(scope, idx) {
var buf;
buf = this.getBuffer(scope, idx);
if (!buf) {
return 0;
}
return buf.length;
}
}, {
key: "length",
value: function length(scope, index) {
var buf = this.getBuffer(scope, index);
// Tells if buffer has packets or not
ready(scope, idx) {
return this.length(scope) > 0;
}
if (!buf) {
return 0;
}
// Clears inport buffers
clear() {
return this.prepareBuffer();
}
return buf.length;
} // Tells if buffer has packets or not
};
}, {
key: "ready",
value: function ready(scope) {
return this.length(scope) > 0;
} // Clears inport buffers
module.exports = InPort;
}, {
key: "clear",
value: function clear() {
return this.prepareBuffer();
}
}]);
return InPort;
}(BasePort);

@@ -0,1 +1,25 @@

"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
// NoFlo - Flow-Based Programming for JavaScript

@@ -5,10 +29,54 @@ // (c) 2013-2017 Flowhub UG

// NoFlo may be freely distributed under the MIT license
var EventEmitter, IP, InternalSocket;
var _require = require('events'),
EventEmitter = _require.EventEmitter;
({EventEmitter} = require('events'));
var IP = require('./IP');
IP = require('./IP');
function legacyToIp(event, payload) {
// No need to wrap modern IP Objects
if (IP.isIP(payload)) {
return payload;
} // Wrap legacy events into appropriate IP objects
// ## Internal Sockets
switch (event) {
case 'begingroup':
return new IP('openBracket', payload);
case 'endgroup':
return new IP('closeBracket');
case 'data':
return new IP('data', payload);
default:
return null;
}
}
function ipToLegacy(ip) {
switch (ip.type) {
case 'openBracket':
return {
event: 'begingroup',
payload: ip.data
};
case 'data':
return {
event: 'data',
payload: ip.data
};
case 'closeBracket':
return {
event: 'endgroup',
payload: ip.data
};
default:
return null;
}
} // ## Internal Sockets
//
// The default communications mechanism between NoFlo processes is

@@ -19,44 +87,60 @@ // an _internal socket_, which is responsible for accepting information

// connected process.
InternalSocket = class InternalSocket extends EventEmitter {
regularEmitEvent(event, data) {
return this.emit(event, data);
}
debugEmitEvent(event, data) {
var error;
try {
return this.emit(event, data);
} catch (error1) {
error = error1;
if (error.id && error.metadata && error.error) {
if (this.listeners('error').length === 0) {
var InternalSocket = /*#__PURE__*/function (_EventEmitter) {
_inherits(InternalSocket, _EventEmitter);
var _super = _createSuper(InternalSocket);
_createClass(InternalSocket, [{
key: "regularEmitEvent",
value: function regularEmitEvent(event, data) {
this.emit(event, data);
}
}, {
key: "debugEmitEvent",
value: function debugEmitEvent(event, data) {
try {
this.emit(event, data);
} catch (error) {
if (error.id && error.metadata && error.error) {
// Wrapped debuggable error coming from downstream, no need to wrap
throw error.error;
if (this.listeners('error').length === 0) {
throw error.error;
}
this.emit('error', error);
return;
}
this.emit('error', error);
return;
if (this.listeners('error').length === 0) {
throw error;
}
this.emit('error', {
id: this.to.process.id,
error: error,
metadata: this.metadata
});
}
if (this.listeners('error').length === 0) {
throw error;
}
return this.emit('error', {
id: this.to.process.id,
error: error,
metadata: this.metadata
});
}
}
}]);
constructor(metadata = {}) {
super();
this.metadata = metadata;
this.brackets = [];
this.connected = false;
this.dataDelegate = null;
this.debug = false;
this.emitEvent = this.regularEmitEvent;
}
function InternalSocket() {
var _this;
// ## Socket connections
var metadata = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, InternalSocket);
_this = _super.call(this);
_this.metadata = metadata;
_this.brackets = [];
_this.connected = false;
_this.dataDelegate = null;
_this.debug = false;
_this.emitEvent = _this.regularEmitEvent;
return _this;
} // ## Socket connections
//
// Sockets that are attached to the ports of processes may be

@@ -66,9 +150,9 @@ // either connected or disconnected. The semantical meaning of

// data. Disconnecting means an end of transmission.
//
// This can be used for example to signal the beginning and end
// of information packets resulting from the reading of a single
// file or a database query.
//
// Example, disconnecting when a file has been completely read:
//
// readBuffer: (fd, position, size, buffer) ->

@@ -80,248 +164,255 @@ // fs.read fd, buffer, 0, buffer.length, position, (err, bytes, buffer) =>

// position += buffer.length
//
// # Disconnect when the file has been completely read
// return @outPorts.out.disconnect() if position >= size
//
// # Otherwise, call same method recursively
// @readBuffer fd, position, size, buffer
connect() {
if (this.connected) {
return;
_createClass(InternalSocket, [{
key: "connect",
value: function connect() {
if (this.connected) {
return;
}
this.connected = true;
this.emitEvent('connect', null);
}
this.connected = true;
return this.emitEvent('connect', null);
}
}, {
key: "disconnect",
value: function disconnect() {
if (!this.connected) {
return;
}
disconnect() {
if (!this.connected) {
return;
this.connected = false;
this.emitEvent('disconnect', null);
}
this.connected = false;
return this.emitEvent('disconnect', null);
}
}, {
key: "isConnected",
value: function isConnected() {
return this.connected;
} // ## Sending information packets
//
// The _send_ method is used by a processe's outport to
// send information packets. The actual packet contents are
// not defined by NoFlo, and may be any valid JavaScript data
// structure.
//
// The packet contents however should be such that may be safely
// serialized or deserialized via JSON. This way the NoFlo networks
// can be constructed with more flexibility, as file buffers or
// message queues can be used as additional packet relay mechanisms.
isConnected() {
return this.connected;
}
}, {
key: "send",
value: function send(data) {
if (data === undefined && typeof this.dataDelegate === 'function') {
this.handleSocketEvent('data', this.dataDelegate());
return;
}
// ## Sending information packets
this.handleSocketEvent('data', data);
} // ## Sending information packets without open bracket
//
// As _connect_ event is considered as open bracket, it needs to be followed
// by a _disconnect_ event or a closing bracket. In the new simplified
// sending semantics single IP objects can be sent without open/close brackets.
// The _send_ method is used by a processe's outport to
// send information packets. The actual packet contents are
// not defined by NoFlo, and may be any valid JavaScript data
// structure.
}, {
key: "post",
value: function post(packet) {
var autoDisconnect = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var ip = packet;
// The packet contents however should be such that may be safely
// serialized or deserialized via JSON. This way the NoFlo networks
// can be constructed with more flexibility, as file buffers or
// message queues can be used as additional packet relay mechanisms.
send(data) {
if (data === void 0 && typeof this.dataDelegate === 'function') {
data = this.dataDelegate();
}
return this.handleSocketEvent('data', data);
}
if (ip === undefined && typeof this.dataDelegate === 'function') {
ip = this.dataDelegate();
} // Send legacy connect/disconnect if needed
// ## Sending information packets without open bracket
// As _connect_ event is considered as open bracket, it needs to be followed
// by a _disconnect_ event or a closing bracket. In the new simplified
// sending semantics single IP objects can be sent without open/close brackets.
post(ip, autoDisconnect = true) {
if (ip === void 0 && typeof this.dataDelegate === 'function') {
ip = this.dataDelegate();
}
// Send legacy connect/disconnect if needed
if (!this.isConnected() && this.brackets.length === 0) {
this.connect();
}
this.handleSocketEvent('ip', ip, false);
if (autoDisconnect && this.isConnected() && this.brackets.length === 0) {
return this.disconnect();
}
}
if (!this.isConnected() && this.brackets.length === 0) {
this.connect();
}
// ## Information Packet grouping
this.handleSocketEvent('ip', ip, false);
// Processes sending data to sockets may also group the packets
// when necessary. This allows transmitting tree structures as
// a stream of packets.
if (autoDisconnect && this.isConnected() && this.brackets.length === 0) {
this.disconnect();
}
} // ## Information Packet grouping
//
// Processes sending data to sockets may also group the packets
// when necessary. This allows transmitting tree structures as
// a stream of packets.
//
// For example, an object could be split into multiple packets
// where each property is identified by a separate grouping:
//
// # Group by object ID
// @outPorts.out.beginGroup object.id
//
// for property, value of object
// @outPorts.out.beginGroup property
// @outPorts.out.send value
// @outPorts.out.endGroup()
//
// @outPorts.out.endGroup()
//
// This would cause a tree structure to be sent to the receiving
// process as a stream of packets. So, an article object may be
// as packets like:
//
// * `/<article id>/title/Lorem ipsum`
// * `/<article id>/author/Henri Bergius`
//
// Components are free to ignore groupings, but are recommended
// to pass received groupings onward if the data structures remain
// intact through the component's processing.
// For example, an object could be split into multiple packets
// where each property is identified by a separate grouping:
}, {
key: "beginGroup",
value: function beginGroup(group) {
this.handleSocketEvent('begingroup', group);
}
}, {
key: "endGroup",
value: function endGroup() {
this.handleSocketEvent('endgroup');
} // ## Socket data delegation
//
// Sockets have the option to receive data from a delegate function
// should the `send` method receive undefined for `data`. This
// helps in the case of defaulting values.
// # Group by object ID
// @outPorts.out.beginGroup object.id
}, {
key: "setDataDelegate",
value: function setDataDelegate(delegate) {
if (typeof delegate !== 'function') {
throw Error('A data delegate must be a function.');
}
// for property, value of object
// @outPorts.out.beginGroup property
// @outPorts.out.send value
// @outPorts.out.endGroup()
this.dataDelegate = delegate;
} // ## Socket debug mode
//
// Sockets can catch exceptions happening in processes when data is
// sent to them. These errors can then be reported to the network for
// notification to the developer.
// @outPorts.out.endGroup()
}, {
key: "setDebug",
value: function setDebug(active) {
this.debug = active;
this.emitEvent = this.debug ? this.debugEmitEvent : this.regularEmitEvent;
} // ## Socket identifiers
//
// Socket identifiers are mainly used for debugging purposes.
// Typical identifiers look like _ReadFile:OUT -> Display:IN_,
// but for sockets sending initial information packets to
// components may also loom like _DATA -> ReadFile:SOURCE_.
// This would cause a tree structure to be sent to the receiving
// process as a stream of packets. So, an article object may be
// as packets like:
}, {
key: "getId",
value: function getId() {
var fromStr = function fromStr(from) {
return "".concat(from.process.id, "() ").concat(from.port.toUpperCase());
};
// * `/<article id>/title/Lorem ipsum`
// * `/<article id>/author/Henri Bergius`
var toStr = function toStr(to) {
return "".concat(to.port.toUpperCase(), " ").concat(to.process.id, "()");
};
// Components are free to ignore groupings, but are recommended
// to pass received groupings onward if the data structures remain
// intact through the component's processing.
beginGroup(group) {
return this.handleSocketEvent('begingroup', group);
}
if (!this.from && !this.to) {
return 'UNDEFINED';
}
endGroup() {
return this.handleSocketEvent('endgroup');
}
if (this.from && !this.to) {
return "".concat(fromStr(this.from), " -> ANON");
}
// ## Socket data delegation
if (!this.from) {
return "DATA -> ".concat(toStr(this.to));
}
// Sockets have the option to receive data from a delegate function
// should the `send` method receive undefined for `data`. This
// helps in the case of defaulting values.
setDataDelegate(delegate) {
if (typeof delegate !== 'function') {
throw Error('A data delegate must be a function.');
return "".concat(fromStr(this.from), " -> ").concat(toStr(this.to));
}
return this.dataDelegate = delegate;
}
/* eslint-disable no-param-reassign */
// ## Socket debug mode
}, {
key: "handleSocketEvent",
value: function handleSocketEvent(event, payload) {
var autoConnect = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var isIP = event === 'ip' && IP.isIP(payload);
var ip = isIP ? payload : legacyToIp(event, payload);
// Sockets can catch exceptions happening in processes when data is
// sent to them. These errors can then be reported to the network for
// notification to the developer.
setDebug(active) {
this.debug = active;
return this.emitEvent = this.debug ? this.debugEmitEvent : this.regularEmitEvent;
}
if (!ip) {
return;
}
// ## Socket identifiers
if (!this.isConnected() && autoConnect && this.brackets.length === 0) {
// Connect before sending
this.connect();
}
// Socket identifiers are mainly used for debugging purposes.
// Typical identifiers look like _ReadFile:OUT -> Display:IN_,
// but for sockets sending initial information packets to
// components may also loom like _DATA -> ReadFile:SOURCE_.
getId() {
var fromStr, toStr;
fromStr = function(from) {
return `${from.process.id}() ${from.port.toUpperCase()}`;
};
toStr = function(to) {
return `${to.port.toUpperCase()} ${to.process.id}()`;
};
if (!(this.from || this.to)) {
return "UNDEFINED";
}
if (this.from && !this.to) {
return `${fromStr(this.from)} -> ANON`;
}
if (!this.from) {
return `DATA -> ${toStr(this.to)}`;
}
return `${fromStr(this.from)} -> ${toStr(this.to)}`;
}
if (event === 'begingroup') {
this.brackets.push(payload);
}
legacyToIp(event, payload) {
if (IP.isIP(payload)) {
// No need to wrap modern IP Objects
return payload;
}
// Wrap legacy events into appropriate IP objects
switch (event) {
case 'begingroup':
return new IP('openBracket', payload);
case 'endgroup':
return new IP('closeBracket');
case 'data':
return new IP('data', payload);
default:
return null;
}
}
if (isIP && ip.type === 'openBracket') {
this.brackets.push(ip.data);
}
ipToLegacy(ip) {
var legacy;
switch (ip.type) {
case 'openBracket':
return legacy = {
event: 'begingroup',
payload: ip.data
};
case 'data':
return legacy = {
event: 'data',
payload: ip.data
};
case 'closeBracket':
return legacy = {
event: 'endgroup',
payload: ip.data
};
}
}
if (event === 'endgroup') {
// Prevent closing already closed groups
if (this.brackets.length === 0) {
return;
} // Add group name to bracket
handleSocketEvent(event, payload, autoConnect = true) {
var ip, isIP, legacy;
isIP = event === 'ip' && IP.isIP(payload);
ip = isIP ? payload : this.legacyToIp(event, payload);
if (!ip) {
return;
}
if (!this.isConnected() && autoConnect && this.brackets.length === 0) {
// Connect before sending
this.connect();
}
if (event === 'begingroup') {
this.brackets.push(payload);
}
if (isIP && ip.type === 'openBracket') {
this.brackets.push(ip.data);
}
if (event === 'endgroup') {
// Prevent closing already closed groups
if (this.brackets.length === 0) {
return;
ip.data = this.brackets.pop();
payload = ip.data;
}
// Add group name to bracket
ip.data = this.brackets.pop();
payload = ip.data;
}
if (isIP && payload.type === 'closeBracket') {
// Prevent closing already closed brackets
if (this.brackets.length === 0) {
if (isIP && payload.type === 'closeBracket') {
// Prevent closing already closed brackets
if (this.brackets.length === 0) {
return;
}
this.brackets.pop();
} // Emit the IP Object
this.emitEvent('ip', ip); // Emit the legacy event
if (!ip || !ip.type) {
return;
}
this.brackets.pop();
if (isIP) {
var legacy = ipToLegacy(ip);
event = legacy.event;
payload = legacy.payload;
}
if (event === 'connect') {
this.connected = true;
}
if (event === 'disconnect') {
this.connected = false;
}
this.emitEvent(event, payload);
}
// Emit the IP Object
this.emitEvent('ip', ip);
// Emit the legacy event
if (!(ip && ip.type)) {
return;
}
if (isIP) {
legacy = this.ipToLegacy(ip);
event = legacy.event;
payload = legacy.payload;
}
if (event === 'connect') {
this.connected = true;
}
if (event === 'disconnect') {
this.connected = false;
}
return this.emitEvent(event, payload);
}
}]);
};
return InternalSocket;
}(EventEmitter);
exports.InternalSocket = InternalSocket;
exports.createSocket = function() {
return new InternalSocket;
};
exports.createSocket = function () {
return new InternalSocket();
};

@@ -0,7 +1,16 @@

"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
// NoFlo - Flow-Based Programming for JavaScript
// (c) 2016-2017 Flowhub UG
// NoFlo may be freely distributed under the MIT license
// ## Information Packets
//
// IP objects are the way information is transmitted between

@@ -12,6 +21,6 @@ // components running in a NoFlo network. IP objects contain

// (`openBracket`, `closeBracket`).
//
// The component currently holding an IP object is identified
// with the `owner` key.
//
// By default, IP objects may be sent to multiple components.

@@ -21,48 +30,71 @@ // If they're set to be clonable, each component will receive

// IP object working with data that is safe to clone.
//
// It is also possible to carry metadata with an IP object.
// For example, the `datatype` and `schema` of the sending
// port is transmitted with the IP object.
var IP;
module.exports = IP = (function() {
class IP {
// Valid IP types:
// - 'data'
// - 'openBracket'
// - 'closeBracket'
module.exports = /*#__PURE__*/function () {
_createClass(IP, null, [{
key: "isIP",
// Detects if an arbitrary value is an IP
static isIP(obj) {
return obj && typeof obj === 'object' && obj._isIP === true;
}
value: function isIP(obj) {
return obj && _typeof(obj) === 'object' && obj.isIP === true;
} // Creates as new IP object
// Valid types: 'data', 'openBracket', 'closeBracket'
// Creates as new IP object
// Valid types: 'data', 'openBracket', 'closeBracket'
constructor(type = 'data', data = null, options = {}) {
var key, val;
this.type = type;
this.data = data;
this._isIP = true;
this.scope = null; // sync scope id
this.owner = null; // packet owner process
this.clonable = false; // cloning safety flag
this.index = null; // addressable port index
this.schema = null;
this.datatype = 'all';
for (key in options) {
val = options[key];
this[key] = val;
}
}]);
function IP(type) {
var _this = this;
var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
_classCallCheck(this, IP);
this.type = type || 'data';
this.data = data;
this.isIP = true;
this.scope = null; // sync scope id
this.owner = null; // packet owner process
this.clonable = false; // cloning safety flag
this.index = null; // addressable port index
this.schema = null;
this.datatype = 'all';
if (_typeof(options) === 'object') {
Object.keys(options).forEach(function (key) {
_this[key] = options[key];
});
}
// Creates a new IP copying its contents by value not reference
clone() {
var ip, key, ref, val;
ip = new IP(this.type);
ref = this;
for (key in ref) {
val = ref[key];
if (['owner'].indexOf(key) !== -1) {
continue;
return this;
} // Creates a new IP copying its contents by value not reference
_createClass(IP, [{
key: "clone",
value: function clone() {
var _this2 = this;
var ip = new IP(this.type);
Object.keys(this).forEach(function (key) {
var val = _this2[key];
if (key === 'owner') {
return;
}
if (val === null) {
continue;
return;
}
if (typeof val === 'object') {
if (_typeof(val) === 'object') {
ip[key] = JSON.parse(JSON.stringify(val));

@@ -72,32 +104,26 @@ } else {

}
}
});
return ip;
}
} // Moves an IP to a different owner
// Moves an IP to a different owner
move(owner) {
}, {
key: "move",
value: function move(owner) {
// no-op
this.owner = owner;
}
return this;
} // Frees IP contents
// no-op
}, {
key: "drop",
value: function drop() {
var _this3 = this;
// Frees IP contents
drop() {
var key, ref, results, val;
ref = this;
results = [];
for (key in ref) {
val = ref[key];
results.push(delete this[key]);
}
return results;
Object.keys(this).forEach(function (key) {
delete _this3[key];
});
}
}]);
};
// Valid IP types
IP.types = ['data', 'openBracket', 'closeBracket'];
return IP;
}).call(this);
}();

@@ -1,16 +0,24 @@

var CoffeeScript, dynamicLoader, fbpGraph, fs, manifest, manifestLoader, path, registerCustomLoaders, registerModules, registerSubgraph, utils;
"use strict";
path = require('path');
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
fs = require('fs');
/* eslint-disable
global-require,
import/no-dynamic-require,
no-underscore-dangle,
prefer-destructuring,
*/
var path = require('path');
manifest = require('fbp-manifest');
var fs = require('fs');
utils = require('../Utils');
var manifest = require('fbp-manifest');
fbpGraph = require('fbp-graph');
var fbpGraph = require('fbp-graph'); // We allow components to be un-compiled CoffeeScript
// We allow components to be un-compiled CoffeeScript
CoffeeScript = require('coffeescript');
var CoffeeScript = require('coffeescript');
var utils = require('../Utils');
if (typeof CoffeeScript.register !== 'undefined') {

@@ -20,85 +28,119 @@ CoffeeScript.register();

registerCustomLoaders = function(loader, componentLoaders, callback) {
var customLoader;
function registerCustomLoaders(loader, componentLoaders, callback) {
if (!componentLoaders.length) {
return callback(null);
callback(null);
return;
}
customLoader = require(componentLoaders.shift());
return loader.registerLoader(customLoader, function(err) {
var customLoader = require(componentLoaders.shift());
loader.registerLoader(customLoader, function (err) {
if (err) {
return callback(err);
callback(err);
return;
}
return registerCustomLoaders(loader, componentLoaders, callback);
registerCustomLoaders(loader, componentLoaders, callback);
});
};
}
registerModules = function(loader, modules, callback) {
var c, compatible, componentLoaders, i, j, len, len1, loaderPath, m, ref, ref1;
compatible = modules.filter(function(m) {
var ref;
return (ref = m.runtime) === 'noflo' || ref === 'noflo-nodejs';
function registerModules(loader, modules, callback) {
var compatible = modules.filter(function (m) {
return ['noflo', 'noflo-nodejs'].includes(m.runtime);
});
componentLoaders = [];
for (i = 0, len = compatible.length; i < len; i++) {
m = compatible[i];
var componentLoaders = [];
compatible.forEach(function (m) {
if (m.icon) {
loader.setLibraryIcon(m.name, m.icon);
}
if ((ref = m.noflo) != null ? ref.loader : void 0) {
loaderPath = path.resolve(loader.baseDir, m.base, m.noflo.loader);
if (m.noflo != null ? m.noflo.loader : undefined) {
var loaderPath = path.resolve(loader.baseDir, m.base, m.noflo.loader);
componentLoaders.push(loaderPath);
}
ref1 = m.components;
for (j = 0, len1 = ref1.length; j < len1; j++) {
c = ref1[j];
m.components.forEach(function (c) {
loader.registerComponent(m.name, c.name, path.resolve(loader.baseDir, c.path));
}
});
});
registerCustomLoaders(loader, componentLoaders, callback);
}
var dynamicLoader = {
listComponents: function listComponents(loader, manifestOptions, callback) {
var opts = manifestOptions;
opts.discover = true;
manifest.list.list(loader.baseDir, opts, function (err, modules) {
if (err) {
callback(err);
return;
}
registerModules(loader, modules, function (err2) {
if (err2) {
callback(err2);
return;
}
callback(null, modules);
});
});
}
return registerCustomLoaders(loader, componentLoaders, callback);
};
manifestLoader = {
writeCache: function(loader, options, manifest, callback) {
var filePath;
filePath = path.resolve(loader.baseDir, options.manifest);
return fs.writeFile(filePath, JSON.stringify(manifest, null, 2), {
var manifestLoader = {
writeCache: function writeCache(loader, options, manifestContents, callback) {
var filePath = path.resolve(loader.baseDir, options.manifest);
fs.writeFile(filePath, JSON.stringify(manifestContents, null, 2), {
encoding: 'utf-8'
}, callback);
},
readCache: function(loader, options, callback) {
options.discover = false;
return manifest.load.load(loader.baseDir, options, callback);
readCache: function readCache(loader, options, callback) {
var opts = options;
opts.discover = false;
manifest.load.load(loader.baseDir, opts, callback);
},
prepareManifestOptions: function(loader) {
var options;
if (!loader.options) {
loader.options = {};
prepareManifestOptions: function prepareManifestOptions(loader) {
var l = loader;
if (!l.options) {
l.options = {};
}
options = {};
options.runtimes = loader.options.runtimes || [];
var options = {};
options.runtimes = l.options.runtimes || [];
if (options.runtimes.indexOf('noflo') === -1) {
options.runtimes.push('noflo');
}
options.recursive = typeof loader.options.recursive === 'undefined' ? true : loader.options.recursive;
options.manifest = loader.options.manifest || 'fbp.json';
options.recursive = typeof l.options.recursive === 'undefined' ? true : l.options.recursive;
options.manifest = l.options.manifest || 'fbp.json';
return options;
},
listComponents: function(loader, manifestOptions, callback) {
return this.readCache(loader, manifestOptions, (err, manifest) => {
listComponents: function listComponents(loader, manifestOptions, callback) {
var _this = this;
this.readCache(loader, manifestOptions, function (err, manifestContents) {
if (err) {
if (!loader.options.discover) {
return callback(err);
callback(err);
return;
}
dynamicLoader.listComponents(loader, manifestOptions, (err, modules) => {
if (err) {
return callback(err);
dynamicLoader.listComponents(loader, manifestOptions, function (err2, modules) {
if (err2) {
callback(err2);
return;
}
return this.writeCache(loader, manifestOptions, {
_this.writeCache(loader, manifestOptions, {
version: 1,
modules: modules
}, function(err) {
if (err) {
return callback(err);
}, function (err3) {
if (err3) {
callback(err3);
return;
}
return callback(null, modules);
callback(null, modules);
});

@@ -108,24 +150,10 @@ });

}
return registerModules(loader, manifest.modules, function(err) {
if (err) {
return callback(err);
registerModules(loader, manifestContents.modules, function (err2) {
if (err2) {
callback(err2);
return;
}
return callback(null, manifest.modules);
});
});
}
};
dynamicLoader = {
listComponents: function(loader, manifestOptions, callback) {
manifestOptions.discover = true;
return manifest.list.list(loader.baseDir, manifestOptions, (err, modules) => {
if (err) {
return callback(err);
}
return registerModules(loader, modules, function(err) {
if (err) {
return callback(err);
}
return callback(null, modules);
callback(null, manifestContents.modules);
});

@@ -136,50 +164,51 @@ });

registerSubgraph = function(loader) {
var graphPath;
function registerSubgraph(loader) {
// Inject subgraph component
if (path.extname(__filename) === '.js') {
graphPath = path.resolve(__dirname, '../../components/Graph.js');
} else {
graphPath = path.resolve(__dirname, '../../components/Graph.coffee');
}
return loader.registerComponent(null, 'Graph', graphPath);
};
var graphPath = path.resolve(__dirname, '../../components/Graph.js');
loader.registerComponent(null, 'Graph', graphPath);
}
exports.register = function(loader, callback) {
var manifestOptions, ref;
manifestOptions = manifestLoader.prepareManifestOptions(loader);
if ((ref = loader.options) != null ? ref.cache : void 0) {
manifestLoader.listComponents(loader, manifestOptions, function(err, modules) {
exports.register = function register(loader, callback) {
var manifestOptions = manifestLoader.prepareManifestOptions(loader);
if (loader.options != null ? loader.options.cache : undefined) {
manifestLoader.listComponents(loader, manifestOptions, function (err, modules) {
if (err) {
return callback(err);
callback(err);
return;
}
registerSubgraph(loader);
return callback(null, modules);
callback(null, modules);
});
return;
}
return dynamicLoader.listComponents(loader, manifestOptions, function(err, modules) {
dynamicLoader.listComponents(loader, manifestOptions, function (err, modules) {
if (err) {
return callback(err);
callback(err);
return;
}
registerSubgraph(loader);
return callback(null, modules);
callback(null, modules);
});
};
exports.dynamicLoad = function(name, cPath, metadata, callback) {
var e, implementation, instance;
exports.dynamicLoad = function dynamicLoad(name, cPath, metadata, callback) {
var implementation;
var instance;
try {
implementation = require(cPath);
} catch (error) {
e = error;
callback(e);
} catch (err) {
callback(err);
return;
}
if (typeof implementation.getComponent === 'function') {
try {
instance = implementation.getComponent(metadata);
} catch (error) {
e = error;
callback(e);
} catch (err) {
callback(err);
return;

@@ -190,65 +219,85 @@ }

instance = implementation(metadata);
} catch (error) {
e = error;
callback(e);
} catch (err) {
callback(err);
return;
}
} else {
callback(new Error(`Unable to instantiate ${cPath}`));
callback(new Error("Unable to instantiate ".concat(cPath)));
return;
}
if (typeof name === 'string') {
instance.componentName = name;
}
return callback(null, instance);
callback(null, instance);
};
exports.setSource = function(loader, packageId, name, source, language, callback) {
var Module, e, implementation, moduleImpl, modulePath;
Module = require('module');
exports.setSource = function setSource(loader, packageId, name, source, language, callback) {
var Module = require('module');
var src = source;
if (language === 'coffeescript') {
try {
source = CoffeeScript.compile(source, {
src = CoffeeScript.compile(src, {
bare: true
});
} catch (error) {
e = error;
return callback(e);
} catch (err) {
callback(err);
return;
}
}
var implementation;
try {
// Use the Node.js module API to evaluate in the correct directory context
modulePath = path.resolve(loader.baseDir, `./components/${name}.js`);
moduleImpl = new Module(modulePath, module);
var modulePath = path.resolve(loader.baseDir, "./components/".concat(name, ".js"));
var moduleImpl = new Module(modulePath, module);
moduleImpl.paths = Module._nodeModulePaths(path.dirname(modulePath));
moduleImpl.filename = modulePath;
moduleImpl._compile(source, modulePath);
moduleImpl._compile(src, modulePath);
implementation = moduleImpl.exports;
} catch (error) {
e = error;
return callback(e);
} catch (err) {
callback(err);
return;
}
if (!(typeof implementation === 'function' || typeof implementation.getComponent === 'function')) {
return callback(new Error('Provided source failed to create a runnable component'));
if (typeof implementation !== 'function' && typeof implementation.getComponent !== 'function') {
callback(new Error('Provided source failed to create a runnable component'));
return;
}
return loader.registerComponent(packageId, name, implementation, callback);
loader.registerComponent(packageId, name, implementation, callback);
};
exports.getSource = function(loader, name, callback) {
var component, componentName, nameParts;
component = loader.components[name];
exports.getSource = function getSource(loader, name, callback) {
var componentName = name;
var component = loader.components[name];
if (!component) {
// Try an alias
for (componentName in loader.components) {
if (componentName.split('/')[1] === name) {
component = loader.components[componentName];
name = componentName;
// Try an alias
var keys = Object.keys(loader.components);
for (var i = 0; i < keys.length; i += 1) {
var key = keys[i];
if (key.split('/')[1] === name) {
component = loader.components[key];
componentName = key;
break;
}
}
if (!component) {
return callback(new Error(`Component ${name} not installed`));
callback(new Error("Component ".concat(componentName, " not installed")));
return;
}
}
nameParts = name.split('/');
var nameParts = componentName.split('/');
if (nameParts.length === 1) {

@@ -258,4 +307,5 @@ nameParts[1] = nameParts[0];

}
if (loader.isGraph(component)) {
if (typeof component === 'object') {
if (_typeof(component) === 'object') {
if (typeof component.toJSON === 'function') {

@@ -270,12 +320,19 @@ callback(null, {

}
return callback(new Error(`Can't provide source for ${name}. Not a file`));
callback(new Error("Can't provide source for ".concat(componentName, ". Not a file")));
return;
}
fbpGraph.graph.loadFile(component, function(err, graph) {
fbpGraph.graph.loadFile(component, function (err, graph) {
if (err) {
return callback(err);
callback(err);
return;
}
if (!graph) {
return callback(new Error('Unable to load graph'));
callback(new Error('Unable to load graph'));
return;
}
return callback(null, {
callback(null, {
name: nameParts[1],

@@ -289,10 +346,15 @@ library: nameParts[0],

}
if (typeof component !== 'string') {
return callback(new Error(`Can't provide source for ${name}. Not a file`));
callback(new Error("Can't provide source for ".concat(componentName, ". Not a file")));
return;
}
return fs.readFile(component, 'utf-8', function(err, code) {
fs.readFile(component, 'utf-8', function (err, code) {
if (err) {
return callback(err);
callback(err);
return;
}
return callback(null, {
callback(null, {
name: nameParts[1],

@@ -304,2 +366,2 @@ library: nameParts[0],

});
};
};

@@ -1,4 +0,8 @@

var isBrowser;
"use strict";
({isBrowser} = require('../Platform'));
/* eslint-disable
global-require,
*/
var _require = require('../Platform'),
isBrowser = _require.isBrowser;

@@ -9,2 +13,2 @@ if (isBrowser()) {

module.exports = require('./NodeJs');
}
}

@@ -1,1025 +0,216 @@

// NoFlo - Flow-Based Programming for JavaScript
// (c) 2013-2017 Flowhub UG
// (c) 2011-2012 Henri Bergius, Nemein
// NoFlo may be freely distributed under the MIT license
var EventEmitter, IP, Network, componentLoader, graph, internalSocket, platform, utils;
"use strict";
internalSocket = require("./InternalSocket");
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
graph = require("fbp-graph");
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
({EventEmitter} = require('events'));
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
platform = require('./Platform');
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
componentLoader = require('./ComponentLoader');
function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); }
utils = require('./Utils');
function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
IP = require('./IP');
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
Network = (function() {
// ## The NoFlo network coordinator
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
// NoFlo networks consist of processes connected to each other
// via sockets attached from outports to inports.
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
// The role of the network coordinator is to take a graph and
// instantiate all the necessary processes from the designated
// components, attach sockets between them, and handle the sending
// of Initial Information Packets.
class Network extends EventEmitter {
// All NoFlo networks are instantiated with a graph. Upon instantiation
// they will load all the needed components, instantiate them, and
// set up the defined connections and IIPs.
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
// The network will also listen to graph changes and modify itself
// accordingly, including removing connections, adding new nodes,
// and sending new IIPs.
constructor(graph, options = {}) {
super();
this.options = options;
this.processes = {};
this.connections = [];
this.initials = [];
this.nextInitials = [];
this.defaults = [];
this.graph = graph;
this.started = false;
this.stopped = true;
this.debug = true;
this.eventBuffer = [];
// On Node.js we default the baseDir for component loading to
// the current working directory
if (!platform.isBrowser()) {
this.baseDir = graph.baseDir || process.cwd();
} else {
// On browser we default the baseDir to the Component loading
// root
this.baseDir = graph.baseDir || '/';
}
// As most NoFlo networks are long-running processes, the
// network coordinator marks down the start-up time. This
// way we can calculate the uptime of the network.
this.startupDate = null;
// Initialize a Component Loader for the network
if (graph.componentLoader) {
this.loader = graph.componentLoader;
} else {
this.loader = new componentLoader.ComponentLoader(this.baseDir, this.options);
}
}
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
// The uptime of the network is the current time minus the start-up
// time, in seconds.
uptime() {
if (!this.startupDate) {
return 0;
}
return new Date() - this.startupDate;
}
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
getActiveProcesses() {
var active, name, process, ref;
active = [];
if (!this.started) {
return active;
}
ref = this.processes;
for (name in ref) {
process = ref[name];
if (process.component.load > 0) {
// Modern component with load
active.push(name);
}
if (process.component.__openConnections > 0) {
// Legacy component
active.push(name);
}
}
return active;
}
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
bufferedEmit(event, payload) {
var ev, i, len, ref;
// Errors get emitted immediately, like does network end
if (event === 'icon' || event === 'error' || event === 'process-error' || event === 'end') {
this.emit(event, payload);
return;
}
if (!this.isStarted() && event !== 'end') {
this.eventBuffer.push({
type: event,
payload: payload
});
return;
}
this.emit(event, payload);
if (event === 'start') {
ref = this.eventBuffer;
// Once network has started we can send the IP-related events
for (i = 0, len = ref.length; i < len; i++) {
ev = ref[i];
this.emit(ev.type, ev.payload);
}
this.eventBuffer = [];
}
if (event === 'ip') {
// Emit also the legacy events from IP
switch (payload.type) {
case 'openBracket':
this.bufferedEmit('begingroup', payload);
break;
case 'closeBracket':
this.bufferedEmit('endgroup', payload);
break;
case 'data':
this.bufferedEmit('data', payload);
}
}
}
// NoFlo - Flow-Based Programming for JavaScript
// (c) 2013-2018 Flowhub UG
// (c) 2011-2012 Henri Bergius, Nemein
// NoFlo may be freely distributed under the MIT license
var BaseNetwork = require('./BaseNetwork');
/* eslint-disable
no-param-reassign,
*/
// ## The NoFlo network coordinator
//
// NoFlo networks consist of processes connected to each other
// via sockets attached from outports to inports.
//
// The role of the network coordinator is to take a graph and
// instantiate all the necessary processes from the designated
// components, attach sockets between them, and handle the sending
// of Initial Information Packets.
// ## Loading components
// Components can be passed to the NoFlo network in two ways:
var Network = /*#__PURE__*/function (_BaseNetwork) {
_inherits(Network, _BaseNetwork);
// * As direct, instantiated JavaScript objects
// * As filenames
load(component, metadata, callback) {
return this.loader.load(component, callback, metadata);
}
var _super = _createSuper(Network);
// ## Add a process to the network
// All NoFlo networks are instantiated with a graph. Upon instantiation
// they will load all the needed components, instantiate them, and
// set up the defined connections and IIPs.
function Network(graph) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
// Processes can be added to a network at either start-up time
// or later. The processes are added with a node definition object
// that includes the following properties:
_classCallCheck(this, Network);
// * `id`: Identifier of the process in the network. Typically a string
// * `component`: Filename or path of a NoFlo component, or a component instance object
addNode(node, callback) {
var process;
// Processes are treated as singletons by their identifier. If
// we already have a process with the given ID, return that.
if (this.processes[node.id]) {
callback(null, this.processes[node.id]);
return;
return _super.call(this, graph, options);
} // Add a process to the network. The node will also be registered
// with the current graph.
_createClass(Network, [{
key: "addNode",
value: function addNode(node, options, callback) {
var _this = this;
if (typeof options === 'function') {
callback = options;
options = {};
}
process = {
id: node.id
};
// No component defined, just register the process but don't start.
if (!node.component) {
this.processes[process.id] = process;
callback(null, process);
return;
}
// Load the component for the process.
return this.load(node.component, node.metadata, (err, instance) => {
var inPorts, name, outPorts, port;
if (err) {
return callback(err);
}
instance.nodeId = node.id;
process.component = instance;
process.componentName = node.component;
// Inform the ports of the node name
inPorts = process.component.inPorts.ports;
outPorts = process.component.outPorts.ports;
for (name in inPorts) {
port = inPorts[name];
port.node = node.id;
port.nodeInstance = instance;
port.name = name;
}
for (name in outPorts) {
port = outPorts[name];
port.node = node.id;
port.nodeInstance = instance;
port.name = name;
}
if (instance.isSubgraph()) {
this.subscribeSubgraph(process);
}
this.subscribeNode(process);
// Store and return the process instance
this.processes[process.id] = process;
return callback(null, process);
});
}
removeNode(node, callback) {
var process;
process = this.getNode(node.id);
if (!process) {
return callback(new Error(`Node ${node.id} not found`));
}
return process.component.shutdown((err) => {
_get(_getPrototypeOf(Network.prototype), "addNode", this).call(this, node, options, function (err, process) {
if (err) {
return callback(err);
callback(err);
return;
}
delete this.processes[node.id];
return callback(null);
});
}
renameNode(oldId, newId, callback) {
var inPorts, name, outPorts, port, process;
process = this.getNode(oldId);
if (!process) {
return callback(new Error(`Process ${oldId} not found`));
}
// Inform the process of its ID
process.id = newId;
// Inform the ports of the node name
inPorts = process.component.inPorts.ports;
outPorts = process.component.outPorts.ports;
for (name in inPorts) {
port = inPorts[name];
if (!port) {
continue;
if (!options.initial) {
_this.graph.addNode(node.id, node.component, node.metadata);
}
port.node = newId;
}
for (name in outPorts) {
port = outPorts[name];
if (!port) {
continue;
}
port.node = newId;
}
this.processes[newId] = process;
delete this.processes[oldId];
return callback(null);
}
// Get process by its ID.
getNode(id) {
return this.processes[id];
}
connect(done = function() {}) {
var callStack, edges, initializers, nodes, serialize, setDefaults, subscribeGraph;
// Wrap the future which will be called when done in a function and return
// it
callStack = 0;
serialize = (next, add) => {
return (type) => {
// Add either a Node, an Initial, or an Edge and move on to the next one
// when done
return this[`add${type}`](add, function(err) {
if (err) {
return done(err);
}
callStack++;
if (callStack % 100 === 0) {
setTimeout(function() {
return next(type);
}, 0);
return;
}
return next(type);
});
};
};
// Subscribe to graph changes when everything else is done
subscribeGraph = () => {
this.subscribeGraph();
return done();
};
// Serialize default socket creation then call callback when done
setDefaults = utils.reduceRight(this.graph.nodes, serialize, subscribeGraph);
// Serialize initializers then call defaults.
initializers = utils.reduceRight(this.graph.initializers, serialize, function() {
return setDefaults("Defaults");
callback(null, process);
});
// Serialize edge creators then call the initializers.
edges = utils.reduceRight(this.graph.edges, serialize, function() {
return initializers("Initial");
});
// Serialize node creators then call the edge creators
nodes = utils.reduceRight(this.graph.nodes, serialize, function() {
return edges("Edge");
});
// Start with node creators
return nodes("Node");
}
} // Remove a process from the network. The node will also be removed
// from the current graph.
connectPort(socket, process, port, index, inbound, callback) {
if (inbound) {
socket.to = {
process: process,
port: port,
index: index
};
if (!(process.component.inPorts && process.component.inPorts[port])) {
callback(new Error(`No inport '${port}' defined in process ${process.id} (${socket.getId()})`));
}, {
key: "removeNode",
value: function removeNode(node, callback) {
var _this2 = this;
_get(_getPrototypeOf(Network.prototype), "removeNode", this).call(this, node, function (err) {
if (err) {
callback(err);
return;
}
if (process.component.inPorts[port].isAddressable()) {
process.component.inPorts[port].attach(socket, index);
callback();
return;
}
process.component.inPorts[port].attach(socket);
_this2.graph.removeNode(node.id);
callback();
return;
}
socket.from = {
process: process,
port: port,
index: index
};
if (!(process.component.outPorts && process.component.outPorts[port])) {
callback(new Error(`No outport '${port}' defined in process ${process.id} (${socket.getId()})`));
return;
}
if (process.component.outPorts[port].isAddressable()) {
process.component.outPorts[port].attach(socket, index);
callback();
return;
}
process.component.outPorts[port].attach(socket);
callback();
}
});
} // Rename a process in the network. Renaming a process also modifies
// the current graph.
subscribeGraph() {
var graphOps, processOps, processing, registerOp;
// A NoFlo graph may change after network initialization.
// For this, the network subscribes to the change events from
// the graph.
}, {
key: "renameNode",
value: function renameNode(oldId, newId, callback) {
var _this3 = this;
// In graph we talk about nodes and edges. Nodes correspond
// to NoFlo processes, and edges to connections between them.
graphOps = [];
processing = false;
registerOp = function(op, details) {
return graphOps.push({
op: op,
details: details
});
};
processOps = (err) => {
var cb, op;
_get(_getPrototypeOf(Network.prototype), "renameNode", this).call(this, oldId, newId, function (err) {
if (err) {
if (this.listeners('process-error').length === 0) {
throw err;
}
this.bufferedEmit('process-error', err);
}
if (!graphOps.length) {
processing = false;
callback(err);
return;
}
processing = true;
op = graphOps.shift();
cb = processOps;
switch (op.op) {
case 'renameNode':
return this.renameNode(op.details.from, op.details.to, cb);
default:
return this[op.op](op.details, cb);
}
};
this.graph.on('addNode', function(node) {
registerOp('addNode', node);
if (!processing) {
return processOps();
}
});
this.graph.on('removeNode', function(node) {
registerOp('removeNode', node);
if (!processing) {
return processOps();
}
});
this.graph.on('renameNode', function(oldId, newId) {
registerOp('renameNode', {
from: oldId,
to: newId
});
if (!processing) {
return processOps();
}
});
this.graph.on('addEdge', function(edge) {
registerOp('addEdge', edge);
if (!processing) {
return processOps();
}
});
this.graph.on('removeEdge', function(edge) {
registerOp('removeEdge', edge);
if (!processing) {
return processOps();
}
});
this.graph.on('addInitial', function(iip) {
registerOp('addInitial', iip);
if (!processing) {
return processOps();
}
});
return this.graph.on('removeInitial', function(iip) {
registerOp('removeInitial', iip);
if (!processing) {
return processOps();
}
});
}
subscribeSubgraph(node) {
var emitSub;
if (!node.component.isReady()) {
node.component.once('ready', () => {
return this.subscribeSubgraph(node);
});
return;
}
if (!node.component.network) {
return;
}
node.component.network.setDebug(this.debug);
emitSub = (type, data) => {
if (type === 'process-error' && this.listeners('process-error').length === 0) {
if (data.id && data.metadata && data.error) {
throw data.error;
}
throw data;
}
if (!data) {
data = {};
}
if (data.subgraph) {
if (!data.subgraph.unshift) {
data.subgraph = [data.subgraph];
}
data.subgraph.unshift(node.id);
} else {
data.subgraph = [node.id];
}
return this.bufferedEmit(type, data);
};
node.component.network.on('ip', function(data) {
return emitSub('ip', data);
});
return node.component.network.on('process-error', function(data) {
return emitSub('process-error', data);
});
}
_this3.graph.renameNode(oldId, newId);
// Subscribe to events from all connected sockets and re-emit them
subscribeSocket(socket, source) {
var ref;
socket.on('ip', (ip) => {
return this.bufferedEmit('ip', {
id: socket.getId(),
type: ip.type,
socket: socket,
data: ip.data,
metadata: socket.metadata
});
callback();
});
socket.on('error', (event) => {
if (this.listeners('process-error').length === 0) {
if (event.id && event.metadata && event.error) {
throw event.error;
}
throw event;
}
return this.bufferedEmit('process-error', event);
});
if (!(source != null ? (ref = source.component) != null ? ref.isLegacy() : void 0 : void 0)) {
return;
}
// Handle activation for legacy components via connects/disconnects
socket.on('connect', function() {
if (!source.component.__openConnections) {
source.component.__openConnections = 0;
}
return source.component.__openConnections++;
});
return socket.on('disconnect', () => {
source.component.__openConnections--;
if (source.component.__openConnections < 0) {
source.component.__openConnections = 0;
}
if (source.component.__openConnections === 0) {
return this.checkIfFinished();
}
});
}
} // Add a connection to the network. The edge will also be registered
// with the current graph.
subscribeNode(node) {
node.component.on('activate', (load) => {
if (this.debouncedEnd) {
return this.abortDebounce = true;
}
});
node.component.on('deactivate', (load) => {
if (load > 0) {
return;
}
return this.checkIfFinished();
});
if (!node.component.getIcon) {
return;
}, {
key: "addEdge",
value: function addEdge(edge, options, callback) {
var _this4 = this;
if (typeof options === 'function') {
callback = options;
options = {};
}
return node.component.on('icon', () => {
return this.bufferedEmit('icon', {
id: node.id,
icon: node.component.getIcon()
});
});
}
addEdge(edge, callback) {
var from, socket, to;
socket = internalSocket.createSocket(edge.metadata);
socket.setDebug(this.debug);
from = this.getNode(edge.from.node);
if (!from) {
return callback(new Error(`No process defined for outbound node ${edge.from.node}`));
}
if (!from.component) {
return callback(new Error(`No component defined for outbound node ${edge.from.node}`));
}
if (!from.component.isReady()) {
from.component.once("ready", () => {
return this.addEdge(edge, callback);
});
return;
}
to = this.getNode(edge.to.node);
if (!to) {
return callback(new Error(`No process defined for inbound node ${edge.to.node}`));
}
if (!to.component) {
return callback(new Error(`No component defined for inbound node ${edge.to.node}`));
}
if (!to.component.isReady()) {
to.component.once("ready", () => {
return this.addEdge(edge, callback);
});
return;
}
// Subscribe to events from the socket
this.subscribeSocket(socket, from);
return this.connectPort(socket, to, edge.to.port, edge.to.index, true, (err) => {
_get(_getPrototypeOf(Network.prototype), "addEdge", this).call(this, edge, options, function (err) {
if (err) {
return callback(err);
callback(err);
return;
}
return this.connectPort(socket, from, edge.from.port, edge.from.index, false, (err) => {
if (err) {
return callback(err);
}
this.connections.push(socket);
return callback();
});
});
}
removeEdge(edge, callback) {
var connection, i, len, ref, results;
ref = this.connections;
results = [];
for (i = 0, len = ref.length; i < len; i++) {
connection = ref[i];
if (!connection) {
continue;
if (!options.initial) {
_this4.graph.addEdgeIndex(edge.from.node, edge.from.port, edge.from.index, edge.to.node, edge.to.port, edge.to.index, edge.metadata);
}
if (!(edge.to.node === connection.to.process.id && edge.to.port === connection.to.port)) {
continue;
}
connection.to.process.component.inPorts[connection.to.port].detach(connection);
if (edge.from.node) {
if (connection.from && edge.from.node === connection.from.process.id && edge.from.port === connection.from.port) {
connection.from.process.component.outPorts[connection.from.port].detach(connection);
}
}
this.connections.splice(this.connections.indexOf(connection), 1);
results.push(callback());
}
return results;
}
addDefaults(node, callback) {
var key, port, process, ref, socket;
process = this.getNode(node.id);
if (!process) {
return callback(new Error(`Process ${node.id} not defined`));
}
if (!process.component) {
return callback(new Error(`No component defined for node ${node.id}`));
}
if (!process.component.isReady()) {
process.component.setMaxListeners(0);
process.component.once("ready", () => {
return this.addDefaults(process, callback);
});
return;
}
ref = process.component.inPorts.ports;
for (key in ref) {
port = ref[key];
// Attach a socket to any defaulted inPorts as long as they aren't already attached.
if (port.hasDefault() && !port.isAttached()) {
socket = internalSocket.createSocket();
socket.setDebug(this.debug);
// Subscribe to events from the socket
this.subscribeSocket(socket);
this.connectPort(socket, process, key, void 0, true, function() {});
this.connections.push(socket);
this.defaults.push(socket);
}
}
return callback();
}
addInitial(initializer, callback) {
var socket, to;
socket = internalSocket.createSocket(initializer.metadata);
socket.setDebug(this.debug);
// Subscribe to events from the socket
this.subscribeSocket(socket);
to = this.getNode(initializer.to.node);
if (!to) {
return callback(new Error(`No process defined for inbound node ${initializer.to.node}`));
}
if (!to.component) {
return callback(new Error(`No component defined for inbound node ${initializer.to.node}`));
}
if (!(to.component.isReady() || to.component.inPorts[initializer.to.port])) {
to.component.setMaxListeners(0);
to.component.once("ready", () => {
return this.addInitial(initializer, callback);
});
return;
}
return this.connectPort(socket, to, initializer.to.port, initializer.to.index, true, (err) => {
var init;
if (err) {
return callback(err);
}
this.connections.push(socket);
init = {
socket: socket,
data: initializer.from.data
};
this.initials.push(init);
this.nextInitials.push(init);
if (this.isRunning()) {
// Network is running now, send initials immediately
this.sendInitials();
} else if (!this.isStopped()) {
// Network has finished but hasn't been stopped, set
// started and set
this.setStarted(true);
this.sendInitials();
}
return callback();
callback();
});
}
} // Remove a connection from the network. The edge will also be removed
// from the current graph.
removeInitial(initializer, callback) {
var connection, i, init, j, k, len, len1, len2, ref, ref1, ref2;
ref = this.connections;
for (i = 0, len = ref.length; i < len; i++) {
connection = ref[i];
if (!connection) {
continue;
}
if (!(initializer.to.node === connection.to.process.id && initializer.to.port === connection.to.port)) {
continue;
}
connection.to.process.component.inPorts[connection.to.port].detach(connection);
this.connections.splice(this.connections.indexOf(connection), 1);
ref1 = this.initials;
for (j = 0, len1 = ref1.length; j < len1; j++) {
init = ref1[j];
if (!init) {
continue;
}
if (init.socket !== connection) {
continue;
}
this.initials.splice(this.initials.indexOf(init), 1);
}
ref2 = this.nextInitials;
for (k = 0, len2 = ref2.length; k < len2; k++) {
init = ref2[k];
if (!init) {
continue;
}
if (init.socket !== connection) {
continue;
}
this.nextInitials.splice(this.nextInitials.indexOf(init), 1);
}
}
return callback();
}
}, {
key: "removeEdge",
value: function removeEdge(edge, callback) {
var _this5 = this;
sendInitial(initial) {
return initial.socket.post(new IP('data', initial.data, {
initial: true
}));
}
sendInitials(callback) {
var send;
if (!callback) {
callback = function() {};
}
send = () => {
var i, initial, len, ref;
ref = this.initials;
for (i = 0, len = ref.length; i < len; i++) {
initial = ref[i];
this.sendInitial(initial);
_get(_getPrototypeOf(Network.prototype), "removeEdge", this).call(this, edge, function (err) {
if (err) {
callback(err);
return;
}
this.initials = [];
return callback();
};
if (typeof process !== 'undefined' && process.execPath && process.execPath.indexOf('node') !== -1) {
// nextTick is faster on Node.js
return process.nextTick(send);
} else {
return setTimeout(send, 0);
}
}
isStarted() {
return this.started;
}
_this5.graph.removeEdge(edge.from.node, edge.from.port, edge.to.node, edge.to.port);
isStopped() {
return this.stopped;
}
callback();
});
} // Add an IIP to the network. The IIP will also be registered with the
// current graph. If the network is running, the IIP will be sent immediately.
isRunning() {
return this.getActiveProcesses().length > 0;
}
}, {
key: "addInitial",
value: function addInitial(iip, options, callback) {
var _this6 = this;
startComponents(callback) {
var count, id, length, onProcessStart, process, ref, results;
if (!callback) {
callback = function() {};
if (typeof options === 'function') {
callback = options;
options = {};
}
// Emit start event when all processes are started
count = 0;
length = this.processes ? Object.keys(this.processes).length : 0;
onProcessStart = function(err) {
_get(_getPrototypeOf(Network.prototype), "addInitial", this).call(this, iip, options, function (err) {
if (err) {
return callback(err);
callback(err);
return;
}
count++;
if (count === length) {
return callback();
}
};
if (!(this.processes && Object.keys(this.processes).length)) {
// Perform any startup routines necessary for every component.
return callback();
}
ref = this.processes;
results = [];
for (id in ref) {
process = ref[id];
if (process.component.isStarted()) {
onProcessStart();
continue;
}
if (process.component.start.length === 0) {
platform.deprecated('component.start method without callback is deprecated');
process.component.start();
onProcessStart();
continue;
}
results.push(process.component.start(onProcessStart));
}
return results;
}
sendDefaults(callback) {
var i, len, ref, socket;
if (!callback) {
callback = function() {};
}
if (!this.defaults.length) {
return callback();
}
ref = this.defaults;
for (i = 0, len = ref.length; i < len; i++) {
socket = ref[i];
if (socket.to.process.component.inPorts[socket.to.port].sockets.length !== 1) {
// Don't send defaults if more than one socket is present on the port.
// This case should only happen when a subgraph is created as a component
// as its network is instantiated and its inputs are serialized before
// a socket is attached from the "parent" graph.
continue;
if (!options.initial) {
_this6.graph.addInitialIndex(iip.from.data, iip.to.node, iip.to.port, iip.to.index, iip.metadata);
}
socket.connect();
socket.send();
socket.disconnect();
}
return callback();
}
start(callback) {
if (!callback) {
platform.deprecated('Calling network.start() without callback is deprecated');
callback = function() {};
}
if (this.debouncedEnd) {
this.abortDebounce = true;
}
if (this.started) {
this.stop((err) => {
if (err) {
return callback(err);
}
return this.start(callback);
});
return;
}
this.initials = this.nextInitials.slice(0);
this.eventBuffer = [];
this.startComponents((err) => {
if (err) {
return callback(err);
}
this.sendInitials((err) => {
if (err) {
return callback(err);
}
this.sendDefaults((err) => {
if (err) {
return callback(err);
}
this.setStarted(true);
callback(null);
});
});
callback();
});
}
} // Remove an IIP from the network. The IIP will also be removed from the
// current graph.
stop(callback) {
var connection, count, i, id, len, length, onProcessEnd, process, ref, ref1, results;
if (!callback) {
platform.deprecated('Calling network.stop() without callback is deprecated');
callback = function() {};
}
if (this.debouncedEnd) {
this.abortDebounce = true;
}
if (!this.started) {
this.stopped = true;
return callback(null);
}
ref = this.connections;
// Disconnect all connections
for (i = 0, len = ref.length; i < len; i++) {
connection = ref[i];
if (!connection.isConnected()) {
continue;
}
connection.disconnect();
}
// Emit stop event when all processes are stopped
count = 0;
length = this.processes ? Object.keys(this.processes).length : 0;
onProcessEnd = (err) => {
}, {
key: "removeInitial",
value: function removeInitial(iip, callback) {
var _this7 = this;
_get(_getPrototypeOf(Network.prototype), "removeInitial", this).call(this, iip, function (err) {
if (err) {
return callback(err);
callback(err);
return;
}
count++;
if (count === length) {
this.setStarted(false);
this.stopped = true;
return callback();
}
};
if (!(this.processes && Object.keys(this.processes).length)) {
this.setStarted(false);
this.stopped = true;
return callback();
}
ref1 = this.processes;
// Tell processes to shut down
results = [];
for (id in ref1) {
process = ref1[id];
if (!process.component.isStarted()) {
onProcessEnd();
continue;
}
if (process.component.shutdown.length === 0) {
platform.deprecated('component.shutdown method without callback is deprecated');
process.component.shutdown();
onProcessEnd();
continue;
}
results.push(process.component.shutdown(onProcessEnd));
}
return results;
}
setStarted(started) {
if (this.started === started) {
return;
}
if (!started) {
// Ending the execution
this.started = false;
this.bufferedEmit('end', {
start: this.startupDate,
end: new Date,
uptime: this.uptime()
});
return;
}
if (!this.startupDate) {
// Starting the execution
this.startupDate = new Date;
}
this.started = true;
this.stopped = false;
return this.bufferedEmit('start', {
start: this.startupDate
_this7.graph.removeInitial(iip.to.node, iip.to.port);
callback();
});
}
}]);
checkIfFinished() {
if (this.isRunning()) {
return;
}
delete this.abortDebounce;
if (!this.debouncedEnd) {
this.debouncedEnd = utils.debounce(() => {
if (this.abortDebounce) {
return;
}
if (this.isRunning()) {
return;
}
return this.setStarted(false);
}, 50);
}
return this.debouncedEnd();
}
getDebug() {
return this.debug;
}
setDebug(active) {
var i, instance, len, process, processId, ref, ref1, results, socket;
if (active === this.debug) {
return;
}
this.debug = active;
ref = this.connections;
for (i = 0, len = ref.length; i < len; i++) {
socket = ref[i];
socket.setDebug(active);
}
ref1 = this.processes;
results = [];
for (processId in ref1) {
process = ref1[processId];
instance = process.component;
if (instance.isSubgraph()) {
results.push(instance.network.setDebug(active));
} else {
results.push(void 0);
}
}
return results;
}
};
// Processes contains all the instantiated components for this network
Network.prototype.processes = {};
// Connections contains all the socket connections in the network
Network.prototype.connections = [];
// Initials contains all Initial Information Packets (IIPs)
Network.prototype.initials = [];
// Container to hold sockets that will be sending default data.
Network.prototype.defaults = [];
// The Graph this network is instantiated with
Network.prototype.graph = null;
// Start-up timestamp for the network, used for calculating uptime
Network.prototype.startupDate = null;
return Network;
}(BaseNetwork);
}).call(this);
exports.Network = Network;
exports.Network = Network;

@@ -0,1 +1,5 @@

"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
// NoFlo - Flow-Based Programming for JavaScript

@@ -5,41 +9,43 @@ // (c) 2013-2018 Flowhub UG

// NoFlo may be freely distributed under the MIT license
//
// NoFlo is a Flow-Based Programming environment for JavaScript. This file provides the
// main entry point to the NoFlo network.
//
// Find out more about using NoFlo from <http://noflojs.org/documentation/>
/* eslint-disable
no-param-reassign,
*/
// ## Main APIs
//
// ### Graph interface
//
// [fbp-graph](https://github.com/flowbased/fbp-graph) is used for instantiating FBP graph definitions.
var fbpGraph, ports;
var fbpGraph = require('fbp-graph');
fbpGraph = require('fbp-graph');
exports.graph = fbpGraph.graph;
exports.Graph = fbpGraph.Graph; // ### Graph journal
//
// Journal is used for keeping track of graph changes
exports.Graph = fbpGraph.Graph;
// ### Graph journal
// Journal is used for keeping track of graph changes
exports.journal = fbpGraph.journal;
exports.Journal = fbpGraph.Journal; // ## Network interface
//
// [Network](../Network/) is used for running NoFlo graphs. The direct Network inteface is only
// provided for backwards compatibility purposes. Use `createNetwork` instead.
exports.Journal = fbpGraph.Journal;
var _require = require('./Network'),
Network = _require.Network;
// ## Network interface
exports.Network = require('./LegacyNetwork').Network;
// [Network](../Network/) is used for running NoFlo graphs.
exports.Network = require('./Network').Network;
// ### Platform detection
var _require2 = require('./Platform'),
deprecated = _require2.deprecated; // ### Platform detection
//
// NoFlo works on both Node.js and the browser. Because some dependencies are different,
// we need a way to detect which we're on.
exports.isBrowser = require('./Platform').isBrowser;
// ### Component Loader
exports.isBrowser = require('./Platform').isBrowser; // ### Component Loader
//
// The [ComponentLoader](../ComponentLoader/) is responsible for finding and loading

@@ -49,51 +55,38 @@ // NoFlo components. Component Loader uses [fbp-manifest](https://github.com/flowbased/fbp-manifest)

// directory on the file system.
exports.ComponentLoader = require('./ComponentLoader').ComponentLoader;
// ### Component baseclasses
exports.ComponentLoader = require('./ComponentLoader').ComponentLoader; // ### Component baseclasses
//
// These baseclasses can be used for defining NoFlo components.
exports.Component = require('./Component').Component;
// ### Component helpers
exports.Component = require('./Component').Component; // ### NoFlo ports
//
// These classes are used for instantiating ports on NoFlo components.
// These helpers aid in providing specific behavior in components with minimal overhead.
exports.helpers = require('./Helpers');
var ports = require('./Ports');
// ### NoFlo ports
// These classes are used for instantiating ports on NoFlo components.
ports = require('./Ports');
exports.InPorts = ports.InPorts;
exports.OutPorts = ports.OutPorts;
exports.InPort = require('./InPort');
exports.OutPort = require('./OutPort');
// ### NoFlo sockets
exports.OutPort = require('./OutPort'); // ### NoFlo sockets
//
// The NoFlo [internalSocket](InternalSocket.html) is used for connecting ports of
// different components together in a network.
exports.internalSocket = require('./InternalSocket');
// ### Information Packets
exports.internalSocket = require('./InternalSocket'); // ### Information Packets
//
// NoFlo Information Packets are defined as "IP" objects.
exports.IP = require('./IP');
// ## Network instantiation
exports.IP = require('./IP'); // ## Network instantiation
//
// This function handles instantiation of NoFlo networks from a Graph object. It creates
// the network, and then starts execution by sending the Initial Information Packets.
//
// noflo.createNetwork(someGraph, function (err, network) {
// console.log('Network is now running!');
// });
//
// It is also possible to instantiate a Network but delay its execution by giving the
// third `delay` parameter. In this case you will have to handle connecting the graph and
// sending of IIPs manually.
//
// noflo.createNetwork(someGraph, function (err, network) {

@@ -108,5 +101,27 @@ // if (err) {

// }, true);
exports.createNetwork = function(graph, callback, options) {
var network, networkReady;
if (typeof options !== 'object') {
//
// ### Network options
//
// It is possible to pass some options to control the behavior of network creation:
//
// * `delay`: (default: FALSE) Whether the network should be started later. Defaults to
// immediate execution
// * `subscribeGraph`: (default: TRUE) Whether the network should monitor the underlying
// graph for changes
//
// Options can be passed as a second argument before the callback:
//
// noflo.createNetwork(someGraph, options, callback);
//
// The options object can also be used for setting ComponentLoader options in this
// network.
exports.createNetwork = function createNetwork(graph, options, callback) {
if (typeof options === 'function') {
var opts = callback;
callback = options;
options = opts;
}
if (typeof options === 'boolean') {
options = {

@@ -116,4 +131,16 @@ delay: options

}
if (_typeof(options) !== 'object') {
options = {};
}
if (typeof options.subscribeGraph === 'undefined') {
// Default to legacy network for backwards compatibility.
options.subscribeGraph = true;
}
if (typeof callback !== 'function') {
callback = function(err) {
deprecated('Calling noflo.createNetwork without a callback is deprecated');
callback = function callback(err) {
if (err) {

@@ -123,43 +150,56 @@ throw err;

};
}
network = new exports.Network(graph, options);
networkReady = function(network) {
} // Choose legacy or modern network based on whether graph
// subscription is needed
var NetworkType = options.subscribeGraph ? exports.Network : Network;
var network = new NetworkType(graph, options);
var networkReady = function networkReady(net) {
// Send IIPs
return network.start(function(err) {
net.start(function (err) {
if (err) {
return callback(err);
callback(err);
return;
}
return callback(null, network);
callback(null, net);
});
};
// Ensure components are loaded before continuing
network.loader.listComponents(function(err) {
}; // Ensure components are loaded before continuing
network.loader.listComponents(function (err) {
if (err) {
return callback(err);
}
if (graph.nodes.length === 0) {
// Empty network, no need to connect it up
return networkReady(network);
}
// In case of delayed execution we don't wire it up
callback(err);
return;
} // In case of delayed execution we don't wire it up
if (options.delay) {
callback(null, network);
return;
}
// Wire the network up and start execution
return network.connect(function(err) {
if (err) {
return callback(err);
} // Empty network, no need to connect it up
if (graph.nodes.length === 0) {
networkReady(network);
return;
} // Wire the network up and start execution
network.connect(function (err2) {
if (err2) {
callback(err2);
return;
}
return networkReady(network);
networkReady(network);
});
});
return network;
};
// ### Starting a network from a file
}; // ### Starting a network from a file
//
// It is also possible to start a NoFlo network by giving it a path to a `.json` or `.fbp` network
// definition file.
//
// noflo.loadFile('somefile.json', function (err, network) {

@@ -171,9 +211,11 @@ // if (err) {

// })
exports.loadFile = function(file, options, callback) {
var baseDir;
exports.loadFile = function loadFile(file, options, callback) {
if (!callback) {
callback = options;
baseDir = null;
options = null;
}
if (callback && typeof options !== 'object') {
if (callback && _typeof(options) !== 'object') {
options = {

@@ -183,28 +225,38 @@ baseDir: options

}
return exports.graph.loadFile(file, function(err, net) {
if (_typeof(options) !== 'object') {
options = {};
}
if (!options.subscribeGraph) {
options.subscribeGraph = false;
}
exports.graph.loadFile(file, function (err, net) {
if (err) {
return callback(err);
callback(err);
return;
}
if (options.baseDir) {
net.baseDir = options.baseDir;
}
return exports.createNetwork(net, callback, options);
exports.createNetwork(net, options, callback);
});
};
// ### Saving a network definition
}; // ### Saving a network definition
//
// NoFlo graph files can be saved back into the filesystem with this method.
exports.saveFile = function(graph, file, callback) {
return graph.save(file, callback);
};
// ## Embedding NoFlo in existing JavaScript code
exports.saveFile = function saveFile(graph, file, callback) {
graph.save(file, callback);
}; // ## Embedding NoFlo in existing JavaScript code
//
// The `asCallback` helper provides an interface to wrap NoFlo components
// or graphs into existing JavaScript code.
//
// // Produce an asynchronous function wrapping a NoFlo graph
// var wrapped = noflo.asCallback('myproject/MyGraph');
//
// // Call the function, providing input data and a callback for output data

@@ -216,10 +268,11 @@ // wrapped({

// });
exports.asCallback = require('./AsCallback').asCallback;
//
// ## Generating components from JavaScript functions
exports.asCallback = require('./AsCallback').asCallback; // ## Generating components from JavaScript functions
//
// The `asComponent` helper makes it easy to expose a JavaScript function as a
// NoFlo component. All input arguments become input ports, and the function's
// result will be sent to either `out` or `error` port.
//
// exports.getComponent = function () {

@@ -230,2 +283,4 @@ // return noflo.asComponent(Math.random, {

// };
exports.asComponent = require('./AsComponent').asComponent;
//
exports.asComponent = require('./AsComponent').asComponent;

@@ -0,184 +1,262 @@

"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); }
function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
// NoFlo - Flow-Based Programming for JavaScript
// (c) 2014-2017 Flowhub UG
// NoFlo may be freely distributed under the MIT license
var BasePort, IP, OutPort;
var BasePort = require('./BasePort');
BasePort = require('./BasePort');
var IP = require('./IP'); // ## NoFlo outport
//
// Outport Port (outport) implementation for NoFlo components.
// These ports are the way a component sends Information Packets.
IP = require('./IP');
// ## NoFlo outport
module.exports = /*#__PURE__*/function (_BasePort) {
_inherits(OutPort, _BasePort);
// Outport Port (outport) implementation for NoFlo components.
// These ports are the way a component sends Information Packets.
OutPort = class OutPort extends BasePort {
constructor(options = {}) {
if (options.scoped == null) {
options.scoped = true;
var _super = _createSuper(OutPort);
function OutPort() {
var _this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, OutPort);
var opts = options;
if (opts.scoped == null) {
opts.scoped = true;
}
super(options);
this.cache = {};
}
attach(socket, index = null) {
super.attach(socket, index);
if (this.isCaching() && (this.cache[index] != null)) {
return this.send(this.cache[index], index);
}
_this = _super.call(this, opts);
_this.cache = {};
return _this;
}
connect(socketId = null) {
var i, len, results, socket, sockets;
sockets = this.getSockets(socketId);
this.checkRequired(sockets);
results = [];
for (i = 0, len = sockets.length; i < len; i++) {
socket = sockets[i];
if (!socket) {
continue;
_createClass(OutPort, [{
key: "attach",
value: function attach(socket) {
var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
_get(_getPrototypeOf(OutPort.prototype), "attach", this).call(this, socket, index);
if (this.isCaching() && this.cache[index] != null) {
this.send(this.cache[index], index);
}
results.push(socket.connect());
}
return results;
}
}, {
key: "connect",
value: function connect() {
var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var sockets = this.getSockets(index);
this.checkRequired(sockets);
sockets.forEach(function (socket) {
if (!socket) {
return;
}
beginGroup(group, socketId = null) {
var sockets;
sockets = this.getSockets(socketId);
this.checkRequired(sockets);
return sockets.forEach(function(socket) {
if (!socket) {
return;
socket.connect();
});
}
}, {
key: "beginGroup",
value: function beginGroup(group) {
var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var sockets = this.getSockets(index);
this.checkRequired(sockets);
sockets.forEach(function (socket) {
if (!socket) {
return;
}
socket.beginGroup(group);
});
}
}, {
key: "send",
value: function send(data) {
var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var sockets = this.getSockets(index);
this.checkRequired(sockets);
if (this.isCaching() && data !== this.cache[index]) {
this.cache[index] = data;
}
return socket.beginGroup(group);
});
}
send(data, socketId = null) {
var sockets;
sockets = this.getSockets(socketId);
this.checkRequired(sockets);
if (this.isCaching() && data !== this.cache[socketId]) {
this.cache[socketId] = data;
sockets.forEach(function (socket) {
if (!socket) {
return;
}
socket.send(data);
});
}
return sockets.forEach(function(socket) {
if (!socket) {
return;
}, {
key: "endGroup",
value: function endGroup() {
var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var sockets = this.getSockets(index);
this.checkRequired(sockets);
sockets.forEach(function (socket) {
if (!socket) {
return;
}
socket.endGroup();
});
}
}, {
key: "disconnect",
value: function disconnect() {
var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var sockets = this.getSockets(index);
this.checkRequired(sockets);
sockets.forEach(function (socket) {
if (!socket) {
return;
}
socket.disconnect();
});
}
}, {
key: "sendIP",
value: function sendIP(type, data, options, index) {
var autoConnect = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
var ip;
var idx = index;
if (IP.isIP(type)) {
ip = type;
idx = ip.index;
} else {
ip = new IP(type, data, options);
}
return socket.send(data);
});
}
endGroup(socketId = null) {
var i, len, results, socket, sockets;
sockets = this.getSockets(socketId);
this.checkRequired(sockets);
results = [];
for (i = 0, len = sockets.length; i < len; i++) {
socket = sockets[i];
if (!socket) {
continue;
var sockets = this.getSockets(idx);
this.checkRequired(sockets);
if (ip.datatype === 'all') {
// Stamp non-specific IP objects with port datatype
ip.datatype = this.getDataType();
}
results.push(socket.endGroup());
}
return results;
}
disconnect(socketId = null) {
var i, len, results, socket, sockets;
sockets = this.getSockets(socketId);
this.checkRequired(sockets);
results = [];
for (i = 0, len = sockets.length; i < len; i++) {
socket = sockets[i];
if (!socket) {
continue;
if (this.getSchema() && !ip.schema) {
// Stamp non-specific IP objects with port schema
ip.schema = this.getSchema();
}
results.push(socket.disconnect());
}
return results;
}
sendIP(type, data, options, socketId, autoConnect = true) {
var i, ip, len, pristine, ref, socket, sockets;
if (IP.isIP(type)) {
ip = type;
socketId = ip.index;
} else {
ip = new IP(type, data, options);
var cachedData = this.cache[idx] != null ? this.cache[idx].data : undefined;
if (this.isCaching() && data !== cachedData) {
this.cache[idx] = ip;
}
var pristine = true;
sockets.forEach(function (socket) {
if (!socket) {
return;
}
if (pristine) {
socket.post(ip, autoConnect);
pristine = false;
} else {
if (ip.clonable) {
ip = ip.clone();
}
socket.post(ip, autoConnect);
}
});
return this;
}
sockets = this.getSockets(socketId);
this.checkRequired(sockets);
if (ip.datatype === 'all') {
// Stamp non-specific IP objects with port datatype
ip.datatype = this.getDataType();
}, {
key: "openBracket",
value: function openBracket() {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
return this.sendIP('openBracket', data, options, index);
}
if (this.getSchema() && !ip.schema) {
// Stamp non-specific IP objects with port schema
ip.schema = this.getSchema();
}, {
key: "data",
value: function data(_data) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
return this.sendIP('data', _data, options, index);
}
if (this.isCaching() && data !== ((ref = this.cache[socketId]) != null ? ref.data : void 0)) {
this.cache[socketId] = ip;
}, {
key: "closeBracket",
value: function closeBracket() {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
return this.sendIP('closeBracket', data, options, index);
}
pristine = true;
for (i = 0, len = sockets.length; i < len; i++) {
socket = sockets[i];
if (!socket) {
continue;
}, {
key: "checkRequired",
value: function checkRequired(sockets) {
if (sockets.length === 0 && this.isRequired()) {
throw new Error("".concat(this.getId(), ": No connections available"));
}
if (pristine) {
socket.post(ip, autoConnect);
pristine = false;
} else {
if (ip.clonable) {
ip = ip.clone();
}
}, {
key: "getSockets",
value: function getSockets(index) {
// Addressable sockets affect only one connection at time
if (this.isAddressable()) {
if (index === null) {
throw new Error("".concat(this.getId(), " Socket ID required"));
}
socket.post(ip, autoConnect);
}
}
return this;
}
openBracket(data = null, options = {}, socketId = null) {
return this.sendIP('openBracket', data, options, socketId);
}
if (!this.sockets[index]) {
return [];
}
data(data, options = {}, socketId = null) {
return this.sendIP('data', data, options, socketId);
}
return [this.sockets[index]];
} // Regular sockets affect all outbound connections
closeBracket(data = null, options = {}, socketId = null) {
return this.sendIP('closeBracket', data, options, socketId);
}
checkRequired(sockets) {
if (sockets.length === 0 && this.isRequired()) {
throw new Error(`${this.getId()}: No connections available`);
return this.sockets;
}
}
getSockets(socketId) {
// Addressable sockets affect only one connection at time
if (this.isAddressable()) {
if (socketId === null) {
throw new Error(`${this.getId()} Socket ID required`);
}, {
key: "isCaching",
value: function isCaching() {
if (this.options.caching) {
return true;
}
if (!this.sockets[socketId]) {
return [];
}
return [this.sockets[socketId]];
}
// Regular sockets affect all outbound connections
return this.sockets;
}
isCaching() {
if (this.options.caching) {
return true;
return false;
}
return false;
}
}]);
};
module.exports = OutPort;
return OutPort;
}(BasePort);

@@ -0,17 +1,25 @@

"use strict";
// NoFlo - Flow-Based Programming for JavaScript
// (c) 2014-2017 Flowhub UG
// NoFlo may be freely distributed under the MIT license
//
/* eslint-disable
no-console,
no-undef,
*/
// Platform detection method
exports.isBrowser = function() {
exports.isBrowser = function isBrowser() {
if (typeof process !== 'undefined' && process.execPath && process.execPath.match(/node|iojs/)) {
return false;
}
return true;
};
// Mechanism for showing API deprecation warnings. By default logs the warnings
}; // Mechanism for showing API deprecation warnings. By default logs the warnings
// but can also be configured to throw instead with the `NOFLO_FATAL_DEPRECATED`
// env var.
exports.deprecated = function(message) {
exports.deprecated = function deprecated(message) {
if (exports.isBrowser()) {

@@ -21,9 +29,12 @@ if (window.NOFLO_FATAL_DEPRECATED) {

}
console.warn(message);
return;
}
if (process.env.NOFLO_FATAL_DEPRECATED) {
throw new Error(message);
}
return console.warn(message);
};
console.warn(message);
};

@@ -0,152 +1,230 @@

"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
/* eslint-disable max-classes-per-file */
// NoFlo - Flow-Based Programming for JavaScript
// (c) 2014-2017 Flowhub UG
// NoFlo may be freely distributed under the MIT license
var EventEmitter, InPort, InPorts, OutPort, OutPorts, Ports;
var _require = require('events'),
EventEmitter = _require.EventEmitter;
({EventEmitter} = require('events'));
var InPort = require('./InPort');
InPort = require('./InPort');
var OutPort = require('./OutPort'); // NoFlo ports collections
//
// Ports collection classes for NoFlo components. These are
// used to hold a set of input or output ports of a component.
OutPort = require('./OutPort');
Ports = (function() {
// NoFlo ports collections
var Ports = /*#__PURE__*/function (_EventEmitter) {
_inherits(Ports, _EventEmitter);
// Ports collection classes for NoFlo components. These are
// used to hold a set of input or output ports of a component.
class Ports extends EventEmitter {
constructor(ports) {
var name, options;
super();
this.ports = {};
if (!ports) {
return;
}
for (name in ports) {
options = ports[name];
this.add(name, options);
}
var _super = _createSuper(Ports);
function Ports(ports, model) {
var _this;
_classCallCheck(this, Ports);
_this = _super.call(this);
_this.model = model;
_this.ports = {};
if (!ports) {
return _possibleConstructorReturn(_this);
}
add(name, options, process) {
Object.keys(ports).forEach(function (name) {
var options = ports[name];
_this.add(name, options);
});
return _this;
}
_createClass(Ports, [{
key: "add",
value: function add(name, options, process) {
if (name === 'add' || name === 'remove') {
throw new Error('Add and remove are restricted port names');
}
/* eslint-disable no-useless-escape */
if (!name.match(/^[a-z0-9_\.\/]+$/)) {
throw new Error(`Port names can only contain lowercase alphanumeric characters and underscores. '${name}' not allowed`);
}
throw new Error("Port names can only contain lowercase alphanumeric characters and underscores. '".concat(name, "' not allowed"));
} // Remove previous implementation
if (this.ports[name]) {
// Remove previous implementation
this.remove(name);
}
if (typeof options === 'object' && options.canAttach) {
if (_typeof(options) === 'object' && options.canAttach) {
this.ports[name] = options;
} else {
this.ports[name] = new this.model(options, process);
var Model = this.model;
this.ports[name] = new Model(options, process);
}
this[name] = this.ports[name];
this.emit('add', name);
return this;
return this; // chainable
}
remove(name) {
}, {
key: "remove",
value: function remove(name) {
if (!this.ports[name]) {
throw new Error(`Port ${name} not defined`);
throw new Error("Port ".concat(name, " not defined"));
}
delete this.ports[name];
delete this[name];
this.emit('remove', name);
return this;
return this; // chainable
}
}]);
};
return Ports;
}(EventEmitter);
Ports.prototype.model = InPort;
exports.InPorts = /*#__PURE__*/function (_Ports) {
_inherits(InPorts, _Ports);
return Ports;
var _super2 = _createSuper(InPorts);
}).call(this);
function InPorts(ports) {
_classCallCheck(this, InPorts);
exports.InPorts = InPorts = class InPorts extends Ports {
on(name, event, callback) {
if (!this.ports[name]) {
throw new Error(`Port ${name} not available`);
}
return this.ports[name].on(event, callback);
return _super2.call(this, ports, InPort);
}
once(name, event, callback) {
if (!this.ports[name]) {
throw new Error(`Port ${name} not available`);
_createClass(InPorts, [{
key: "on",
value: function on(name, event, callback) {
if (!this.ports[name]) {
throw new Error("Port ".concat(name, " not available"));
}
this.ports[name].on(event, callback);
}
return this.ports[name].once(event, callback);
}, {
key: "once",
value: function once(name, event, callback) {
if (!this.ports[name]) {
throw new Error("Port ".concat(name, " not available"));
}
this.ports[name].once(event, callback);
}
}]);
return InPorts;
}(Ports);
exports.OutPorts = /*#__PURE__*/function (_Ports2) {
_inherits(OutPorts, _Ports2);
var _super3 = _createSuper(OutPorts);
function OutPorts(ports) {
_classCallCheck(this, OutPorts);
return _super3.call(this, ports, OutPort);
}
};
exports.OutPorts = OutPorts = (function() {
class OutPorts extends Ports {
connect(name, socketId) {
_createClass(OutPorts, [{
key: "connect",
value: function connect(name, socketId) {
if (!this.ports[name]) {
throw new Error(`Port ${name} not available`);
throw new Error("Port ".concat(name, " not available"));
}
return this.ports[name].connect(socketId);
this.ports[name].connect(socketId);
}
beginGroup(name, group, socketId) {
}, {
key: "beginGroup",
value: function beginGroup(name, group, socketId) {
if (!this.ports[name]) {
throw new Error(`Port ${name} not available`);
throw new Error("Port ".concat(name, " not available"));
}
return this.ports[name].beginGroup(group, socketId);
this.ports[name].beginGroup(group, socketId);
}
send(name, data, socketId) {
}, {
key: "send",
value: function send(name, data, socketId) {
if (!this.ports[name]) {
throw new Error(`Port ${name} not available`);
throw new Error("Port ".concat(name, " not available"));
}
return this.ports[name].send(data, socketId);
this.ports[name].send(data, socketId);
}
endGroup(name, socketId) {
}, {
key: "endGroup",
value: function endGroup(name, socketId) {
if (!this.ports[name]) {
throw new Error(`Port ${name} not available`);
throw new Error("Port ".concat(name, " not available"));
}
return this.ports[name].endGroup(socketId);
this.ports[name].endGroup(socketId);
}
disconnect(name, socketId) {
}, {
key: "disconnect",
value: function disconnect(name, socketId) {
if (!this.ports[name]) {
throw new Error(`Port ${name} not available`);
throw new Error("Port ".concat(name, " not available"));
}
return this.ports[name].disconnect(socketId);
this.ports[name].disconnect(socketId);
}
}]);
};
OutPorts.prototype.model = OutPort;
return OutPorts;
}(Ports); // Port name normalization:
// returns object containing keys name and index for ports names in
// format `portname` or `portname[index]`.
}).call(this);
// Port name normalization:
// returns object containing keys name and index for ports names in
// format `portname` or `portname[index]`.
exports.normalizePortName = function(name) {
var matched, port;
port = {
exports.normalizePortName = function normalizePortName(name) {
var port = {
name: name
};
}; // Regular port
if (name.indexOf('[') === -1) {
// Regular port
return port;
}
// Addressable port with index
matched = name.match(/(.*)\[([0-9]+)\]/);
if (!(matched != null ? matched.length : void 0)) {
} // Addressable port with index
var matched = name.match(/(.*)\[([0-9]+)\]/);
if (!(matched != null ? matched.length : undefined)) {
return name;
}
port.name = matched[1];
port.index = matched[2];
return port;
};
return {
name: matched[1],
index: matched[2]
};
};

@@ -0,1 +1,3 @@

"use strict";
// NoFlo - Flow-Based Programming for JavaScript

@@ -5,74 +7,88 @@ // (c) 2014-2017 Flowhub UG

/* eslint-disable
no-param-reassign,
prefer-rest-params,
*/
// Guess language from filename
var createReduce, debounce, guessLanguageFromFilename, isArray, optimizeCb, reduceRight;
guessLanguageFromFilename = function(filename) {
function guessLanguageFromFilename(filename) {
if (/.*\.coffee$/.test(filename)) {
return 'coffeescript';
}
return 'javascript';
};
}
isArray = function(obj) {
function isArray(obj) {
if (Array.isArray) {
return Array.isArray(obj);
}
return Object.prototype.toString.call(arg) === '[object Array]';
};
// the following functions are from http://underscorejs.org/docs/underscore.html
return Object.prototype.toString.call(obj) === '[object Array]';
} // the following functions are from http://underscorejs.org/docs/underscore.html
// Underscore.js 1.8.3 http://underscorejs.org
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
// Internal function that returns an efficient (for current engines)
// version of the passed-in callback,
// to be repeatedly applied in other Underscore functions.
optimizeCb = function(func, context, argCount) {
if (context === void 0) {
function optimizeCb(func, context, argCount) {
if (context === undefined) {
return func;
}
switch ((argCount === null ? 3 : argCount)) {
switch (argCount === null ? 3 : argCount) {
case 1:
return function(value) {
return function (value) {
return func.call(context, value);
};
case 2:
return function(value, other) {
return function (value, other) {
return func.call(context, value, other);
};
case 3:
return function(value, index, collection) {
return function (value, index, collection) {
return func.call(context, value, index, collection);
};
case 4:
return function(accumulator, value, index, collection) {
return func.call(context, accumulator, value, index, collection);
return function (accumulator, value, index, collection) {
func.call(context, accumulator, value, index, collection);
};
default: // No-op
}
return function() {
return function call() {
return func.apply(context, arguments);
};
};
// Create a reducing function iterating left or right.
} // Create a reducing function iterating left or right.
// Optimized iterator function as using arguments.length in the main function
// will deoptimize the, see #1991.
createReduce = function(dir) {
var iterator;
iterator = function(obj, iteratee, memo, keys, index, length) {
var currentKey;
function createReduce(dir) {
function iterator(obj, iteratee, memo, keys, index, length) {
while (index >= 0 && index < length) {
currentKey = keys ? keys[index] : index;
var currentKey = keys ? keys[index] : index;
memo = iteratee(memo, obj[currentKey], currentKey, obj);
index += dir;
}
return memo;
};
return function(obj, iteratee, memo, context) {
var index, keys, length;
}
return function reduce(obj, iteratee, memo, context) {
iteratee = optimizeCb(iteratee, context, 4);
keys = Object.keys(obj);
length = (keys || obj).length;
index = dir > 0 ? 0 : length - 1;
var keys = Object.keys(obj);
var _ref = keys || obj,
length = _ref.length;
var index = dir > 0 ? 0 : length - 1;
if (arguments.length < 3) {

@@ -82,9 +98,8 @@ memo = obj[keys ? keys[index] : index];

}
return iterator(obj, iteratee, memo, keys, index, length);
};
};
}
reduceRight = createReduce(-1);
// Returns a function, that, as long as it continues to be invoked,
var reduceRight = createReduce(-1); // Returns a function, that, as long as it continues to be invoked,
// will not be triggered.

@@ -94,12 +109,13 @@ // The function will be called after it stops being called for N milliseconds.

// instead of the trailing.
debounce = function(func, wait, immediate) {
var args, context, later, result, timeout, timestamp;
timeout = void 0;
args = void 0;
context = void 0;
timestamp = void 0;
result = void 0;
later = function() {
var last;
last = Date.now - timestamp;
function debounce(func, wait, immediate) {
var timeout;
var args;
var context;
var timestamp;
var result;
function later() {
var last = Date.now - timestamp;
if (last < wait && last >= 0) {

@@ -109,33 +125,37 @@ timeout = setTimeout(later, wait - last);

timeout = null;
if (!immediate) {
result = func.apply(context, args);
if (!timeout) {
context = args = null;
context = null;
args = null;
}
}
}
};
return function() {
var callNow;
}
return function after() {
context = this;
args = arguments;
timestamp = Date.now;
callNow = immediate && !timeout;
var callNow = immediate && !timeout;
if (!timeout) {
timeout = setTimeout(later, wait);
}
if (callNow) {
result = func.apply(context, args);
context = args = null;
context = null;
args = null;
}
return result;
};
};
}
exports.guessLanguageFromFilename = guessLanguageFromFilename;
exports.reduceRight = reduceRight;
exports.debounce = debounce;
exports.isArray = isArray;
exports.isArray = isArray;

@@ -11,3 +11,3 @@ {

"author": "Henri Bergius <henri.bergius@iki.fi>",
"version": "1.1.3",
"version": "1.2.0",
"license": "MIT",

@@ -19,26 +19,27 @@ "engines": {

"coffeescript": "^2.2.1",
"debug": "^3.0.0",
"debug": "^4.0.1",
"fbp": "^1.5.0",
"fbp-graph": "^0.3.1",
"fbp-graph": "^0.4.0",
"fbp-manifest": "^0.2.0",
"get-function-params": "^2.0.3"
"get-function-params": "^2.0.6"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"@babel/cli": "^7.10.5",
"@babel/core": "^7.11.1",
"@babel/preset-env": "^7.11.0",
"chai": "^4.0.0",
"coffee-coverage": "^3.0.0",
"coveralls": "^3.0.0",
"grunt": "^1.0.1",
"grunt-cli": "^1.2.0",
"grunt-coffeelint": "^0.0.16",
"grunt-contrib-coffee": "^2.0.0",
"grunt-contrib-connect": "^1.0.1",
"grunt-contrib-watch": "^1.0.0",
"grunt-mocha-phantomjs": "^4.0.0",
"grunt-mocha-test": "^0.13.2",
"grunt-noflo-browser": "^1.5.2",
"mocha": "^5.0.0",
"nyc": "^11.2.1"
"eslint": "^7.7.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-plugin-import": "^2.22.0",
"karma": "^5.1.1",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^3.1.0",
"karma-mocha": "^2.0.1",
"karma-mocha-reporter": "^2.2.5",
"mocha": "^7.2.0",
"noflo-component-loader": "^0.3.2",
"nyc": "^15.1.0",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12"
},

@@ -56,5 +57,9 @@ "main": "./lib/NoFlo",

"scripts": {
"test": "nyc grunt test",
"posttest": "nyc check-coverage --lines 75",
"build": "grunt build"
"pretest": "eslint src",
"test:node": "nyc mocha --require spec/utils/inject.js spec",
"test:browser": "karma start karma.config.js",
"test": "npm run test:node && npm run test:browser",
"build:node": "babel src --out-dir .",
"build:browser": "webpack",
"build": "npm run build:node && npm run build:browser"
},

@@ -67,5 +72,5 @@ "docco_husky": {

"include": [
"src/**/*.coffee"
"src/**/*.js"
]
}
}

@@ -85,2 +85,3 @@ NoFlo: Flow-based programming for JavaScript [![Build Status](https://secure.travis-ci.org/noflo/noflo.png?branch=master)](http://travis-ci.org/noflo/noflo) [![Build status](https://ci.appveyor.com/api/projects/status/k4jbqlpohq81pvny/branch/master)](https://ci.appveyor.com/project/bergie/noflo/branch/master) [![Coverage Status](https://coveralls.io/repos/github/noflo/noflo/badge.svg?branch=master)](https://coveralls.io/github/noflo/noflo?branch=master)

```bash
$ npm run build
$ npm test

@@ -94,3 +95,3 @@ ```

```bash
$ grunt test:nodejs
$ npm run test:node
```

@@ -101,23 +102,7 @@

```bash
$ grunt test:browser
$ npm run 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:
```bash
$ grunt watch
```
If you want to only run a particular part of the test suite, you can filter them using the `TESTS` environment variable:
```bash
$ TESTS="Network Lifecycle" grunt watch
```
To quit the watcher, just end the process with Ctrl-C.
## Discussion
There is an IRC channel `#fbp` on FreeNode, and questions can be posted with the [`noflo` tag on Stack Overflow](http://stackoverflow.com/questions/tagged/noflo). See <http://noflojs.org/support/> for other ways to get in touch.
There is a `#noflo` channel on the [Flow-Based Programming Slack](https://join.slack.com/t/fbphq/shared_invite/enQtOTM4ODkzMTYyODE3LTJiMmNlZjhiMWY1MDY1ODA4Y2YzNDBlNDZlMTBkMDNlMjcwNzg2MGZhZjA2NjJjYTliYTM0OTIyYmM0Yzk0MDQ), and questions can be posted with the [`noflo` tag on Stack Overflow](http://stackoverflow.com/questions/tagged/noflo). See <http://noflojs.org/support/> for other ways to get in touch.

@@ -5,7 +5,7 @@ {

"icon": "car",
"loader": "loader.coffee",
"loader": "loader.js",
"components": {
"Forward": "components/Forward.coffee"
"Forward": "components/Forward.js"
}
}
}
}

@@ -6,3 +6,3 @@ {

"components": {
"Output": "components/Output.coffee"
"Output": "components/Output.js"
}

@@ -13,2 +13,2 @@ },

}
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc