UNPKG

noflo

Version:

Flow-Based Programming environment for JavaScript

159 lines (133 loc) 5.36 kB
utils = require '../Utils' fbpGraph = require 'fbp-graph' platform = require '../Platform' customLoader = checked: [] getModuleDependencies: (loader, dependencies, callback) -> unless dependencies?.length return callback null dependency = dependencies.shift() dependency = dependency.replace '/', '-' @getModuleComponents loader, dependency, (err) => @getModuleDependencies loader, dependencies, callback getModuleComponents: (loader, moduleName, callback) -> return callback() unless @checked.indexOf(moduleName) is -1 @checked.push moduleName try definition = require "/#{moduleName}/component.json" catch e if moduleName.substr(0, 1) is '/' and moduleName.length > 1 return @getModuleComponents loader, "noflo-#{moduleName.substr(1)}", callback return callback e return callback() unless definition.noflo return callback() unless definition.dependencies @getModuleDependencies loader, Object.keys(definition.dependencies), (err) -> return callback err if err prefix = loader.getModulePrefix definition.name if definition.noflo.icon loader.setLibraryIcon prefix, definition.noflo.icon if moduleName[0] is '/' moduleName = moduleName.substr 1 if definition.noflo.components for name, cPath of definition.noflo.components if cPath.indexOf('.coffee') isnt -1 cPath = cPath.replace '.coffee', '.js' if cPath.substr(0, 2) is './' cPath = cPath.substr 2 loader.registerComponent prefix, name, "/#{moduleName}/#{cPath}" if definition.noflo.graphs for name, cPath of definition.noflo.graphs def = require "/#{moduleName}/#{cPath}" loader.registerGraph prefix, name, def if definition.noflo.loader # Run a custom component loader loaderPath = "/#{moduleName}/#{definition.noflo.loader}" customLoader = require loaderPath loader.registerLoader customLoader, callback return do callback exports.register = (loader, callback) -> platform.deprecated 'Component.io is deprecated. Please make browser builds using webpack instead. grunt-noflo-browser provides a simple setup for this' customLoader.checked = [] # Start discovery from baseDir setTimeout -> customLoader.getModuleComponents loader, loader.baseDir, callback , 1 exports.dynamicLoad = (name, cPath, metadata, callback) -> try implementation = require cPath catch e callback e return if typeof implementation.getComponent is 'function' instance = implementation.getComponent metadata else if typeof implementation is 'function' instance = implementation metadata else callback new Error "Unable to instantiate #{cPath}" return instance.componentName = name if typeof name is 'string' callback null, instance exports.setSource = (loader, packageId, name, source, language, callback) -> if language is 'coffeescript' unless window.CoffeeScript return callback new Error 'CoffeeScript compiler not available' try source = CoffeeScript.compile source, bare: true catch e return callback e else if language in ['es6', 'es2015'] unless window.babel return callback new Error 'Babel compiler not available' try source = babel.transform(source).code catch e return callback e # We eval the contents to get a runnable component try # Modify require path for NoFlo since we're inside the NoFlo context source = source.replace "require('noflo')", "require('../NoFlo')" source = source.replace 'require("noflo")', 'require("../NoFlo")' # Eval so we can get a function implementation = eval "(function () { var exports = {}; #{source}; return exports; })()" catch e return callback e unless implementation or implementation.getComponent return callback new Error 'Provided source failed to create a runnable component' loader.registerComponent packageId, name, implementation, callback exports.getSource = (loader, name, callback) -> component = loader.components[name] unless component # Try an alias for componentName of loader.components if componentName.split('/')[1] is name component = loader.components[componentName] name = componentName break unless component return callback new Error "Component #{name} not installed" if typeof component isnt 'string' return callback new Error "Can't provide source for #{name}. Not a file" nameParts = name.split '/' if nameParts.length is 1 nameParts[1] = nameParts[0] nameParts[0] = '' if loader.isGraph component fbpGraph.graph.loadFile component, (err, graph) -> return callback err if err return callback new Error 'Unable to load graph' unless graph callback null, name: nameParts[1] library: nameParts[0] code: JSON.stringify graph.toJSON() language: 'json' return path = window.require.resolve component unless path return callback new Error "Component #{name} is not resolvable to a path" callback null, name: nameParts[1] library: nameParts[0] code: window.require.modules[path].toString() language: utils.guessLanguageFromFilename component