<commit_before>'use strict';

var fs = require('fs')
  , url = require('url')
  , path = require('path')
  , fuse = require('fusing')
  , async = require('async')
  , request = require('request')
  , schedule = require('node-schedule')
  , debug = require('debug')('npm-probe');

//
// Base path for all default probes.
//
var base = path.join(__dirname, 'probes')
  , registries = require('./registries');

/**
 * Collector instance, can be provided with following options.
 *  - probes {Array}: probes to use
 *  - cache {Object}: cache instance on which set(key, value, ttl) can be called
 *  - silent {Boolean}: if true do not aquire data
 *
 * @constructor
 * @param {Object} options
 * @api public
 */
function Collector(options) {
  this.fuse();

  //
  // Probes will be stored in probe list. Cache is not required, but if available
  // all data will be stored against the provided cache layer.
  //
  this.writable('feed');
  this.writable('probes', []);
  this.readable('options', options || {});
  this.readable('cache', this.options.cache || null);

  //
  // Add optional error event listener provided via options.
  //
  if (this.options.error) this.on('error', this.options.error);
  this.initialize();
}

//
// Add EventEmitter capacities.
//
fuse(Collector, require('events').EventEmitter);

/**
 * Register a probe to be used against the known registries.
 *
 * @param {Object} probe Valid probe object having name, spec and execute as keys.
 * @returns {Array} List of probes that can be added to the stack.
 * @api public
 */
Collector.readable('use', function use(Probe) {
  var collector = this
    , probe;

  //
  // Any provided probe should have a valid name, specification and function to
  // execute. Simply ignore probes which are invalid.
  //
  probe = new Probe(collector);
  if (!probe.name || !probe.spec || 'function' !== typeof probe.execute) return;

  return probe.list.map(function map(endpoint) {
    debug('[npm-probe] added probe %s for registry: %s', probe.name, endpoint);
    collector.emit('probe::scheduled', probe.name, Date.now());

    return schedule.scheduleJob(probe.name, probe.spec, function execute() {
      probe.execute(registries[endpoint], collector.expose(probe, endpoint));
    });
  });
});

/**
 * Emit `ran` events per registered probe, provide proper name and data.
 *
 * @param {Object} probe details of probe to be executed
 * @param {Object} endpoint name of the endpoint, e.g. nodejitsu
 * @returns {Function} callback to be called
 * @api private
 */
Collector.readable('expose', function expose(probe, registry) {
  var start = Date.now()
    , collector = this;

  debug('[npm-probe] provide callback for probe: %s at %s', probe.name, start);
  return function ran(error, data) {
    var end = Date.now()
      , clone;

    if (error) {
      debug('[npm-probe] emit `error` for probe: %s/%s at %s', registry, probe.name, end);
      return collector.emit('probe::error', error);
    }

    data = {
      name: probe.name,
      registry: registry,
      results: data,
      start: start,
      end: end,
      duration: end - start
    };

    //
    // Clone before emitting, so external listeners cannot polute data storage.
    //
    clone = JSON.parse(JSON.stringify(data));
    collector.emit('probe::ran', null, clone);
    collector.emit('probe::ran::' + probe.name, null, clone);
    debug('[npm-probe] emit `ran` for probe: %s at %s', probe.name, end);

    //
    // Optionally cache the results in provided cache layer.<commit_msg>[fix] use clone from the instance<commit_after>'use strict';

var fs = require('fs')
  , url = require('url')
  , path = require('path')
  , fuse = require('fusing')
  , async = require('async')
  , request = require('request')
  , schedule = require('node-schedule')
  , debug = require('debug')('npm-probe');

//
// Base path for all default probes.
//
var base = path.join(__dirname, 'probes')
  , registries = require('./registries');

/**
 * Collector instance, can be provided with following options.
 *  - probes {Array}: probes to use
 *  - cache {Object}: cache instance on which set(key, value, ttl) can be called
 *  - silent {Boolean}: if true do not aquire data
 *
 * @constructor
 * @param {Object} options
 * @api public
 */
function Collector(options) {
  this.fuse();

  //
  // Probes will be stored in probe list. Cache is not required, but if available
  // all data will be stored against the provided cache layer.
  //
  this.writable('feed');
  this.writable('probes', []);
  this.readable('options', options || {});
  this.readable('cache', this.options.cache || null);

  //
  // Add optional error event listener provided via options.
  //
  if (this.options.error) this.on('error', this.options.error);
  this.initialize();
}

//
// Add EventEmitter capacities.
//
fuse(Collector, require('events').EventEmitter);

/**
 * Register a probe to be used against the known registries.
 *
 * @param {Object} probe Valid probe object having name, spec and execute as keys.
 * @returns {Array} List of probes that can be added to the stack.
 * @api public
 */
Collector.readable('use', function use(Probe) {
  var collector = this
    , probe;

  //
  // Any provided probe should have a valid name, specification and function to
  // execute. Simply ignore probes which are invalid.
  //
  probe = new Probe(collector);
  if (!probe.name || !probe.spec || 'function' !== typeof probe.execute) return;

  return probe.list.map(function map(endpoint) {
    debug('[npm-probe] added probe %s for registry: %s', probe.name, endpoint);
    collector.emit('probe::scheduled', probe.name, Date.now());

    return schedule.scheduleJob(probe.name, probe.spec, function execute() {
      probe.execute(registries[endpoint], collector.expose(probe, endpoint));
    });
  });
});

/**
 * Emit `ran` events per registered probe, provide proper name and data.
 *
 * @param {Object} probe details of probe to be executed
 * @param {Object} endpoint name of the endpoint, e.g. nodejitsu
 * @returns {Function} callback to be called
 * @api private
 */
Collector.readable('expose', function expose(probe, registry) {
  var start = Date.now()
    , collector = this;

  debug('[npm-probe] provide callback for probe: %s at %s', probe.name, start);
  return function ran(error, data) {
    var end = Date.now()
      , clone;

    if (error) {
      debug('[npm-probe] emit `error` for probe: %s/%s at %s', registry, probe.name, end);
      return collector.emit('probe::error', error);
    }

    data = {
      name: probe.name,
      registry: registry,
      results: data,
      start: start,
      end: end,
      duration: end - start
    };

    //
    // Clone before emitting, so external listeners cannot polute data storage.
    //
    clone = collector.clone(data);
    collector.emit('probe::ran', null, clone);
    collector.emit('probe::ran::' + probe.name, null, clone);
    debug('[npm-probe] emit `ran` for probe: %s at %s', probe.name, end);

    //
    // Optionally cache the results in provided cache layer.
{'fraction_non_alphanumeric': 0.14727143869596032, 'fraction_numerical': 0.0, 'mean_word_length': 3.2893617021276595, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '2285930', 'n_tokens_mistral': 2158, 'n_tokens_neox': 2089, 'n_words': 704}