UNPKG

noflo

Version:

Flow-Based Programming environment for JavaScript

301 lines (274 loc) 9.59 kB
(function() { var ComponentLoader, EventEmitter, fbpGraph, internalSocket, registerLoader, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty; internalSocket = require('./InternalSocket'); fbpGraph = require('fbp-graph'); EventEmitter = require('events').EventEmitter; registerLoader = require('./loader/register'); ComponentLoader = (function(superClass) { extend(ComponentLoader, superClass); function ComponentLoader(baseDir, options) { this.baseDir = baseDir; this.options = options != null ? options : {}; this.components = null; this.libraryIcons = {}; this.processing = false; this.ready = false; if (typeof this.setMaxListeners === 'function') { this.setMaxListeners(0); } } ComponentLoader.prototype.getModulePrefix = function(name) { if (!name) { return ''; } if (name === 'noflo') { return ''; } if (name[0] === '@') { name = name.replace(/\@[a-z\-]+\//, ''); } return name.replace('noflo-', ''); }; ComponentLoader.prototype.listComponents = function(callback) { if (this.processing) { this.once('ready', (function(_this) { return function() { return callback(null, _this.components); }; })(this)); return; } if (this.components) { return callback(null, this.components); } this.ready = false; this.processing = true; this.components = {}; registerLoader.register(this, (function(_this) { return function(err) { if (err) { if (callback) { return callback(err); } throw err; } _this.processing = false; _this.ready = true; _this.emit('ready', true); if (callback) { return callback(null, _this.components); } }; })(this)); }; ComponentLoader.prototype.load = function(name, callback, metadata) { var component, componentName; if (!this.ready) { this.listComponents((function(_this) { return function(err) { if (err) { return callback(err); } return _this.load(name, callback, metadata); }; })(this)); return; } component = this.components[name]; if (!component) { for (componentName in this.components) { if (componentName.split('/')[1] === name) { component = this.components[componentName]; break; } } if (!component) { callback(new Error("Component " + name + " not available with base " + this.baseDir)); return; } } if (this.isGraph(component)) { if (typeof process !== 'undefined' && process.execPath && process.execPath.indexOf('node') !== -1) { process.nextTick((function(_this) { return function() { return _this.loadGraph(name, component, callback, metadata); }; })(this)); } else { setTimeout((function(_this) { return function() { return _this.loadGraph(name, component, callback, metadata); }; })(this), 0); } return; } return this.createComponent(name, component, metadata, (function(_this) { return function(err, instance) { if (err) { return callback(err); } if (!instance) { callback(new Error("Component " + name + " could not be loaded.")); return; } if (name === 'Graph') { instance.baseDir = _this.baseDir; } if (typeof name === 'string') { instance.componentName = name; } _this.setIcon(name, instance); return callback(null, instance); }; })(this)); }; ComponentLoader.prototype.createComponent = function(name, component, metadata, callback) { var implementation, instance; implementation = component; if (!implementation) { return callback(new Error("Component " + name + " not available")); } if (typeof implementation === 'string') { if (typeof registerLoader.dynamicLoad === 'function') { registerLoader.dynamicLoad(name, implementation, metadata, callback); return; } return callback(Error("Dynamic loading of " + implementation + " for component " + name + " not available on this platform.")); } if (typeof implementation.getComponent === 'function') { instance = implementation.getComponent(metadata); } else if (typeof implementation === 'function') { instance = implementation(metadata); } else { callback(new Error("Invalid type " + (typeof implementation) + " for component " + name + ".")); return; } return callback(null, instance); }; ComponentLoader.prototype.isGraph = function(cPath) { if (typeof cPath === 'object' && cPath instanceof fbpGraph.Graph) { return true; } if (typeof cPath === 'object' && cPath.processes && cPath.connections) { return true; } if (typeof cPath !== 'string') { return false; } return cPath.indexOf('.fbp') !== -1 || cPath.indexOf('.json') !== -1; }; ComponentLoader.prototype.loadGraph = function(name, component, callback, metadata) { this.createComponent(name, this.components['Graph'], metadata, (function(_this) { return function(err, graph) { var graphSocket; if (err) { return callback(err); } graphSocket = internalSocket.createSocket(); graph.loader = _this; graph.baseDir = _this.baseDir; graph.inPorts.remove('graph'); graph.setGraph(component, function(err) { if (err) { return callback(err); } _this.setIcon(name, graph); return callback(null, graph); }); }; })(this)); }; ComponentLoader.prototype.setIcon = function(name, instance) { var componentName, library, ref; if (!instance.getIcon || instance.getIcon()) { return; } ref = name.split('/'), library = ref[0], componentName = ref[1]; if (componentName && this.getLibraryIcon(library)) { instance.setIcon(this.getLibraryIcon(library)); return; } if (instance.isSubgraph()) { instance.setIcon('sitemap'); return; } instance.setIcon('square'); }; ComponentLoader.prototype.getLibraryIcon = function(prefix) { if (this.libraryIcons[prefix]) { return this.libraryIcons[prefix]; } return null; }; ComponentLoader.prototype.setLibraryIcon = function(prefix, icon) { return this.libraryIcons[prefix] = icon; }; ComponentLoader.prototype.normalizeName = function(packageId, name) { var fullName, prefix; prefix = this.getModulePrefix(packageId); fullName = prefix + "/" + name; if (!packageId) { fullName = name; } return fullName; }; ComponentLoader.prototype.registerComponent = function(packageId, name, cPath, callback) { var fullName; fullName = this.normalizeName(packageId, name); this.components[fullName] = cPath; if (callback) { return callback(); } }; ComponentLoader.prototype.registerGraph = function(packageId, name, gPath, callback) { return this.registerComponent(packageId, name, gPath, callback); }; ComponentLoader.prototype.registerLoader = function(loader, callback) { return loader(this, callback); }; ComponentLoader.prototype.setSource = function(packageId, name, source, language, callback) { if (!registerLoader.setSource) { return callback(new Error('setSource not allowed')); } if (!this.ready) { this.listComponents((function(_this) { return function(err) { if (err) { return callback(err); } return _this.setSource(packageId, name, source, language, callback); }; })(this)); return; } return registerLoader.setSource(this, packageId, name, source, language, callback); }; ComponentLoader.prototype.getSource = function(name, callback) { if (!registerLoader.getSource) { return callback(new Error('getSource not allowed')); } if (!this.ready) { this.listComponents((function(_this) { return function(err) { if (err) { return callback(err); } return _this.getSource(name, callback); }; })(this)); return; } return registerLoader.getSource(this, name, callback); }; ComponentLoader.prototype.clear = function() { this.components = null; this.ready = false; return this.processing = false; }; return ComponentLoader; })(EventEmitter); exports.ComponentLoader = ComponentLoader; }).call(this);