UNPKG

noflo

Version:

Flow-Based Programming environment for JavaScript

295 lines (270 loc) 9.62 kB
(function() { var CoffeeScript, ComponentLoader, babel, fs, internalSocket, loader, manifest, nofloGraph, path, utils, _, __hasProp = {}.hasOwnProperty, __extends = 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; }; _ = require('underscore')._; path = require('path'); fs = require('fs'); loader = require('../ComponentLoader'); internalSocket = require('../InternalSocket'); utils = require('../Utils'); nofloGraph = require('../Graph'); manifest = require('fbp-manifest'); CoffeeScript = require('coffee-script'); if (typeof CoffeeScript.register !== 'undefined') { CoffeeScript.register(); } babel = require('babel-core'); ComponentLoader = (function(_super) { __extends(ComponentLoader, _super); function ComponentLoader() { return ComponentLoader.__super__.constructor.apply(this, arguments); } ComponentLoader.prototype.writeCache = function(options, modules, callback) { var filePath; filePath = path.resolve(this.baseDir, options.manifest); return fs.writeFile(filePath, JSON.stringify(modules, null, 2), { encoding: 'utf-8' }, callback); }; ComponentLoader.prototype.readCache = function(options, callback) { options.discover = false; return manifest.load.load(this.baseDir, options, callback); }; ComponentLoader.prototype.prepareManifestOptions = function() { var options; options = {}; options.runtimes = this.options.runtimes || []; if (options.runtimes.indexOf('noflo') === -1) { options.runtimes.push('noflo'); } options.recursive = typeof this.options.recursive === 'undefined' ? true : this.options.recursive; if (!options.manifest) { options.manifest = 'fbp.json'; } return options; }; ComponentLoader.prototype.readModules = function(modules, callback) { var c, compatible, done, loaderPath, m, _i, _j, _len, _len1, _ref, _ref1; compatible = modules.filter(function(m) { var _ref; return (_ref = m.runtime) === 'noflo' || _ref === 'noflo-nodejs'; }); for (_i = 0, _len = compatible.length; _i < _len; _i++) { m = compatible[_i]; if (m.icon) { this.libraryIcons[m.name] = m.icon; } if ((_ref = m.noflo) != null ? _ref.loader : void 0) { loaderPath = path.resolve(this.baseDir, m.base, m.noflo.loader); this.componentLoaders.push(loaderPath); } _ref1 = m.components; for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { c = _ref1[_j]; this.components["" + m.name + "/" + c.name] = path.resolve(this.baseDir, c.path); } } if (path.extname(__filename) === '.js') { this.components.Graph = path.resolve(__dirname, '../../components/Graph.js'); } else { this.components.Graph = path.resolve(__dirname, '../../components/Graph.coffee'); } if (!this.componentLoaders.length) { return callback(null); } done = _.after(this.componentLoaders.length, callback); return this.componentLoaders.forEach((function(_this) { return function(loaderPath) { loader = require(loaderPath); return _this.registerLoader(loader, function(err) { if (err) { return callback(err); } return done(null); }); }; })(this)); }; ComponentLoader.prototype.listComponents = function(callback) { var manifestOptions; 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; manifestOptions = this.prepareManifestOptions(); if (this.options.cache && !this.failedCache) { this.readCache(manifestOptions, (function(_this) { return function(err, modules) { if (err) { _this.failedCache = true; _this.processing = false; if (!_this.options.discover) { return callback(err); } return _this.listComponents(callback); } _this.components = {}; return _this.readModules(modules.modules, function(err) { _this.ready = true; _this.processing = false; _this.emit('ready', true); if (callback) { return callback(null, _this.components); } }); }; })(this)); return; } this.components = {}; return manifest.list.list(this.baseDir, manifestOptions, (function(_this) { return function(err, modules) { if (err) { return callback(err); } return _this.readModules(modules, function(err) { _this.processing = false; if (err) { return callback(err); } _this.ready = true; _this.emit('ready', true); if (!_this.options.cache) { return callback(null, _this.components); } return _this.writeCache(manifestOptions, modules, function(err) { if (err) { return callback(err); } return callback(null, _this.components); }); }); }; })(this)); }; ComponentLoader.prototype.setSource = function(packageId, name, source, language, callback) { var Module, e, implementation, moduleImpl, modulePath; 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; } Module = require('module'); if (language === 'coffeescript') { try { source = CoffeeScript.compile(source, { bare: true }); } catch (_error) { e = _error; return callback(e); } } else if (language === 'es6' || language === 'es2015') { try { source = babel.transform(source).code; } catch (_error) { e = _error; return callback(e); } } try { modulePath = path.resolve(this.baseDir, "./components/" + name + ".js"); moduleImpl = new Module(modulePath, module); moduleImpl.paths = Module._nodeModulePaths(path.dirname(modulePath)); moduleImpl.filename = modulePath; moduleImpl._compile(source, modulePath); implementation = moduleImpl.exports; } catch (_error) { e = _error; return callback(e); } if (!(implementation || implementation.getComponent)) { return callback(new Error('Provided source failed to create a runnable component')); } return this.registerComponent(packageId, name, implementation, function() { return callback(null); }); }; ComponentLoader.prototype.getSource = function(name, callback) { var component, componentName, nameParts; if (!this.ready) { this.listComponents((function(_this) { return function(err) { if (err) { return callback(err); } return _this.getSource(name, callback); }; })(this)); return; } component = this.components[name]; if (!component) { for (componentName in this.components) { if (componentName.split('/')[1] === name) { component = this.components[componentName]; name = componentName; break; } } if (!component) { return callback(new Error("Component " + name + " not installed")); } } if (typeof component !== 'string') { return callback(new Error("Can't provide source for " + name + ". Not a file")); } nameParts = name.split('/'); if (nameParts.length === 1) { nameParts[1] = nameParts[0]; nameParts[0] = ''; } if (this.isGraph(component)) { nofloGraph.loadFile(component, function(err, graph) { if (err) { return callback(err); } if (!graph) { return callback(new Error('Unable to load graph')); } return callback(null, { name: nameParts[1], library: nameParts[0], code: JSON.stringify(graph.toJSON()), language: 'json' }); }); return; } return fs.readFile(component, 'utf-8', function(err, code) { if (err) { return callback(err); } return callback(null, { name: nameParts[1], library: nameParts[0], language: utils.guessLanguageFromFilename(component), code: code }); }); }; return ComponentLoader; })(loader.ComponentLoader); exports.ComponentLoader = ComponentLoader; }).call(this);