noflo
Version:
Flow-Based Programming environment for JavaScript
209 lines (174 loc) • 6.49 kB
text/coffeescript
# NoFlo - Flow-Based Programming for JavaScript
# (c) 2013-2017 Flowhub UG
# (c) 2013 Henri Bergius, Nemein
# NoFlo may be freely distributed under the MIT license
#
# This is the browser version of the ComponentLoader.
internalSocket = require './InternalSocket'
fbpGraph = require 'fbp-graph'
{EventEmitter} = require 'events'
registerLoader = require './loader/register'
class ComponentLoader extends EventEmitter
constructor: (, = {}) ->
= null
= {}
= false
= false
0 if typeof is 'function'
getModulePrefix: (name) ->
return '' unless name
return '' if name is 'noflo'
name = name.replace /\@[a-z\-]+\//, '' if name[0] is '@'
name.replace 'noflo-', ''
listComponents: (callback) ->
if
'ready', =>
callback null,
return
return callback null, if
= false
= true
= {}
registerLoader.register @, (err) =>
if err
return callback err if callback
throw err
= false
= true
'ready', true
callback null, if callback
return
load: (name, callback, metadata) ->
unless
(err) =>
return callback err if err
name, callback, metadata
return
component = [name]
unless component
# Try an alias
for componentName of
if componentName.split('/')[1] is name
component = [componentName]
break
unless component
# Failure to load
callback new Error "Component #{name} not available with base #{@baseDir}"
return
if component
if typeof process isnt 'undefined' and process.execPath and process.execPath.indexOf('node') isnt -1
# nextTick is faster on Node.js
process.nextTick =>
name, component, callback, metadata
else
setTimeout =>
name, component, callback, metadata
, 0
return
name, component, metadata, (err, instance) =>
return callback err if err
if not instance
callback new Error "Component #{name} could not be loaded."
return
instance.baseDir = if name is 'Graph'
instance.componentName = name if typeof name is 'string'
name, instance
callback null, instance
# Creates an instance of a component.
createComponent: (name, component, metadata, callback) ->
implementation = component
unless implementation
return callback new Error "Component #{name} not available"
# If a string was specified, attempt to `require` it.
if typeof implementation is 'string'
if typeof registerLoader.dynamicLoad is 'function'
registerLoader.dynamicLoad name, implementation, metadata, callback
return
return callback Error "Dynamic loading of #{implementation} for component #{name} not available on this platform."
# Attempt to create the component instance using the `getComponent` method.
if typeof implementation.getComponent is 'function'
instance = implementation.getComponent metadata
# Attempt to create a component using a factory function.
else if typeof implementation is 'function'
instance = implementation metadata
else
callback new Error "Invalid type #{typeof(implementation)} for component #{name}."
return
callback null, instance
isGraph: (cPath) ->
# Live graph instance
return true if typeof cPath is 'object' and cPath instanceof fbpGraph.Graph
# Graph JSON definition
return true if typeof cPath is 'object' and cPath.processes and cPath.connections
return false unless typeof cPath is 'string'
# Graph file path
cPath.indexOf('.fbp') isnt -1 or cPath.indexOf('.json') isnt -1
loadGraph: (name, component, callback, metadata) ->
name, ['Graph'], metadata, (err, graph) =>
return callback err if err
graphSocket = internalSocket.createSocket()
graph.loader = @
graph.baseDir =
graph.inPorts.remove 'graph'
graph.setGraph component, (err) =>
return callback err if err
name, graph
callback null, graph
return
return
setIcon: (name, instance) ->
# See if component has an icon
return if not instance.getIcon or instance.getIcon()
# See if library has an icon
[library, componentName] = name.split '/'
if componentName and library
instance.setIcon library
return
# See if instance is a subgraph
if instance.isSubgraph()
instance.setIcon 'sitemap'
return
instance.setIcon 'square'
return
getLibraryIcon: (prefix) ->
if [prefix]
return [prefix]
return null
setLibraryIcon: (prefix, icon) ->
[prefix] = icon
normalizeName: (packageId, name) ->
prefix = packageId
fullName = "#{prefix}/#{name}"
fullName = name unless packageId
fullName
registerComponent: (packageId, name, cPath, callback) ->
fullName = packageId, name
[fullName] = cPath
do callback if callback
registerGraph: (packageId, name, gPath, callback) ->
packageId, name, gPath, callback
registerLoader: (loader, callback) ->
loader @, callback
setSource: (packageId, name, source, language, callback) ->
unless registerLoader.setSource
return callback new Error 'setSource not allowed'
unless
(err) =>
return callback err if err
packageId, name, source, language, callback
return
registerLoader.setSource @, packageId, name, source, language, callback
getSource: (name, callback) ->
unless registerLoader.getSource
return callback new Error 'getSource not allowed'
unless
(err) =>
return callback err if err
name, callback
return
registerLoader.getSource @, name, callback
clear: ->
= null
= false
= false
exports.ComponentLoader = ComponentLoader