New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.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.2.7 to 1.3.0

21

CHANGES.md
NoFlo ChangeLog
===============
## 1.3.0 (November 23rd 2020)
* NoFlo `createNetwork` and `asCallback` now accept a `flowtrace` option to pass a [Flowtrace instance](https://github.com/flowbased/flowtrace) for retroactive debugging. Example:
```javascript
const { Flowtrace } = require('flowtrace');
const tracer = new Flowtrace();
noflo.createNetwork(myGraph, {
flowtrace: tracer,
}, (err, network) => {
// ...
console.log(tracer.toJSON());
});
```
* NoFlo `createNetwork` now accepts `componentLoader` and `baseDir` via options. Passing them via Graph properties is deprecated
* NoFlo `createNetwork` now defaults to the non-legacy "network drives graph" mode
* NoFlo `createNetwork` now only supports the `graph, options, callback` signature, no options given in some other order
* `noflo.Network` interface has been removed. Use `createNetwork` to instantiate networks
* CoffeeScript is no longer bundled with NoFlo. Install the CoffeeScript compiler in your project if you need to be able to load CoffeeScript components
## 1.2.7 (November 13th 2020)

@@ -5,0 +26,0 @@

9

components/Graph.js

@@ -105,4 +105,2 @@ "use strict";

inst.properties.baseDir = _this2.baseDir;
_this2.createNetwork(inst, callback);

@@ -127,4 +125,2 @@ });

inst.properties.baseDir = _this2.baseDir;
_this2.createNetwork(inst, callback);

@@ -146,6 +142,7 @@ });

graphObj.properties.componentLoader = this.loader;
noflo.createNetwork(graphObj, {
delay: true,
subscribeGraph: false
subscribeGraph: false,
componentLoader: this.loader,
baseDir: this.baseDir
}, function (err, network) {

@@ -152,0 +149,0 @@ _this3.network = network;

"use strict";
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
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); }

@@ -86,4 +92,5 @@

// This is a graph object
component.properties.componentLoader = options.loader;
network = new Network(component, options); // Wire the network up
network = new Network(component, _objectSpread(_objectSpread({}, options), {}, {
componentLoader: options.loader
})); // Wire the network up

@@ -122,4 +129,5 @@ network.connect(function (err) {

graph.properties.componentLoader = options.loader;
network = new Network(graph, options); // Wire the network up and start execution
network = new Network(graph, _objectSpread(_objectSpread({}, options), {}, {
componentLoader: options.loader
})); // Wire the network up and start execution

@@ -158,2 +166,3 @@ network.connect(function (err2) {

outSockets[outport] = internalSocket.createSocket();
network.subscribeSocket(outSockets[outport]);
process.component.outPorts[portDef.port].attach(outSockets[outport]);

@@ -221,2 +230,7 @@ outSockets[outport].from = {

inSockets[port] = internalSocket.createSocket();
network.subscribeSocket(inSockets[port]);
inSockets[port].to = {
process: _process,
port: port
};

@@ -223,0 +237,0 @@ _process.component.inPorts[portDef.port].attach(inSockets[port]);

@@ -47,2 +47,5 @@ "use strict";

var _require2 = require('./Platform'),
deprecated = _require2.deprecated;
function connectPort(socket, process, port, index, inbound, callback) {

@@ -144,7 +147,11 @@ if (inbound) {

if (graph.properties.baseDir && !options.baseDir) {
deprecated('Passing baseDir via Graph properties is deprecated, pass via Network options instead');
}
if (!platform.isBrowser()) {
_this.baseDir = graph.properties.baseDir || process.cwd(); // On browser we default the baseDir to the Component loading
_this.baseDir = options.baseDir || graph.properties.baseDir || process.cwd(); // On browser we default the baseDir to the Component loading
// root
} else {
_this.baseDir = graph.properties.baseDir || '/';
_this.baseDir = options.baseDir || graph.properties.baseDir || '/';
} // As most NoFlo networks are long-running processes, the

@@ -157,8 +164,16 @@ // network coordinator marks down the start-up time. This

if (graph.properties.componentLoader) {
if (options.componentLoader) {
_this.loader = options.componentLoader;
} else if (graph.properties.componentLoader) {
deprecated('Passing componentLoader via Graph properties is deprecated, pass via Network options instead');
_this.loader = graph.properties.componentLoader;
} else {
_this.loader = new componentLoader.ComponentLoader(_this.baseDir, _this.options);
}
} // Enable Flowtrace for this network, when available
_this.flowtraceName = null;
_this.setFlowtrace(options.flowtrace || false, null);
return _this;

@@ -205,2 +220,66 @@ } // The uptime of the network is the current time minus the start-up

}, {
key: "traceEvent",
value: function traceEvent(event, payload) {
if (!this.flowtrace) {
return;
}
if (this.flowtraceName && this.flowtraceName !== this.flowtrace.mainGraph) {
// Let main graph log all events from subgraphs
return;
}
switch (event) {
case 'ip':
{
var type = 'data';
if (payload.type === 'openBracket') {
type = 'begingroup';
} else if (payload.type === 'closeBracket') {
type = 'endgroup';
}
var src = payload.socket.from ? {
node: payload.socket.from.process.id,
port: payload.socket.from.port
} : null;
var tgt = payload.socket.to ? {
node: payload.socket.to.process.id,
port: payload.socket.to.port
} : null;
this.flowtrace.addNetworkPacket("network:".concat(type), src, tgt, this.flowtraceName, {
subgraph: payload.subgraph,
group: payload.group,
datatype: payload.datatype,
schema: payload.schema,
data: payload.data
});
break;
}
case 'start':
{
this.flowtrace.addNetworkStarted(this.flowtraceName);
break;
}
case 'end':
{
this.flowtrace.addNetworkStopped(this.flowtraceName);
break;
}
case 'error':
{
this.flowtrace.addNetworkError(this.flowtraceName, payload);
break;
}
default:
{// No default handler
}
}
}
}, {
key: "bufferedEmit",

@@ -210,3 +289,5 @@ value: function bufferedEmit(event, payload) {

// Errors get emitted immediately, like does network end
// Add the event to Flowtrace immediately
this.traceEvent(event, payload); // Errors get emitted immediately, like does network end
if (['icon', 'error', 'process-error', 'end'].includes(event)) {

@@ -476,2 +557,6 @@ this.emit(event, payload);

if (this.flowtrace) {
node.component.network.setFlowtrace(this.flowtrace, node.componentName, false);
}
var emitSub = function emitSub(type, data) {

@@ -500,3 +585,3 @@ if (type === 'process-error' && _this7.listeners('process-error').length === 0) {

return _this7.bufferedEmit(type, data);
_this7.bufferedEmit(type, data);
};

@@ -1173,2 +1258,35 @@

}
}, {
key: "setFlowtrace",
value: function setFlowtrace(flowtrace) {
var _this21 = this;
var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var main = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
if (!flowtrace) {
this.flowtraceName = null;
this.flowtrace = null;
return;
}
if (this.flowtrace) {
// We already have a tracer
return;
}
this.flowtrace = flowtrace;
this.flowtraceName = name || this.graph.name;
this.flowtrace.addGraph(this.flowtraceName, this.graph, main);
Object.keys(this.processes).forEach(function (nodeId) {
// Register existing subgraphs
var node = _this21.processes[nodeId];
if (!node.component.isSubgraph() || !node.component.network) {
return;
}
node.component.network.setFlowtrace(_this21.flowtrace, node.componentName, false);
});
}
}]);

@@ -1175,0 +1293,0 @@

@@ -64,3 +64,3 @@ "use strict";

deprecated('noflo.Network construction is deprecated, use noflo.createNetwork');
deprecated('subscribeGraph: true is deprecated. Live-edit network graphs via the network methods instead');
return _super.call(this, graph, options);

@@ -67,0 +67,0 @@ } // eslint-disable-next-line no-unused-vars

@@ -31,8 +31,4 @@ "use strict";

try {
// eslint-disable-next-line import/no-unresolved
// eslint-disable-next-line import/no-unresolved,import/no-extraneous-dependencies
CoffeeScript = require('coffeescript');
if (typeof CoffeeScript.register !== 'undefined') {
CoffeeScript.register();
}
} catch (e) {// If there is no CoffeeScript compiler installed, we simply don't support compiling

@@ -378,4 +374,4 @@ } // Try loading TypeScript compiler

if (language === 'typescript') {
// We can't require a TypeScript module, go the setSource route
if (language === 'typescript' || language === 'coffeescript') {
// We can't require a module that requires transpilation, go the setSource route
fs.readFile(path.resolve(loader.baseDir, c.path), 'utf-8', function (fsErr, source) {

@@ -382,0 +378,0 @@ if (fsErr) {

@@ -31,19 +31,7 @@ "use strict";

exports.journal = fbpGraph.journal;
exports.Journal = fbpGraph.Journal; // ## Network interface
exports.Journal = fbpGraph.Journal; // ### Platform detection
//
// [Network](../Network/) is used for running NoFlo graphs. The direct Network inteface is only
// provided for backwards compatibility purposes. Use `createNetwork` instead.
var _require = require('./Network'),
Network = _require.Network;
exports.Network = require('./LegacyNetwork').Network;
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

@@ -83,3 +71,3 @@ //

//
// noflo.createNetwork(someGraph, function (err, network) {
// noflo.createNetwork(someGraph, {}, function (err, network) {
// console.log('Network is now running!');

@@ -89,6 +77,8 @@ // });

// 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
// third `delay` option. In this case you will have to handle connecting the graph and
// sending of IIPs manually.
//
// noflo.createNetwork(someGraph, function (err, network) {
// noflo.createNetwork(someGraph, {
// delay: true,
// }, function (err, network) {
// if (err) {

@@ -100,4 +90,4 @@ // throw err;

// console.log('Network is now running!');
// })
// }, true);
// });
// });
//

@@ -108,5 +98,10 @@ // ### Network options

//
// * `baseDir`: (default: cwd) Project base directory used for component loading
// * `componentLoader`: (default: NULL) NoFlo ComponentLoader instance to use for the
// network. New one will be instantiated for the baseDir if this is not given.
// * `delay`: (default: FALSE) Whether the network should be started later. Defaults to
// immediate execution
// * `subscribeGraph`: (default: TRUE) Whether the network should monitor the underlying
// * `flowtrace`: (default: NULL) Flowtrace instance to create a retroactive debugging
// trace of the network run.
// * `subscribeGraph`: (default: FALSE) Whether the network should monitor the underlying
// graph for changes

@@ -121,15 +116,12 @@ //

exports.createNetwork = function createNetwork(graph, options, callback) {
if (typeof options === 'function') {
var opts = callback;
callback = options;
options = opts;
}
var _require = require('./Network'),
Network = _require.Network;
if (typeof options === 'boolean') {
options = {
delay: options
};
}
var _require2 = require('./LegacyNetwork'),
LegacyNetwork = _require2.Network;
var _require3 = require('./Platform'),
deprecated = _require3.deprecated;
exports.createNetwork = function createNetwork(graph, options, callback) {
if (_typeof(options) !== 'object') {

@@ -140,4 +132,3 @@ options = {};

if (typeof options.subscribeGraph === 'undefined') {
// Default to legacy network for backwards compatibility.
options.subscribeGraph = true;
options.subscribeGraph = false;
}

@@ -157,3 +148,3 @@

var NetworkType = options.subscribeGraph ? exports.Network : Network;
var NetworkType = options.subscribeGraph ? LegacyNetwork : Network;
var network = new NetworkType(graph, options);

@@ -208,3 +199,3 @@

//
// noflo.loadFile('somefile.json', function (err, network) {
// noflo.loadFile('somefile.json', {}, function (err, network) {
// if (err) {

@@ -218,22 +209,13 @@ // throw err;

exports.loadFile = function loadFile(file, options, callback) {
if (!callback) {
callback = options;
options = null;
}
if (typeof callback !== 'function') {
deprecated('Calling noflo.loadFile without a callback is deprecated');
if (callback && _typeof(options) !== 'object') {
options = {
baseDir: options
callback = function callback(err) {
if (err) {
throw err;
}
};
}
if (_typeof(options) !== 'object') {
options = {};
}
if (!options.subscribeGraph) {
options.subscribeGraph = false;
}
exports.graph.loadFile(file, function (err, net) {
exports.graph.loadFile(file, function (err, graph) {
if (err) {

@@ -245,6 +227,6 @@ callback(err);

if (options.baseDir) {
net.properties.baseDir = options.baseDir;
graph.properties.baseDir = options.baseDir;
}
exports.createNetwork(net, options, callback);
exports.createNetwork(graph, options, callback);
});

@@ -251,0 +233,0 @@ }; // ### Saving a network definition

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

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

@@ -18,6 +18,5 @@ "engines": {

"dependencies": {
"coffeescript": "^2.2.1",
"debug": "^4.0.1",
"fbp": "^1.5.0",
"fbp-graph": "^0.6.1",
"fbp-graph": "^0.6.2",
"fbp-manifest": "^0.2.5",

@@ -32,2 +31,3 @@ "get-function-params": "^2.0.6"

"chai": "^4.0.0",
"coffeescript": "^2.2.1",
"coveralls": "^3.0.0",

@@ -38,2 +38,3 @@ "eslint": "^7.7.0",

"events": "^3.2.0",
"flowtrace": "^0.1.2",
"karma": "^5.1.1",

@@ -40,0 +41,0 @@ "karma-chai": "^0.1.0",

@@ -28,5 +28,6 @@ NoFlo: Flow-based programming for JavaScript

* [Flowhub](https://flowhub.io) -- browser-based visual programming **IDE** for NoFlo and other flow-based systems
* [Flowhub](https://app.flowhub.io) -- browser-based visual programming **IDE** for NoFlo and other flow-based systems
* [noflo-nodejs](https://github.com/noflo/noflo-nodejs) -- command-line interface for running NoFlo programs on **Node.js**
* [MsgFlo](https://msgflo.org) -- for running NoFlo and other FBP runtimes as a **distributed system**
* [noflo-browser-app](https://github.com/noflo/noflo-browser-app) -- template for building NoFlo programs for **the web**
* [noflo-assembly](https://github.com/noflo/noflo-assembly) -- **industrial approach** for designing NoFlo programs
* [fbp-spec](https://github.com/flowbased/fbp-spec) -- **data-driven tests** for NoFlo and other FBP environments

@@ -37,10 +38,2 @@ * [flowtrace](https://github.com/flowbased/flowtrace) -- tool for **retroactive debugging** of NoFlo programs. Supports visual replay with Flowhub

## Support
[![Flowhub logo](https://flowhub.io/assets/banner-github.png)](https://flowhub.io)
NoFlo is a part of [Flowhub](https://flowhub.io), a platform for building robust [IoT systems](https://flowhub.io/iot) and web services.<br>
We offer an [Integrated Development Environment](https://app.flowhub.io) and [consulting services](https://flowhub.io/consulting).
By [subscribing to Flowhub](https://plans.flowhub.io) you directly support NoFlo development, and help us all get to the future of programming faster.
## Requirements and installing

@@ -47,0 +40,0 @@

@@ -513,2 +513,43 @@ describe('asCallback interface', () => {

});
describe('with flowtrace option', () => {
it('should store a trace for a simple component execution', (done) => {
const trace = new flowtrace.Flowtrace();
const wrapped = noflo.asCallback('process/Async', {
loader,
flowtrace: trace,
});
wrapped('hello', (err, out) => {
chai.expect(err).to.be.a('null');
chai.expect(out).to.equal('hello');
const collectedTrace = trace.toJSON();
chai.expect(collectedTrace.header.metadata).to.include.keys(['start', 'end']);
chai.expect(collectedTrace.header.graphs['process/Async']).to.be.an('object');
chai.expect(collectedTrace.header.main).to.equal('process/Async');
const eventTypes = collectedTrace.events.map((e) => `${e.protocol}:${e.command}`);
chai.expect(eventTypes).to.eql([
'network:started',
'network:data',
'network:data',
'network:stopped',
]);
chai.expect(JSON.parse(JSON.stringify(collectedTrace.events[1].payload))).to.eql({
data: 'hello',
src: null,
tgt: {
node: 'process/Async',
port: 'in',
},
});
chai.expect(JSON.parse(JSON.stringify(collectedTrace.events[2].payload))).to.eql({
data: 'hello',
src: {
node: 'process/Async',
port: 'out',
},
tgt: null,
});
done();
});
});
});
});

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

var exported = {
noflo: require('../../lib/NoFlo')
const exported = {
noflo: require('../../lib/NoFlo'),
flowtrace: require('flowtrace'),
};

@@ -10,5 +11,4 @@

}
throw new Error('Module ' + moduleName + ' not available');
throw new Error(`Module '${moduleName}' not available`);
};
}

@@ -47,4 +47,14 @@ describe('NoFlo Legacy Network', () => {

g.properties.baseDir = baseDir;
n = new noflo.Network(g);
n.connect(done);
noflo.createNetwork(g, {
subscribeGraph: true,
delay: true,
},
(err, network) => {
if (err) {
done(err);
return;
}
n = network;
n.connect(done);
});
});

@@ -202,3 +212,6 @@ it('should initially be marked as stopped', () => {

g.addInitial('Foo', 'Merge', 'in');
noflo.createNetwork(g, (err, nw) => {
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
}, (err, nw) => {
if (err) {

@@ -219,4 +232,3 @@ done(err);

});
},
true);
});
});

@@ -347,3 +359,5 @@ it('should send some initials when started', (done) => {

'Func', 'callback');
noflo.createNetwork(graph, (err) => {
noflo.createNetwork(graph, {
subscribeGraph: true,
}, (err) => {
if (err) {

@@ -399,3 +413,6 @@ done(err);

};
noflo.createNetwork(g, (err, nw) => {
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
}, (err, nw) => {
if (err) {

@@ -418,4 +435,3 @@ done(err);

});
},
true);
});
});

@@ -431,3 +447,6 @@ it('should not send default values to nodes with an edge', function (done) {

g.addInitial('from-edge', 'Merge', 'in');
noflo.createNetwork(g, (err, nw) => {
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
}, (err, nw) => {
if (err) {

@@ -451,4 +470,3 @@ done(err);

});
},
true);
});
});

@@ -462,3 +480,6 @@ it('should not send default values to nodes with IIP', function (done) {

g.addInitial('from-IIP', 'Def', 'in');
noflo.createNetwork(g, (err, nw) => {
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
}, (err, nw) => {
if (err) {

@@ -482,4 +503,3 @@ done(err);

});
},
true);
});
});

@@ -506,3 +526,6 @@ });

setTimeout(() => {
noflo.createNetwork(g, (err, nw) => {
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
}, (err, nw) => {
if (err) {

@@ -527,4 +550,3 @@ done(err);

});
},
true);
});
},

@@ -606,4 +628,7 @@ 10);

const nw = new noflo.Network(g);
nw.loader.listComponents((err) => {
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
},
(err, nw) => {
if (err) {

@@ -652,8 +677,17 @@ done(err);

g.addEdge('Repeat1', 'out', 'Repeat2', 'in');
const nw = new noflo.Network(g);
nw.loader = loader;
nw.connect((err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('not available');
done();
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
},
(err, nw) => {
if (err) {
done(err);
return;
}
nw.loader = loader;
nw.connect((err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('not available');
done();
});
});

@@ -666,8 +700,17 @@ });

g.addEdge('Repeat1', 'out', 'Repeat2', 'foo');
const nw = new noflo.Network(g);
nw.loader = loader;
nw.connect((err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('No inport');
done();
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
},
(err, nw) => {
if (err) {
done(err);
return;
}
nw.loader = loader;
nw.connect((err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('No inport');
done();
});
});

@@ -680,9 +723,17 @@ });

g.addEdge('Repeat1', 'foo', 'Repeat2', 'in');
let nw = new noflo.Network(g);
nw = new noflo.Network(g);
nw.loader = loader;
nw.connect((err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('No outport');
done();
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
},
(err, nw) => {
if (err) {
done(err);
return;
}
nw.loader = loader;
nw.connect((err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('No outport');
done();
});
});

@@ -696,8 +747,17 @@ });

g.addInitial('hello', 'Repeat1', 'baz');
const nw = new noflo.Network(g);
nw.loader = loader;
nw.connect((err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('No inport');
done();
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
},
(err, nw) => {
if (err) {
done(err);
return;
}
nw.loader = loader;
nw.connect((err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('No inport');
done();
});
});

@@ -711,8 +771,17 @@ });

g.addInitial('hello', 'Repeat1', 'in');
const nw = new noflo.Network(g);
nw.loader = loader;
nw.connect((err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('No component defined');
done();
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
},
(err, nw) => {
if (err) {
done(err);
return;
}
nw.loader = loader;
nw.connect((err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('No component defined');
done();
});
});

@@ -723,5 +792,7 @@ });

g.addNode('Repeat1', 'Split');
const nw = new noflo.Network(g);
nw.loader = loader;
nw.connect((err) => {
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
},
(err, nw) => {
if (err) {

@@ -731,15 +802,22 @@ done(err);

}
nw.addEdge({
from: {
node: 'Repeat2',
port: 'out',
},
to: {
node: 'Repeat1',
port: 'in',
},
}, (err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('No process defined for outbound node');
done();
nw.loader = loader;
nw.connect((err) => {
if (err) {
done(err);
return;
}
nw.addEdge({
from: {
node: 'Repeat2',
port: 'out',
},
to: {
node: 'Repeat1',
port: 'in',
},
}, (err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('No process defined for outbound node');
done();
});
});

@@ -751,5 +829,7 @@ });

g.addNode('Repeat1', 'Split');
const nw = new noflo.Network(g);
nw.loader = loader;
nw.connect((err) => {
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
},
(err, nw) => {
if (err) {

@@ -759,15 +839,22 @@ done(err);

}
nw.addEdge({
from: {
node: 'Repeat1',
port: 'out',
},
to: {
node: 'Repeat2',
port: 'in',
},
}, (err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('No process defined for inbound node');
done();
nw.loader = loader;
nw.connect((err) => {
if (err) {
done(err);
return;
}
nw.addEdge({
from: {
node: 'Repeat1',
port: 'out',
},
to: {
node: 'Repeat2',
port: 'in',
},
}, (err) => {
chai.expect(err).to.be.an('error');
chai.expect(err.message).to.contain('No process defined for inbound node');
done();
});
});

@@ -778,9 +865,19 @@ });

describe('baseDir setting', () => {
it('should set baseDir based on given graph', () => {
it('should set baseDir based on given graph', (done) => {
const g = new noflo.Graph();
g.properties.baseDir = baseDir;
const n = new noflo.Network(g);
chai.expect(n.baseDir).to.equal(baseDir);
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
},
(err, nw) => {
if (err) {
done(err);
return;
}
chai.expect(nw.baseDir).to.equal(baseDir);
done();
});
});
it('should fall back to CWD if graph has no baseDir', function () {
it('should fall back to CWD if graph has no baseDir', function (done) {
if (noflo.isBrowser()) {

@@ -791,11 +888,31 @@ this.skip();

const g = new noflo.Graph();
const n = new noflo.Network(g);
chai.expect(n.baseDir).to.equal(process.cwd());
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
},
(err, nw) => {
if (err) {
done(err);
return;
}
chai.expect(nw.baseDir).to.equal(process.cwd());
done();
});
});
it('should set the baseDir for the component loader', () => {
it('should set the baseDir for the component loader', (done) => {
const g = new noflo.Graph();
g.properties.baseDir = baseDir;
const n = new noflo.Network(g);
chai.expect(n.baseDir).to.equal(baseDir);
chai.expect(n.loader.baseDir).to.equal(baseDir);
noflo.createNetwork(g, {
delay: true,
subscribeGraph: true,
},
(err, nw) => {
if (err) {
done(err);
return;
}
chai.expect(nw.baseDir).to.equal(baseDir);
chai.expect(nw.loader.baseDir).to.equal(baseDir);
done();
});
});

@@ -809,4 +926,7 @@ });

g.properties.baseDir = baseDir;
n = new noflo.Network(g);
n.loader.listComponents((err) => {
noflo.createNetwork(g, {
subscribeGraph: true,
delay: true,
},
(err, network) => {
if (err) {

@@ -816,2 +936,3 @@ done(err);

}
n = network;
n.loader.components.Split = Split;

@@ -818,0 +939,0 @@ g.addNode('A', 'Split');

@@ -46,6 +46,6 @@ describe('NoFlo Network', () => {

g = new noflo.Graph();
g.properties.baseDir = baseDir;
noflo.createNetwork(g, {
subscribeGraph: false,
delay: true,
baseDir,
},

@@ -80,3 +80,3 @@ (err, network) => {

it('should know its baseDir', () => {
chai.expect(n.baseDir).to.equal(g.properties.baseDir);
chai.expect(n.baseDir).to.equal(baseDir);
});

@@ -87,3 +87,3 @@ it('should have a ComponentLoader', () => {

it('should have transmitted the baseDir to the Component Loader', () => {
chai.expect(n.loader.baseDir).to.equal(g.properties.baseDir);
chai.expect(n.loader.baseDir).to.equal(baseDir);
});

@@ -266,3 +266,2 @@ it('should be able to list components', function (done) {

g = new noflo.Graph();
g.properties.baseDir = baseDir;
g.addNode('Merge', 'Merge');

@@ -280,2 +279,3 @@ g.addNode('Callback', 'Callback');

delay: true,
baseDir,
},

@@ -469,3 +469,2 @@ (err, nw) => {

// Pass the already-initialized component loader
graph.properties.componentLoader = n.loader;
graph.addInitial((data) => {

@@ -479,2 +478,3 @@ chai.expect(data).to.equal('Foo');

delay: false,
componentLoader: n.loader,
},

@@ -521,3 +521,2 @@ (err) => {

g = new noflo.Graph();
g.properties.baseDir = baseDir;
g.addNode('Def', 'Def');

@@ -536,2 +535,3 @@ g.addNode('Cb', 'Cb');

delay: true,
baseDir,
},

@@ -570,2 +570,3 @@ (err, nw) => {

delay: true,
baseDir,
},

@@ -603,2 +604,3 @@ (err, nw) => {

delay: true,
baseDir,
},

@@ -632,3 +634,2 @@ (err, nw) => {

g = new noflo.Graph();
g.properties.baseDir = baseDir;
g.addNode('Callback', 'Callback');

@@ -650,2 +651,3 @@ g.addNode('Repeat', 'Split');

subscribeGraph: false,
baseDir,
},

@@ -774,3 +776,2 @@ (err, nw) => {

const g = new noflo.Graph();
g.properties.baseDir = baseDir;
let called = 0;

@@ -795,2 +796,3 @@ for (n = 0; n <= 10000; n++) {

subscribeGraph: false,
baseDir,
},

@@ -843,2 +845,3 @@ (err, nw) => {

subscribeGraph: false,
componentLoader: loader,
},

@@ -850,3 +853,2 @@ (err, nw) => {

}
nw.loader = loader;
nw.connect((err) => {

@@ -867,2 +869,3 @@ chai.expect(err).to.be.an('error');

subscribeGraph: false,
componentLoader: loader,
},

@@ -874,3 +877,2 @@ (err, nw) => {

}
nw.loader = loader;
nw.connect((err) => {

@@ -891,2 +893,3 @@ chai.expect(err).to.be.an('error');

subscribeGraph: false,
componentLoader: loader,
},

@@ -898,3 +901,2 @@ (err, nw) => {

}
nw.loader = loader;
nw.connect((err) => {

@@ -916,2 +918,3 @@ chai.expect(err).to.be.an('error');

subscribeGraph: false,
componentLoader: loader,
},

@@ -923,3 +926,2 @@ (err, nw) => {

}
nw.loader = loader;
nw.connect((err) => {

@@ -941,2 +943,3 @@ chai.expect(err).to.be.an('error');

subscribeGraph: false,
componentLoader: loader,
},

@@ -948,3 +951,2 @@ (err, nw) => {

}
nw.loader = loader;
nw.connect((err) => {

@@ -963,2 +965,3 @@ chai.expect(err).to.be.an('error');

subscribeGraph: false,
componentLoader: loader,
},

@@ -970,3 +973,2 @@ (err, nw) => {

}
nw.loader = loader;
nw.connect((err) => {

@@ -1000,2 +1002,3 @@ if (err) {

subscribeGraph: false,
componentLoader: loader,
},

@@ -1007,3 +1010,2 @@ (err, nw) => {

}
nw.loader = loader;
nw.connect((err) => {

@@ -1033,3 +1035,3 @@ if (err) {

describe('baseDir setting', () => {
it('should set baseDir based on given graph', (done) => {
it('should set baseDir based on given graph (deprecated)', (done) => {
const g = new noflo.Graph();

@@ -1071,6 +1073,6 @@ g.properties.baseDir = baseDir;

const g = new noflo.Graph();
g.properties.baseDir = baseDir;
noflo.createNetwork(g, {
delay: true,
subscribeGraph: false,
baseDir,
},

@@ -1093,6 +1095,6 @@ (err, nw) => {

g = new noflo.Graph();
g.properties.baseDir = baseDir;
noflo.createNetwork(g, {
subscribeGraph: false,
default: true,
delay: true,
baseDir,
},

@@ -1099,0 +1101,0 @@ (err, network) => {

@@ -765,2 +765,3 @@ let loadingPrefix;

let network = null;
const trace = new flowtrace.Flowtrace();
before((done) => {

@@ -772,2 +773,3 @@ graph = new noflo.Graph('main');

subscribeGraph: false,
flowtrace: trace,
},

@@ -899,4 +901,38 @@ (err, net) => {

});
it('should finish', (done) => {
network.once('end', () => {
done();
});
});
it('should produce a Flowtrace with both graphs included', () => {
const collectedTrace = trace.toJSON();
chai.expect(Object.keys(collectedTrace.header.graphs), 'should have exported all graphs').to.eql([
'main',
'foo/AB2',
'foo/AB',
]);
const eventTypes = collectedTrace.events.map((e) => `${e.protocol}:${e.command}`);
chai.expect(eventTypes).to.eql([
'network:started',
'network:data',
'network:data',
'network:data',
'network:data',
'network:stopped',
]);
const subgraphs = collectedTrace.events.map((e) => {
const s = e.payload.subgraph ? e.payload.subgraph.join(':') : '';
return s;
});
chai.expect(subgraphs).to.eql([
'',
'',
'Sub:A',
'Sub',
'',
'',
]);
});
});
});
});

@@ -7,2 +7,3 @@ /* eslint-disable */

global.noflo = require('../../src/lib/NoFlo');
global.flowtrace = require('flowtrace');
global.baseDir = process.cwd();

@@ -13,2 +14,3 @@ } else {

window.baseDir = 'browser';
window.flowtrace = require('flowtrace');
}

@@ -63,3 +63,2 @@ // NoFlo - Flow-Based Programming for JavaScript

}
inst.properties.baseDir = this.baseDir;
this.createNetwork(inst, callback);

@@ -82,3 +81,2 @@ });

}
inst.properties.baseDir = this.baseDir;
this.createNetwork(inst, callback);

@@ -94,3 +92,2 @@ });

if (!graphObj.name) { graphObj.name = this.nodeId; }
graphObj.properties.componentLoader = this.loader;

@@ -100,2 +97,4 @@ noflo.createNetwork(graphObj, {

subscribeGraph: false,
componentLoader: this.loader,
baseDir: this.baseDir,
},

@@ -102,0 +101,0 @@ (err, network) => {

@@ -69,5 +69,6 @@ // NoFlo - Flow-Based Programming for JavaScript

// This is a graph object
component.properties.componentLoader = options.loader;
network = new Network(component, options);
network = new Network(component, {
...options,
componentLoader: options.loader,
});
// Wire the network up

@@ -104,4 +105,6 @@ network.connect((err) => {

// Prepare network
graph.properties.componentLoader = options.loader;
network = new Network(graph, options);
network = new Network(graph, {
...options,
componentLoader: options.loader,
});
// Wire the network up and start execution

@@ -139,2 +142,3 @@ network.connect((err2) => {

outSockets[outport] = internalSocket.createSocket();
network.subscribeSocket(outSockets[outport]);
process.component.outPorts[portDef.port].attach(outSockets[outport]);

@@ -193,2 +197,7 @@ outSockets[outport].from = {

inSockets[port] = internalSocket.createSocket();
network.subscribeSocket(inSockets[port]);
inSockets[port].to = {
process,
port,
};
process.component.inPorts[portDef.port].attach(inSockets[port]);

@@ -195,0 +204,0 @@ }

@@ -17,2 +17,3 @@ // NoFlo - Flow-Based Programming for JavaScript

const IP = require('./IP');
const { deprecated } = require('./Platform');

@@ -101,8 +102,11 @@ function connectPort(socket, process, port, index, inbound, callback) {

// the current working directory
if (graph.properties.baseDir && !options.baseDir) {
deprecated('Passing baseDir via Graph properties is deprecated, pass via Network options instead');
}
if (!platform.isBrowser()) {
this.baseDir = graph.properties.baseDir || process.cwd();
this.baseDir = options.baseDir || graph.properties.baseDir || process.cwd();
// On browser we default the baseDir to the Component loading
// root
} else {
this.baseDir = graph.properties.baseDir || '/';
this.baseDir = options.baseDir || graph.properties.baseDir || '/';
}

@@ -116,3 +120,6 @@

// Initialize a Component Loader for the network
if (graph.properties.componentLoader) {
if (options.componentLoader) {
this.loader = options.componentLoader;
} else if (graph.properties.componentLoader) {
deprecated('Passing componentLoader via Graph properties is deprecated, pass via Network options instead');
this.loader = graph.properties.componentLoader;

@@ -122,2 +129,6 @@ } else {

}
// Enable Flowtrace for this network, when available
this.flowtraceName = null;
this.setFlowtrace(options.flowtrace || false, null);
}

@@ -151,3 +162,62 @@

traceEvent(event, payload) {
if (!this.flowtrace) {
return;
}
if (this.flowtraceName && this.flowtraceName !== this.flowtrace.mainGraph) {
// Let main graph log all events from subgraphs
return;
}
switch (event) {
case 'ip': {
let type = 'data';
if (payload.type === 'openBracket') {
type = 'begingroup';
} else if (payload.type === 'closeBracket') {
type = 'endgroup';
}
const src = payload.socket.from ? {
node: payload.socket.from.process.id,
port: payload.socket.from.port,
} : null;
const tgt = payload.socket.to ? {
node: payload.socket.to.process.id,
port: payload.socket.to.port,
} : null;
this.flowtrace.addNetworkPacket(
`network:${type}`,
src,
tgt,
this.flowtraceName,
{
subgraph: payload.subgraph,
group: payload.group,
datatype: payload.datatype,
schema: payload.schema,
data: payload.data,
},
);
break;
}
case 'start': {
this.flowtrace.addNetworkStarted(this.flowtraceName);
break;
}
case 'end': {
this.flowtrace.addNetworkStopped(this.flowtraceName);
break;
}
case 'error': {
this.flowtrace.addNetworkError(this.flowtraceName, payload);
break;
}
default: {
// No default handler
}
}
}
bufferedEmit(event, payload) {
// Add the event to Flowtrace immediately
this.traceEvent(event, payload);
// Errors get emitted immediately, like does network end

@@ -377,5 +447,10 @@ if (['icon', 'error', 'process-error', 'end'].includes(event)) {

if (!node.component.network) { return; }
if (!node.component.network) {
return;
}
node.component.network.setDebug(this.debug);
if (this.flowtrace) {
node.component.network.setFlowtrace(this.flowtrace, node.componentName, false);
}

@@ -396,3 +471,3 @@ const emitSub = (type, data) => {

}
return this.bufferedEmit(type, data);
this.bufferedEmit(type, data);
};

@@ -911,4 +986,27 @@

}
setFlowtrace(flowtrace, name = null, main = true) {
if (!flowtrace) {
this.flowtraceName = null;
this.flowtrace = null;
return;
}
if (this.flowtrace) {
// We already have a tracer
return;
}
this.flowtrace = flowtrace;
this.flowtraceName = name || this.graph.name;
this.flowtrace.addGraph(this.flowtraceName, this.graph, main);
Object.keys(this.processes).forEach((nodeId) => {
// Register existing subgraphs
const node = this.processes[nodeId];
if (!node.component.isSubgraph() || !node.component.network) {
return;
}
node.component.network.setFlowtrace(this.flowtrace, node.componentName, false);
});
}
}
module.exports = BaseNetwork;

@@ -26,3 +26,3 @@ // NoFlo - Flow-Based Programming for JavaScript

constructor(graph, options = {}) {
deprecated('noflo.Network construction is deprecated, use noflo.createNetwork');
deprecated('subscribeGraph: true is deprecated. Live-edit network graphs via the network methods instead');
super(graph, options);

@@ -29,0 +29,0 @@ }

@@ -17,7 +17,4 @@ /* eslint-disable

try {
// eslint-disable-next-line import/no-unresolved
// eslint-disable-next-line import/no-unresolved,import/no-extraneous-dependencies
CoffeeScript = require('coffeescript');
if (typeof CoffeeScript.register !== 'undefined') {
CoffeeScript.register();
}
} catch (e) {

@@ -318,4 +315,4 @@ // If there is no CoffeeScript compiler installed, we simply don't support compiling

const language = utils.guessLanguageFromFilename(c.path);
if (language === 'typescript') {
// We can't require a TypeScript module, go the setSource route
if (language === 'typescript' || language === 'coffeescript') {
// We can't require a module that requires transpilation, go the setSource route
fs.readFile(path.resolve(loader.baseDir, c.path), 'utf-8', (fsErr, source) => {

@@ -322,0 +319,0 @@ if (fsErr) {

@@ -31,12 +31,2 @@ // NoFlo - Flow-Based Programming for JavaScript

// ## Network interface
//
// [Network](../Network/) is used for running NoFlo graphs. The direct Network inteface is only
// provided for backwards compatibility purposes. Use `createNetwork` instead.
const {
Network,
} = require('./Network');
exports.Network = require('./LegacyNetwork').Network;
const { deprecated } = require('./Platform');
// ### Platform detection

@@ -87,3 +77,3 @@ //

//
// noflo.createNetwork(someGraph, function (err, network) {
// noflo.createNetwork(someGraph, {}, function (err, network) {
// console.log('Network is now running!');

@@ -93,6 +83,8 @@ // });

// 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
// third `delay` option. In this case you will have to handle connecting the graph and
// sending of IIPs manually.
//
// noflo.createNetwork(someGraph, function (err, network) {
// noflo.createNetwork(someGraph, {
// delay: true,
// }, function (err, network) {
// if (err) {

@@ -104,4 +96,4 @@ // throw err;

// console.log('Network is now running!');
// })
// }, true);
// });
// });
//

@@ -112,5 +104,10 @@ // ### Network options

//
// * `baseDir`: (default: cwd) Project base directory used for component loading
// * `componentLoader`: (default: NULL) NoFlo ComponentLoader instance to use for the
// network. New one will be instantiated for the baseDir if this is not given.
// * `delay`: (default: FALSE) Whether the network should be started later. Defaults to
// immediate execution
// * `subscribeGraph`: (default: TRUE) Whether the network should monitor the underlying
// * `flowtrace`: (default: NULL) Flowtrace instance to create a retroactive debugging
// trace of the network run.
// * `subscribeGraph`: (default: FALSE) Whether the network should monitor the underlying
// graph for changes

@@ -124,11 +121,7 @@ //

// network.
const { Network } = require('./Network');
const { Network: LegacyNetwork } = require('./LegacyNetwork');
const { deprecated } = require('./Platform');
exports.createNetwork = function createNetwork(graph, options, callback) {
if (typeof options === 'function') {
const opts = callback;
callback = options;
options = opts;
}
if (typeof options === 'boolean') {
options = { delay: options };
}
if (typeof options !== 'object') {

@@ -138,4 +131,3 @@ options = {};

if (typeof options.subscribeGraph === 'undefined') {
// Default to legacy network for backwards compatibility.
options.subscribeGraph = true;
options.subscribeGraph = false;
}

@@ -151,3 +143,3 @@ if (typeof callback !== 'function') {

// subscription is needed
const NetworkType = options.subscribeGraph ? exports.Network : Network;
const NetworkType = options.subscribeGraph ? LegacyNetwork : Network;
const network = new NetworkType(graph, options);

@@ -201,3 +193,3 @@

//
// noflo.loadFile('somefile.json', function (err, network) {
// noflo.loadFile('somefile.json', {}, function (err, network) {
// if (err) {

@@ -209,18 +201,10 @@ // throw err;

exports.loadFile = function loadFile(file, options, callback) {
if (!callback) {
callback = options;
options = null;
if (typeof callback !== 'function') {
deprecated('Calling noflo.loadFile without a callback is deprecated');
callback = (err) => {
if (err) { throw err; }
};
}
if (callback && (typeof options !== 'object')) {
options = { baseDir: options };
}
if (typeof options !== 'object') {
options = {};
}
if (!options.subscribeGraph) {
options.subscribeGraph = false;
}
exports.graph.loadFile(file, (err, net) => {
exports.graph.loadFile(file, (err, graph) => {
if (err) {

@@ -231,5 +215,5 @@ callback(err);

if (options.baseDir) {
net.properties.baseDir = options.baseDir;
graph.properties.baseDir = options.baseDir;
}
exports.createNetwork(net, options, callback);
exports.createNetwork(graph, options, callback);
});

@@ -236,0 +220,0 @@ };

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