noflo
Version:
Flow-Based Programming environment for JavaScript
233 lines (232 loc) • 10.3 kB
JavaScript
;
// NoFlo - Flow-Based Programming for JavaScript
// (c) 2013-2018 Flowhub UG
// (c) 2011-2012 Henri Bergius, Nemein
// NoFlo may be freely distributed under the MIT license
//
// NoFlo is a Flow-Based Programming environment for JavaScript. This file provides the
// main entry point to the NoFlo network.
//
// Find out more about using NoFlo from <http://noflojs.org/documentation/>
Object.defineProperty(exports, "__esModule", { value: true });
exports.asComponent = exports.asPromise = exports.asCallback = exports.saveFile = exports.loadFile = exports.createNetwork = exports.IP = exports.internalSocket = exports.OutPort = exports.InPort = exports.OutPorts = exports.InPorts = exports.Component = exports.ComponentLoader = exports.isBrowser = exports.Journal = exports.journal = exports.Graph = exports.graph = void 0;
/* eslint-disable
no-param-reassign,
import/first
*/
// ## Main APIs
//
// ### Graph interface
//
// [fbp-graph](https://github.com/flowbased/fbp-graph) is used for instantiating FBP graph definitions.
const fbp_graph_1 = require("fbp-graph");
// ## Network instantiation
//
// This function handles instantiation of NoFlo networks from a Graph object. It creates
// the network, and then starts execution by sending the Initial Information Packets.
//
// const network = await noflo.createNetwork(someGraph, {});
// console.log('Network is now running!');
//
// It is also possible to instantiate a Network but delay its execution by giving the
// third `delay` option. In this case you will have to handle connecting the graph and
// sending of IIPs manually.
//
// noflo.createNetwork(someGraph, {
// delay: true,
// })
// .then((network) => network.connect())
// .then((network) => network.start())
// .then(() => {
// console.log('Network is now running!');
// });
//
// ### Network options
//
// It is possible to pass some options to control the behavior of network creation:
//
// * `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
// * `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
//
// Options can be passed as a second argument before the callback:
//
// noflo.createNetwork(someGraph, options, callback);
//
// The options object can also be used for setting ComponentLoader options in this
// network.
const Network_1 = require("./Network");
const LegacyNetwork_1 = require("./LegacyNetwork");
const Platform_1 = require("./Platform");
var fbp_graph_2 = require("fbp-graph");
Object.defineProperty(exports, "graph", { enumerable: true, get: function () { return fbp_graph_2.graph; } });
Object.defineProperty(exports, "Graph", { enumerable: true, get: function () { return fbp_graph_2.Graph; } });
Object.defineProperty(exports, "journal", { enumerable: true, get: function () { return fbp_graph_2.journal; } });
Object.defineProperty(exports, "Journal", { enumerable: true, get: function () { return fbp_graph_2.Journal; } });
// ### 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.
var Platform_2 = require("./Platform");
Object.defineProperty(exports, "isBrowser", { enumerable: true, get: function () { return Platform_2.isBrowser; } });
// ### Component Loader
//
// The [ComponentLoader](../ComponentLoader/) is responsible for finding and loading
// NoFlo components. Component Loader uses [fbp-manifest](https://github.com/flowbased/fbp-manifest)
// to find components and graphs by traversing the NPM dependency tree from a given root
// directory on the file system.
var ComponentLoader_1 = require("./ComponentLoader");
Object.defineProperty(exports, "ComponentLoader", { enumerable: true, get: function () { return ComponentLoader_1.ComponentLoader; } });
// ### Component baseclasses
//
// These baseclasses can be used for defining NoFlo components.
var Component_1 = require("./Component");
Object.defineProperty(exports, "Component", { enumerable: true, get: function () { return Component_1.Component; } });
// ### NoFlo ports
//
// These classes are used for instantiating ports on NoFlo components.
var Ports_1 = require("./Ports");
Object.defineProperty(exports, "InPorts", { enumerable: true, get: function () { return Ports_1.InPorts; } });
Object.defineProperty(exports, "OutPorts", { enumerable: true, get: function () { return Ports_1.OutPorts; } });
var InPort_1 = require("./InPort");
Object.defineProperty(exports, "InPort", { enumerable: true, get: function () { return InPort_1.default; } });
var OutPort_1 = require("./OutPort");
Object.defineProperty(exports, "OutPort", { enumerable: true, get: function () { return OutPort_1.default; } });
// ### NoFlo sockets
//
// The NoFlo [internalSocket](InternalSocket.html) is used for connecting ports of
// different components together in a network.
const internalSocket = require("./InternalSocket");
exports.internalSocket = internalSocket;
// ### Information Packets
//
// NoFlo Information Packets are defined as "IP" objects.
var IP_1 = require("./IP");
Object.defineProperty(exports, "IP", { enumerable: true, get: function () { return IP_1.default; } });
/**
* @callback NetworkCallback
* @param {Error | null} err
* @param {Network|LegacyNetwork} [network]
*/
/**
* @typedef CreateNetworkOptions
* @property {boolean} [subscribeGraph] - Whether the Network should monitor the graph
* @property {boolean} [delay] - Whether the Network should be started later
*/
/**
* @typedef { CreateNetworkOptions & import("./BaseNetwork").NetworkOptions} NetworkOptions
*/
/**
* @param {import("fbp-graph").Graph} graphInstance - Graph definition to build a Network for
* @param {NetworkOptions} options - Network options
* @param {NetworkCallback} [callback] - Legacy callback for the created Network
* @returns {Promise<Network|LegacyNetwork>}
*/
function createNetwork(graphInstance, options, callback) {
if (typeof options !== 'object') {
options = {};
}
if (typeof options.subscribeGraph === 'undefined') {
options.subscribeGraph = false;
}
// Choose legacy or modern network based on whether graph
// subscription is needed
const NetworkType = options.subscribeGraph ? LegacyNetwork_1.LegacyNetwork : Network_1.Network;
const network = new NetworkType(graphInstance, options);
// Ensure components are loaded before continuing
const promise = network.loader.listComponents()
.then(() => {
if (options.delay) {
// In case of delayed execution we don't wire it up
return Promise.resolve(network);
}
const connected = /** @type {Promise<Network|LegacyNetwork>} */ (network.connect());
return connected.then(() => network.start());
});
if (callback) {
Platform_1.deprecated('Providing a callback to NoFlo.createNetwork is deprecated, use Promises');
promise.then((nw) => {
callback(null, nw);
}, callback);
}
return promise;
}
exports.createNetwork = createNetwork;
// ### Starting a network from a file
//
// It is also possible to start a NoFlo network by giving it a path to a `.json` or `.fbp` network
// definition file.
//
// noflo.loadFile('somefile.json', {})
// .then((network) => {
// console.log('Network is now running!');
// });
/**
* @param {string} file
* @param {NetworkOptions} options - Network options
* @param {any} [callback] - Legacy callback
* @returning {Promise<Network>}
*/
function loadFile(file, options, callback) {
const promise = fbp_graph_1.graph.loadFile(file)
.then((graphInstance) => createNetwork(graphInstance, options));
if (callback) {
Platform_1.deprecated('Providing a callback to NoFlo.loadFile is deprecated, use Promises');
promise.then((network) => {
callback(null, network);
}, callback);
}
return promise;
}
exports.loadFile = loadFile;
// ### Saving a network definition
//
// NoFlo graph files can be saved back into the filesystem with this method.
/**
* @param {graph.Graph} graphInstance
* @param {string} file
* @param {any} [callback] - Legacy callback
* @returning {Promise<string>}
*/
function saveFile(graphInstance, file, callback) {
return graphInstance.save(file, callback);
}
exports.saveFile = saveFile;
// ## Embedding NoFlo in existing JavaScript code
//
// The `asCallback` helper provides an interface to wrap NoFlo components
// or graphs into existing JavaScript code.
//
// // Produce an asynchronous function wrapping a NoFlo graph
// var wrapped = noflo.asCallback('myproject/MyGraph');
//
// // Call the function, providing input data and a callback for output data
// wrapped({
// in: 'data'
// }, function (err, results) {
// // Do something with results
// });
//
var AsCallback_1 = require("./AsCallback");
Object.defineProperty(exports, "asCallback", { enumerable: true, get: function () { return AsCallback_1.asCallback; } });
Object.defineProperty(exports, "asPromise", { enumerable: true, get: function () { return AsCallback_1.asPromise; } });
// ## Generating components from JavaScript functions
//
// The `asComponent` helper makes it easy to expose a JavaScript function as a
// NoFlo component. All input arguments become input ports, and the function's
// result will be sent to either `out` or `error` port.
//
// exports.getComponent = function () {
// return noflo.asComponent(Math.random, {
// description: 'Generate a random number',
// });
// };
//
var AsComponent_1 = require("./AsComponent");
Object.defineProperty(exports, "asComponent", { enumerable: true, get: function () { return AsComponent_1.asComponent; } });