<commit_before>#     NoFlo - Flow-Based Programming for JavaScript
#     (c) 2013-2014 TheGrid (Rituwall Inc.)
#     (c) 2013 <NAME>, Nemein
#     NoFlo may be freely distributed under the MIT license
#
# This is the Node.js version of the ComponentLoader.

reader = require 'read-installed'
{_} = require 'underscore'
path = require 'path'
fs = require 'fs'
loader = require '../ComponentLoader'
internalSocket = require '../InternalSocket'
utils = require '../Utils'
nofloGraph = require '../Graph'

# We allow components to be un-compiled CoffeeScript
CoffeeScript = require 'coffee-script'
if typeof CoffeeScript.register != 'undefined'
    CoffeeScript.register()

# Disable NPM logging in normal NoFlo operation
log = require 'npmlog'
log.pause()

class ComponentLoader extends loader.ComponentLoader
  getModuleComponents: (moduleDef, callback) ->
    components = {}
    @checked.push moduleDef.name

    depCount = _.keys(moduleDef.dependencies).length
    done = _.after depCount + 1, =>
      callback components

    # Handle sub-modules
    _.each moduleDef.dependencies, (def) =>
      return done() unless def.name?
      return done() unless @checked.indexOf(def.name) is -1
      @getModuleComponents def, (depComponents) ->
        return done() if _.isEmpty depComponents
        components[name] = cPath for name, cPath of depComponents
        done()

    # No need for further processing for non-NoFlo projects
    return done() unless moduleDef.noflo

    checkOwn = (def) =>
      # Handle own components
      prefix = @getModulePrefix def.name

      # See if the library has a default icon
      if def.noflo.icon
        @libraryIcons[prefix] = def.noflo.icon

      if def.noflo.components
        for name, cPath of def.noflo.components
          @registerComponent prefix, name, path.resolve def.realPath, cPath
      if moduleDef.noflo.graphs
        for name, gPath of def.noflo.graphs
          @registerGraph prefix, name, path.resolve def.realPath, gPath
      if def.noflo.loader
        # Run a custom component loader
        loader = require path.resolve def.realPath, def.noflo.loader
        @registerLoader loader, done
      else
        done()

    # Normally we can rely on the module data we get from read-installed, but in
    # case cache has been cleared, we must re-read the file
    unless @revalidate
      return checkOwn moduleDef
    @readPackageFile "#{moduleDef.realPath}/package.json", (err, data) ->
      return done() if err
      checkOwn data

  getCoreComponents: (callback) ->
    # Read core components
    # TODO: These components should eventually be migrated to modules too
    corePath = path.resolve __dirname, '../../src/components'
    if path.extname(__filename) is '.coffee'
      # Handle the non-compiled version of ComponentLoader for unit tests
      corePath = path.resolve __dirname, '../../components'

    fs.readdir corePath, (err, components) =>
      coreComponents = {}
      return callback coreComponents if err
      for component in components
        continue if component.substr(0, 1) is '.'
        [componentName, componentExtension] = component.split '.'
        continue unless componentExtension is 'coffee'
        coreComponents[componentName] = "#{corePath}/#{component}"
      callback coreComponents

  listComponents: (callback) ->
    if @processing
      @once 'ready', =>
        callback @components
      return
    return callback @components if @components

    @ready = false
    @processing = true
    @components = {}
    done = _.after 2, =>
      @ready = true
      @processing = false
      @emit 'ready', true
      callback @components if callback

    @getCoreComponents (coreComponents) =>
      @components[name] = cPath for name, cPath of coreComponents
      done()

    reader @baseDir, (err, data) =>
      return done() if err
      @getModuleComponents data, (components) =>
        @components[name] = cPath for name, cPath of components
        done()

  getPackagePath: (packageId, callback) ->
    found = null
    seen = []
    find = (packageData) ->
      return if seen.indexOf(packageData.name) isnt -1
      seen.push packageData.name
      if packageData.name is packageId
        found = path.resolve packageData.realPath, './package.json'
        return
      _.each packageData.dependencies, find
    reader @baseDir, (err, data) ->
      return callback err if err
      find data
      return callback null, found

  setSource: (packageId, name, source, language, callback) ->
    _eval = require 'eval'
    if language is 'coffeescript'<commit_msg>ComponentLoader: Load components on-demand in setSource also on node.js<commit_after>#     NoFlo - Flow-Based Programming for JavaScript
#     (c) 2013-2014 TheGrid (Rituwall Inc.)
#     (c) 2013 <NAME>, Nemein
#     NoFlo may be freely distributed under the MIT license
#
# This is the Node.js version of the ComponentLoader.

reader = require 'read-installed'
{_} = require 'underscore'
path = require 'path'
fs = require 'fs'
loader = require '../ComponentLoader'
internalSocket = require '../InternalSocket'
utils = require '../Utils'
nofloGraph = require '../Graph'

# We allow components to be un-compiled CoffeeScript
CoffeeScript = require 'coffee-script'
if typeof CoffeeScript.register != 'undefined'
    CoffeeScript.register()

# Disable NPM logging in normal NoFlo operation
log = require 'npmlog'
log.pause()

class ComponentLoader extends loader.ComponentLoader
  getModuleComponents: (moduleDef, callback) ->
    components = {}
    @checked.push moduleDef.name

    depCount = _.keys(moduleDef.dependencies).length
    done = _.after depCount + 1, =>
      callback components

    # Handle sub-modules
    _.each moduleDef.dependencies, (def) =>
      return done() unless def.name?
      return done() unless @checked.indexOf(def.name) is -1
      @getModuleComponents def, (depComponents) ->
        return done() if _.isEmpty depComponents
        components[name] = cPath for name, cPath of depComponents
        done()

    # No need for further processing for non-NoFlo projects
    return done() unless moduleDef.noflo

    checkOwn = (def) =>
      # Handle own components
      prefix = @getModulePrefix def.name

      # See if the library has a default icon
      if def.noflo.icon
        @libraryIcons[prefix] = def.noflo.icon

      if def.noflo.components
        for name, cPath of def.noflo.components
          @registerComponent prefix, name, path.resolve def.realPath, cPath
      if moduleDef.noflo.graphs
        for name, gPath of def.noflo.graphs
          @registerGraph prefix, name, path.resolve def.realPath, gPath
      if def.noflo.loader
        # Run a custom component loader
        loader = require path.resolve def.realPath, def.noflo.loader
        @registerLoader loader, done
      else
        done()

    # Normally we can rely on the module data we get from read-installed, but in
    # case cache has been cleared, we must re-read the file
    unless @revalidate
      return checkOwn moduleDef
    @readPackageFile "#{moduleDef.realPath}/package.json", (err, data) ->
      return done() if err
      checkOwn data

  getCoreComponents: (callback) ->
    # Read core components
    # TODO: These components should eventually be migrated to modules too
    corePath = path.resolve __dirname, '../../src/components'
    if path.extname(__filename) is '.coffee'
      # Handle the non-compiled version of ComponentLoader for unit tests
      corePath = path.resolve __dirname, '../../components'

    fs.readdir corePath, (err, components) =>
      coreComponents = {}
      return callback coreComponents if err
      for component in components
        continue if component.substr(0, 1) is '.'
        [componentName, componentExtension] = component.split '.'
        continue unless componentExtension is 'coffee'
        coreComponents[componentName] = "#{corePath}/#{component}"
      callback coreComponents

  listComponents: (callback) ->
    if @processing
      @once 'ready', =>
        callback @components
      return
    return callback @components if @components

    @ready = false
    @processing = true
    @components = {}
    done = _.after 2, =>
      @ready = true
      @processing = false
      @emit 'ready', true
      callback @components if callback

    @getCoreComponents (coreComponents) =>
      @components[name] = cPath for name, cPath of coreComponents
      done()

    reader @baseDir, (err, data) =>
      return done() if err
      @getModuleComponents data, (components) =>
        @components[name] = cPath for name, cPath of components
        done()

  getPackagePath: (packageId, callback) ->
    found = null
    seen = []
    find = (packageData) ->
      return if seen.indexOf(packageData.name) isnt -1
      seen.push packageData.name
      if packageData.name is packageId
        found = path.resolve packageData.realPath, './package.json'
        return
      _.each packageData.dependencies, find
    reader @baseDir, (err, data) ->
      return callback err if err
      find data
      return callback null, found

  setSource: (packageId, name, source, language, callback) ->
    unless @ready
      @listComponents =>
        @setSource packageId, name, source, language, callback
      return

    _eval = require 'eval'
    if language is 'coffeescript'
{'fraction_non_alphanumeric': 0.09372331340734415, 'fraction_numerical': 0.003842869342442357, 'mean_word_length': 2.8256431196406697, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5434650', 'n_tokens_mistral': 2603, 'n_tokens_neox': 2518, 'n_words': 873}