UNPKG

noflo

Version:

Flow-Based Programming environment for JavaScript

233 lines (232 loc) 10.3 kB
"use strict"; // 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; } });