Comparing version 1.2.7 to 1.3.0
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 @@ |
@@ -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 @@ }; |
796160
5
21945
26
99
- Removedcoffeescript@^2.2.1
- Removedcoffeescript@2.7.0(transitive)
Updatedfbp-graph@^0.6.2