Comparing version 0.1.3 to 0.2.0
@@ -1,4 +0,4 @@ | ||
// Generated by CoffeeScript 1.3.1 | ||
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var cli, noflo, nofloRoot, path; | ||
var cli, noflo, nofloRoot, path, _; | ||
@@ -13,2 +13,4 @@ nofloRoot = "" + __dirname + "/.."; | ||
_ = require("underscore")._; | ||
cli.enable("help"); | ||
@@ -20,4 +22,2 @@ | ||
cli.enable("daemon"); | ||
cli.setApp("" + nofloRoot + "/package.json"); | ||
@@ -32,3 +32,3 @@ | ||
cli.main(function(args, options) { | ||
var arg, shell, _i, _len, _ref, _results; | ||
var arg, baseDir, loader, shell, _i, _len, _ref, _results; | ||
if (options.interactive) { | ||
@@ -41,2 +41,31 @@ process.argv = [process.argv[0], process.argv[1]]; | ||
} | ||
if (cli.args.length === 2 && cli.args[0] === 'list') { | ||
baseDir = path.resolve(process.cwd(), cli.args[1]); | ||
loader = new noflo.ComponentLoader(baseDir); | ||
loader.listComponents(function(components) { | ||
var todo; | ||
todo = 0; | ||
return _.each(components, function(path, component) { | ||
var instance; | ||
return instance = loader.load(component, function(instance) { | ||
todo--; | ||
console.log(''); | ||
console.log("" + component + " (" + path + ")"); | ||
if (instance.description) { | ||
console.log(instance.description); | ||
} | ||
if (instance.inPorts) { | ||
console.log('Inports:', _.keys(instance.inPorts).join(', ')); | ||
} | ||
if (instance.outPorts) { | ||
console.log('Outports:', _.keys(instance.outPorts).join(', ')); | ||
} | ||
if (todo === 0) { | ||
return process.exit(0); | ||
} | ||
}); | ||
}); | ||
}); | ||
return; | ||
} | ||
_ref = cli.args; | ||
@@ -43,0 +72,0 @@ _results = []; |
@@ -123,3 +123,3 @@ { | ||
"process": "Read Template", | ||
"port": "source" | ||
"port": "in" | ||
} | ||
@@ -126,0 +126,0 @@ } |
@@ -80,6 +80,6 @@ { | ||
"process": "ReadFile", | ||
"port": "source" | ||
"port": "in" | ||
} | ||
} | ||
] | ||
} | ||
} |
@@ -1,6 +0,6 @@ | ||
// Generated by CoffeeScript 1.3.1 | ||
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var ArrayPort, port, | ||
__hasProp = {}.hasOwnProperty, | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
@@ -13,4 +13,2 @@ port = require("./Port"); | ||
ArrayPort.name = 'ArrayPort'; | ||
function ArrayPort(name) { | ||
@@ -58,3 +56,3 @@ this.sockets = []; | ||
} | ||
this.sockets[socketId].on("connect", function() { | ||
this.sockets[socketId].once("connect", function() { | ||
return _this.sockets[socketId].beginGroup(group); | ||
@@ -61,0 +59,0 @@ }); |
@@ -1,6 +0,6 @@ | ||
// Generated by CoffeeScript 1.3.1 | ||
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var Component, events, | ||
__hasProp = {}.hasOwnProperty, | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
@@ -13,4 +13,2 @@ events = require("events"); | ||
Component.name = 'Component'; | ||
function Component() { | ||
@@ -17,0 +15,0 @@ return Component.__super__.constructor.apply(this, arguments); |
@@ -1,13 +0,15 @@ | ||
// Generated by CoffeeScript 1.3.1 | ||
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var Fbp; | ||
var Fbp, fs; | ||
fs = require('fs'); | ||
Fbp = (function() { | ||
Fbp.name = 'Fbp'; | ||
Fbp.prototype.matchPort = new RegExp("([A-Z\.]+)"); | ||
Fbp.prototype.matchComponent = new RegExp("([A-Za-z]+)\\(([A-Za-z0-9\/\.]+|)\\)"); | ||
Fbp.prototype.matchComponent = new RegExp("([A-Za-z\.]+)\\(([A-Za-z0-9\/\.]+|)\\)"); | ||
Fbp.prototype.matchComponentGlobal = new RegExp("([A-Za-z\.]+)\\(([A-Za-z0-9\/\.]+|)\\)", "g"); | ||
Fbp.prototype.matchInitial = new RegExp("\'(.+)\'"); | ||
@@ -19,2 +21,4 @@ | ||
Fbp.prototype.matchSubgraph = new RegExp("\n *\\'(.+)\\' *-> *GRAPH *([A-Za-z\\.]+)\\(Graph\\)"); | ||
function Fbp() { | ||
@@ -30,5 +34,29 @@ this.lastElement = null; | ||
Fbp.prototype.loadFile = function(file) { | ||
return fs.readFileSync(file, "utf-8", function(err) { | ||
if (err) { | ||
throw err; | ||
} | ||
}); | ||
}; | ||
Fbp.prototype.compileSubgraphs = function(string) { | ||
var fbp, file, index, match, name, original, _ref; | ||
while (true) { | ||
match = string.match(this.matchSubgraph); | ||
if (match == null) { | ||
return string; | ||
} else { | ||
_ref = match, match = _ref[0], file = _ref[1], name = _ref[2], index = _ref[3], original = _ref[4]; | ||
fbp = this.compileSubgraphs(this.loadFile(file)); | ||
fbp = fbp.replace(this.matchComponentGlobal, "" + name + ".$1($2)"); | ||
string = string.replace(match, "\n" + fbp); | ||
} | ||
} | ||
}; | ||
Fbp.prototype.parse = function(string) { | ||
var char, checkTerminator, component, connection, currentString, index, initial, json, port, _i, _len; | ||
currentString = ""; | ||
string = this.compileSubgraphs("\n" + string); | ||
for (index = _i = 0, _len = string.length; _i < _len; index = ++_i) { | ||
@@ -69,3 +97,3 @@ char = string[index]; | ||
if (!(this.lastElement === "initial" || this.lastElement === "port")) { | ||
throw "Port or initial expected, got " + currentString + " on line " + this.currentLine; | ||
throw new Error("Port or initial expected, got " + currentString + " on line " + this.currentLine); | ||
} | ||
@@ -79,3 +107,3 @@ this.lastElement = "connection"; | ||
if (this.lastElement !== null) { | ||
throw "Newline expected, got " + currentString + " on line " + this.currentLine; | ||
throw new Error("Newline expected, got " + currentString + " on line " + this.currentLine); | ||
} | ||
@@ -89,3 +117,3 @@ this.lastElement = "initial"; | ||
if (!(this.lastElement === "port" || this.lastElement === null)) { | ||
throw "Port or newline expected, got " + currentString + " on line " + this.currentLine; | ||
throw new Error("Port or newline expected, got " + currentString + " on line " + this.currentLine); | ||
} | ||
@@ -99,3 +127,3 @@ this.lastElement = "component"; | ||
if (!(this.lastElement === "connection" || this.lastElement === "component")) { | ||
throw "Connection or component expected, got " + currentString + " on line " + this.currentLine; | ||
throw new Error("Connection or component expected, got " + currentString + " on line " + this.currentLine); | ||
} | ||
@@ -102,0 +130,0 @@ this.lastElement = "port"; |
@@ -1,6 +0,6 @@ | ||
// Generated by CoffeeScript 1.3.1 | ||
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var Graph, events, fbp, fs, | ||
__hasProp = {}.hasOwnProperty, | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
@@ -17,4 +17,2 @@ fs = require('fs'); | ||
Graph.name = 'Graph'; | ||
Graph.prototype.name = ''; | ||
@@ -69,3 +67,3 @@ | ||
this.emit('removeNode', node); | ||
if (this.nodes.indexOf(node !== -1)) { | ||
if (-1 !== this.nodes.indexOf(node)) { | ||
return this.nodes.splice(this.nodes.indexOf(node), 1); | ||
@@ -72,0 +70,0 @@ } |
@@ -1,6 +0,6 @@ | ||
// Generated by CoffeeScript 1.3.1 | ||
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var InternalSocket, events, | ||
__hasProp = {}.hasOwnProperty, | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
@@ -13,4 +13,2 @@ events = require("events"); | ||
InternalSocket.name = 'InternalSocket'; | ||
function InternalSocket() { | ||
@@ -17,0 +15,0 @@ this.connected = false; |
194
lib/NoFlo.js
@@ -1,4 +0,4 @@ | ||
// Generated by CoffeeScript 1.3.1 | ||
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var NoFlo, arrayport, component, graph, internalSocket, port; | ||
var NoFlo, arrayport, asynccomponent, component, componentLoader, graph, internalSocket, port; | ||
@@ -9,2 +9,6 @@ internalSocket = require("./InternalSocket"); | ||
componentLoader = require("./ComponentLoader"); | ||
asynccomponent = require("./AsyncComponent"); | ||
port = require("./Port"); | ||
@@ -18,4 +22,2 @@ | ||
NoFlo.name = 'NoFlo'; | ||
NoFlo.prototype.processes = {}; | ||
@@ -29,2 +31,4 @@ | ||
NoFlo.prototype.portBuffer = {}; | ||
function NoFlo(graph) { | ||
@@ -48,2 +52,3 @@ var _this = this; | ||
}); | ||
this.loader = new componentLoader.ComponentLoader(process.cwd()); | ||
} | ||
@@ -55,25 +60,12 @@ | ||
NoFlo.prototype.load = function(component) { | ||
var implementation; | ||
NoFlo.prototype.load = function(component, callback) { | ||
if (typeof component === 'object') { | ||
return component; | ||
return callback(component); | ||
} | ||
try { | ||
if (component.substr(0, 1) === ".") { | ||
component = "" + (process.cwd()) + (component.substr(1)); | ||
} | ||
implementation = require(component); | ||
} catch (error) { | ||
try { | ||
implementation = require("../components/" + component); | ||
} catch (localError) { | ||
error.message = "" + localError.message + " (" + error.message + ")"; | ||
throw error; | ||
} | ||
} | ||
return implementation.getComponent(); | ||
return this.loader.load(component, callback); | ||
}; | ||
NoFlo.prototype.addNode = function(node) { | ||
var process; | ||
NoFlo.prototype.addNode = function(node, callback) { | ||
var process, | ||
_this = this; | ||
if (this.processes[node.id]) { | ||
@@ -85,6 +77,16 @@ return; | ||
}; | ||
if (node.component) { | ||
process.component = this.load(node.component); | ||
if (!node.component) { | ||
this.processes[process.id] = process; | ||
if (callback) { | ||
callback(process); | ||
} | ||
return; | ||
} | ||
return this.processes[process.id] = process; | ||
return this.load(node.component, function(instance) { | ||
process.component = instance; | ||
_this.processes[process.id] = process; | ||
if (callback) { | ||
return callback(process); | ||
} | ||
}); | ||
}; | ||
@@ -148,4 +150,33 @@ | ||
NoFlo.prototype.addEdge = function(edge) { | ||
var from, socket, to, | ||
NoFlo.prototype.flushPortBuffer = function(id) { | ||
var buffer, inports, outports, _i, _j, _len, _len1; | ||
buffer = this.portBuffer[id]; | ||
inports = buffer.ins; | ||
outports = buffer.outs; | ||
for (_i = 0, _len = outports.length; _i < _len; _i++) { | ||
port = outports[_i]; | ||
port.emit("ready"); | ||
} | ||
for (_j = 0, _len1 = inports.length; _j < _len1; _j++) { | ||
port = inports[_j]; | ||
port.emit("ready"); | ||
} | ||
return delete this.portBuffer[id]; | ||
}; | ||
NoFlo.prototype.setupPortBuffer = function(id) { | ||
if (this.portBuffer[id] != null) { | ||
this.portBuffer[id].count++; | ||
} else { | ||
this.portBuffer[id] = { | ||
ins: [], | ||
outs: [], | ||
count: 1 | ||
}; | ||
} | ||
return this.portBuffer[id]; | ||
}; | ||
NoFlo.prototype.addEdge = function(edge, callback) { | ||
var buffer, from, fromPort, socket, to, | ||
_this = this; | ||
@@ -167,4 +198,15 @@ if (!edge.from.node) { | ||
if (!from.component.isReady()) { | ||
buffer = this.setupPortBuffer(from.id); | ||
from.component.once("ready", function() { | ||
return _this.addEdge(edge); | ||
var fromPort, next; | ||
_this.addEdge(edge, callback); | ||
fromPort = from.component.outPorts[edge.from.port]; | ||
buffer.outs.push(fromPort); | ||
next = function() { | ||
buffer.count--; | ||
if (buffer.count === 0) { | ||
return _this.flushPortBuffer(from.id); | ||
} | ||
}; | ||
return setTimeout(next, 0); | ||
}); | ||
@@ -181,4 +223,17 @@ return; | ||
if (!to.component.isReady()) { | ||
fromPort = from.component.outPorts[edge.from.port]; | ||
fromPort.downstreamIsGettingReady = true; | ||
buffer = this.setupPortBuffer(from.id); | ||
to.component.once("ready", function() { | ||
return _this.addEdge(edge); | ||
var next; | ||
_this.addEdge(edge, callback); | ||
fromPort = from.component.outPorts[edge.from.port]; | ||
buffer.ins.push(fromPort); | ||
next = function() { | ||
buffer.count--; | ||
if (buffer.count === 0) { | ||
return _this.flushPortBuffer(from.id); | ||
} | ||
}; | ||
return setTimeout(next, 0); | ||
}); | ||
@@ -189,3 +244,6 @@ return; | ||
this.connectPort(socket, from, edge.from.port, false); | ||
return this.connections.push(socket); | ||
this.connections.push(socket); | ||
if (callback) { | ||
return callback(); | ||
} | ||
}; | ||
@@ -219,3 +277,3 @@ | ||
NoFlo.prototype.addInitial = function(initializer) { | ||
NoFlo.prototype.addInitial = function(initializer, callback) { | ||
var socket, to, | ||
@@ -234,3 +292,3 @@ _this = this; | ||
to.component.once("ready", function() { | ||
return _this.addInitial(initializer); | ||
return _this.addInitial(initializer, callback); | ||
}); | ||
@@ -243,3 +301,6 @@ return; | ||
socket.send(initializer.from.data); | ||
return socket.disconnect(); | ||
socket.disconnect(); | ||
if (callback) { | ||
return callback(); | ||
} | ||
}; | ||
@@ -251,4 +312,4 @@ | ||
exports.createNetwork = function(graph, debug) { | ||
var edge, initializer, network, node, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2; | ||
exports.createNetwork = function(graph, debug, callback) { | ||
var network; | ||
if (debug == null) { | ||
@@ -259,17 +320,42 @@ debug = false; | ||
network.debug = debug; | ||
_ref = graph.nodes; | ||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
node = _ref[_i]; | ||
network.addNode(node); | ||
} | ||
_ref1 = graph.edges; | ||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { | ||
edge = _ref1[_j]; | ||
network.addEdge(edge); | ||
} | ||
_ref2 = graph.initializers; | ||
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { | ||
initializer = _ref2[_k]; | ||
network.addInitial(initializer); | ||
} | ||
network.loader.listComponents(function() { | ||
var edge, initializer, node, toAdd, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results; | ||
toAdd = graph.nodes.length + graph.edges.length + graph.initializers.length; | ||
if (toAdd === 0) { | ||
callback(network); | ||
return; | ||
} | ||
_ref = graph.nodes; | ||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
node = _ref[_i]; | ||
network.addNode(node, function() { | ||
toAdd--; | ||
if ((callback != null) && toAdd === 0) { | ||
return callback(network); | ||
} | ||
}); | ||
} | ||
_ref1 = graph.edges; | ||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { | ||
edge = _ref1[_j]; | ||
network.addEdge(edge, function() { | ||
toAdd--; | ||
if ((callback != null) && toAdd === 0) { | ||
return callback(network); | ||
} | ||
}); | ||
} | ||
_ref2 = graph.initializers; | ||
_results = []; | ||
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { | ||
initializer = _ref2[_k]; | ||
_results.push(network.addInitial(initializer, function() { | ||
toAdd--; | ||
if ((callback != null) && toAdd === 0) { | ||
return callback(network); | ||
} | ||
})); | ||
} | ||
return _results; | ||
}); | ||
return network; | ||
@@ -283,3 +369,3 @@ }; | ||
return graph.loadFile(file, function(net) { | ||
return success(exports.createNetwork(net, debug)); | ||
return exports.createNetwork(net, debug, success); | ||
}); | ||
@@ -296,2 +382,6 @@ }; | ||
exports.ComponentLoader = componentLoader.ComponentLoader; | ||
exports.AsyncComponent = asynccomponent.AsyncComponent; | ||
exports.Port = port.Port; | ||
@@ -298,0 +388,0 @@ |
@@ -1,6 +0,6 @@ | ||
// Generated by CoffeeScript 1.3.1 | ||
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var Port, events, | ||
__hasProp = {}.hasOwnProperty, | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
@@ -13,8 +13,38 @@ events = require("events"); | ||
Port.name = 'Port'; | ||
function Port(name) { | ||
var _this = this; | ||
this.name = name; | ||
this.socket = null; | ||
this.from = null; | ||
this.downstreamIsGettingReady = false; | ||
this.groups = []; | ||
this.data = []; | ||
this.buffer = []; | ||
this.on("ready", function() { | ||
var conn, datum, group, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3; | ||
if (_this.downstreamIsGettingReady) { | ||
_this.downstreamIsGettingReady = false; | ||
_ref = _this.buffer; | ||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
conn = _ref[_i]; | ||
_ref1 = conn.groups; | ||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { | ||
group = _ref1[_j]; | ||
_this.beginGroup(group); | ||
} | ||
_ref2 = conn.data; | ||
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { | ||
datum = _ref2[_k]; | ||
_this.send(datum); | ||
} | ||
_ref3 = conn.groups; | ||
for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { | ||
group = _ref3[_l]; | ||
_this.endGroup(); | ||
} | ||
_this.disconnect(); | ||
} | ||
return _this.buffer = []; | ||
} | ||
}); | ||
} | ||
@@ -53,2 +83,5 @@ | ||
Port.prototype.connect = function() { | ||
if (this.downstreamIsGettingReady) { | ||
return; | ||
} | ||
if (!this.socket) { | ||
@@ -62,2 +95,6 @@ throw new Error("No connection available"); | ||
var _this = this; | ||
if (this.downstreamIsGettingReady) { | ||
this.groups.push(group); | ||
return; | ||
} | ||
if (!this.socket) { | ||
@@ -77,2 +114,6 @@ throw new Error("No connection available"); | ||
var _this = this; | ||
if (this.downstreamIsGettingReady) { | ||
this.data.push(data); | ||
return; | ||
} | ||
if (!this.socket) { | ||
@@ -91,2 +132,5 @@ throw new Error("No connection available"); | ||
Port.prototype.endGroup = function() { | ||
if (this.downstreamIsGettingReady) { | ||
return; | ||
} | ||
if (!this.socket) { | ||
@@ -99,2 +143,13 @@ throw new Error("No connection available"); | ||
Port.prototype.disconnect = function() { | ||
var buffer; | ||
if (this.downstreamIsGettingReady) { | ||
buffer = { | ||
groups: this.groups, | ||
data: this.data | ||
}; | ||
this.buffer.push(buffer); | ||
this.groups = []; | ||
this.data = []; | ||
return; | ||
} | ||
if (!this.socket) { | ||
@@ -101,0 +156,0 @@ return; |
@@ -1,2 +0,2 @@ | ||
// Generated by CoffeeScript 1.3.1 | ||
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
@@ -3,0 +3,0 @@ var express, noflo, nofloRoot, path, prepareEdge, prepareNetwork, prepareNode, preparePort; |
@@ -1,2 +0,2 @@ | ||
// Generated by CoffeeScript 1.3.1 | ||
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
@@ -3,0 +3,0 @@ var app, noflo, noflo_root, normalizePath, shell; |
@@ -1,2 +0,2 @@ | ||
// Generated by CoffeeScript 1.3.1 | ||
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
@@ -3,0 +3,0 @@ var noflo; |
@@ -10,3 +10,3 @@ { | ||
], | ||
"version": "0.1.3", | ||
"version": "0.2.0", | ||
"licenses": [{ | ||
@@ -22,4 +22,7 @@ "type": "MIT", | ||
"cli": ">=0.3.7", | ||
"daemon": "0.4.x", | ||
"glob": ">=2.0.7" | ||
"glob": ">=2.0.7", | ||
"underscore": ">=1.3.3", | ||
"read-installed": "0.0.x", | ||
"npmlog": "0.0.x", | ||
"coffee-script": ">=1.1.0" | ||
}, | ||
@@ -29,7 +32,4 @@ "devDependencies": { | ||
"async" : ">=0.1.18", | ||
"coffee-script": ">=1.1.0", | ||
"docco-husky": ">=0.3.2", | ||
"kckupmq": "0.3.x", | ||
"jsdom": "0.2.x", | ||
"request": "2.x.x" | ||
"coffeelint": "*" | ||
}, | ||
@@ -46,3 +46,4 @@ "main": "./lib/NoFlo", | ||
"scripts": { | ||
"test": "./node_modules/nodeunit/bin/nodeunit test" | ||
"pretest": "./node_modules/.bin/coffeelint -f test/coffeelint.json -r src", | ||
"test": "./node_modules/.bin/nodeunit test" | ||
}, | ||
@@ -49,0 +50,0 @@ "docco_husky": { |
150
README.md
@@ -97,26 +97,28 @@ NoFlo: Flow-based programming for Node.js [![Build Status](https://secure.travis-ci.org/bergie/noflo.png?branch=master)](http://travis-ci.org/bergie/noflo) | ||
noflo = require "noflo" | ||
```coffeescript | ||
noflo = require "noflo" | ||
class Forwarder extends noflo.Component | ||
description: "This component receives data on a single input | ||
class Forwarder extends noflo.Component | ||
description: "This component receives data on a single input | ||
port and sends the same data out to the output port" | ||
constructor: -> | ||
# Register ports | ||
@inPorts = | ||
in: new noflo.Port() | ||
@outPorts = | ||
out: new noflo.Port() | ||
constructor: -> | ||
# Register ports | ||
@inPorts = | ||
in: new noflo.Port() | ||
@outPorts = | ||
out: new noflo.Port() | ||
@inPorts.in.on "data", (data) => | ||
# Forward data when we receive it. | ||
# Note: send() will connect automatically if needed | ||
@outPorts.out.send data | ||
@inPorts.in.on "data", (data) => | ||
# Forward data when we receive it. | ||
# Note: send() will connect automatically if needed | ||
@outPorts.out.send data | ||
@inPorts.in.on "disconnect", => | ||
# Disconnect output port when input port disconnects | ||
@outPorts.out.disconnect() | ||
@inPorts.in.on "disconnect", => | ||
# Disconnect output port when input port disconnects | ||
@outPorts.out.disconnect() | ||
exports.getComponent = -> | ||
new Forwarder() | ||
exports.getComponent = -> | ||
new Forwarder() | ||
``` | ||
@@ -137,8 +139,10 @@ This example component register two ports: _in_ and _out_. When it receives data in the _in_ port, it opens the _out_ port and sends the same data there. When the _in_ connection closes, it will also close the _out_ connection. So basically this component would be a simple repeater. | ||
# Load a subgraph as a new process | ||
'examples/spreadsheet/parse.fbp' -> GRAPH Reader(Graph) | ||
# Send the filename to the component (subgraph) | ||
'somefile.xls' -> READ.SOURCE Reader() | ||
# Display the results | ||
Reader() ENTITIZE.OUT -> IN Display(Output) | ||
```fbp | ||
# Load a subgraph as a new process | ||
'examples/spreadsheet/parse.fbp' -> GRAPH Reader(Graph) | ||
# Send the filename to the component (subgraph) | ||
'somefile.xls' -> READ.SOURCE Reader() | ||
# Display the results | ||
Reader() ENTITIZE.OUT -> IN Display(Output) | ||
``` | ||
@@ -232,43 +236,47 @@ ### Some words on component design | ||
{ | ||
"properties": { | ||
"name": "Count lines in a file" | ||
```json | ||
{ | ||
"properties": { | ||
"name": "Count lines in a file" | ||
}, | ||
"processes": { | ||
"Read File": { | ||
"component": "ReadFile" | ||
}, | ||
"processes": { | ||
"Read File": { | ||
"component": "ReadFile" | ||
"Split by Lines": { | ||
"component": "SplitStr" | ||
}, | ||
... | ||
}, | ||
"connections": [ | ||
{ | ||
"data": "package.json", | ||
"tgt": { | ||
"process": "Read File", | ||
"port": "source" | ||
} | ||
}, | ||
{ | ||
"src": { | ||
"process": "Read File", | ||
"port": "out" | ||
}, | ||
"Split by Lines": { | ||
"component": "SplitStr" | ||
}, | ||
... | ||
"tgt": { | ||
"process": "Split by Lines", | ||
"port": "in" | ||
} | ||
}, | ||
"connections": [ | ||
{ | ||
"data": "package.json", | ||
"tgt": { | ||
"process": "Read File", | ||
"port": "source" | ||
} | ||
}, | ||
{ | ||
"src": { | ||
"process": "Read File", | ||
"port": "out" | ||
}, | ||
"tgt": { | ||
"process": "Split by Lines", | ||
"port": "in" | ||
} | ||
}, | ||
... | ||
] | ||
} | ||
... | ||
] | ||
} | ||
``` | ||
To run a graph file, you can either use the _load_ command of the NoFlo shell, or do it programmatically: | ||
noflo = require "noflo" | ||
noflo.loadFile "example.json", (network) -> | ||
console.log "Graph loaded" | ||
console.log network.graph.toDOT() | ||
```coffeescript | ||
noflo = require "noflo" | ||
noflo.loadFile "example.json", (network) -> | ||
console.log "Graph loaded" | ||
console.log network.graph.toDOT() | ||
``` | ||
@@ -288,14 +296,18 @@ ## Language for Flow-Based Programming | ||
'somefile.txt' -> SOURCE Read(ReadFile) OUT -> IN Split(SplitStr) | ||
Split() OUT -> IN Count(Counter) COUNT -> IN Display(Output) | ||
Read() ERROR -> IN Display() | ||
```fbp | ||
'somefile.txt' -> SOURCE Read(ReadFile) OUT -> IN Split(SplitStr) | ||
Split() OUT -> IN Count(Counter) COUNT -> IN Display(Output) | ||
Read() ERROR -> IN Display() | ||
``` | ||
NoFlo supports the FBP language fully. You can either load a graph with a string of FBP-language commands with: | ||
```coffeescript | ||
fbpData = "<some FBP language connections>" | ||
fbpData = "<some FBP language connections>" | ||
noflo = require "noflo" | ||
noflo.graph.loadFbp fbpData, (graph) -> | ||
console.log "Graph loaded" | ||
console.log graph.toDOT() | ||
noflo = require "noflo" | ||
noflo.graph.loadFbp fbpData, (graph) -> | ||
console.log "Graph loaded" | ||
console.log graph.toDOT() | ||
``` | ||
@@ -328,2 +340,2 @@ The `.fbp` file suffix is used for files containing FBP language. This means you can load them also the same way as you load JSON files, using the `noflo.loadFile` method, or the NoFlo shell. Example: | ||
* [Web Workers](https://github.com/pgriess/node-webworker) based multiprocess runner | ||
* Sockets-based multi-computer runner | ||
* Sockets-based multi-computer runner, or possibly DNode |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
4
337
5
1
2188532
7
199
4625
+ Addedcoffee-script@>=1.1.0
+ Addednpmlog@0.0.x
+ Addedread-installed@0.0.x
+ Addedunderscore@>=1.3.3
+ Addedansi@0.2.1(transitive)
+ Addedcoffee-script@1.12.7(transitive)
+ Addedgithub-url-from-git@1.1.1(transitive)
+ Addedglob@3.2.11(transitive)
+ Addedgraceful-fs@1.1.141.2.3(transitive)
+ Addedlru-cache@2.7.3(transitive)
+ Addedminimatch@0.3.0(transitive)
+ Addednormalize-package-data@0.1.7(transitive)
+ Addednpmlog@0.0.6(transitive)
+ Addedread-installed@0.0.4(transitive)
+ Addedread-package-json@0.4.1(transitive)
+ Addedsemver@1.1.4(transitive)
+ Addedsigmund@1.0.1(transitive)
+ Addedslide@1.1.6(transitive)
+ Addedunderscore@1.13.7(transitive)
- Removeddaemon@0.4.x
- Removeddaemon@0.4.1(transitive)