<commit_before>var ip = require('ip')
var http = require('http')
var path = require('path')
var debug = require('debug')('micromono:server:pipe')
var callsite = require('callsite')
var argsNames = require('js-args-names')
var ServicePipeline = require('../service/pipeline')

exports.getCallerPath = function () {
  var stack = callsite()
  var callerFilename = stack[2].getFileName()
  return path.dirname(callerFilename)
}

exports.getServerOptions = function(options) {
  var serviceNames
  if ('string' === typeof options.service) {
    serviceNames = options.service.split(',')
    if (0 === serviceNames.length) {
      serviceNames = undefined
    }
  }
  return {
    port: options.port || process.env.PORT || 3000,
    host: options.host || process.env.HOST || ip.address() || '0.0.0.0',
    serviceNames: serviceNames,
    serviceDir: options.serviceDir || null
  }
}

exports.requireAllServices = function(serviceNames, serviceDir, require) {
  debug('require all services: ', serviceNames)

  var services = {}
  serviceNames.forEach(function(name) {
    services[name] = require(name, serviceDir)
  })

  return {
    services: services
  }
}

exports.initFramework = function(frameworkType, framework) {
  if (!framework && 'string' === typeof frameworkType) {
    debug('initialize framework adapter for "%s"', frameworkType)
    var FrameworkAdapter = require('../web/framework/' + frameworkType)
    framework = new FrameworkAdapter()
  }

  return {
    framework: framework
  }
}

exports.prepareFrameworkForBalancer = function(framework, app) {
  framework.app = app
  return {
    serveBalancerAsset: function(asset) {
      framework.serveLocalAsset(asset, 'balancer')
    },
    attachHttpServer: framework.attachHttpServer.bind(framework)
  }
}

exports.createHttpServer = function(set) {
  var requestHandler

  function setHttpRequestHandler(fn) {
    requestHandler = fn
  }

  function serverHandler(req, res) {
    requestHandler(req, res)
  }

  var httpServer = http.createServer(serverHandler)
  // Set to global superpipe so the children pipelines can use it.
  set('httpServer', httpServer)

  return {
    httpServer: httpServer,
    setHttpRequestHandler: setHttpRequestHandler
  }
}

exports.runServices = function(createPipeline, services, runService, next) {
  var pipeline = createPipeline()
  pipeline.pipe(function setCreatePipeline() {
    return {
      createPipeline: createPipeline
    }
  })

  Object.keys(services).forEach(function(serviceName) {
    var service = services[serviceName]
    var serviceDepName = 'service:' + serviceName
    pipeline.pipe(function setServiceDepName(setDep) {
      setDep(serviceDepName, service)
    }, 'setDep')
    pipeline.pipe(runService, [serviceDepName, 'createPipeline', 'next'])
  })

  pipeline.error('errorHandler')
  pipeline.pipe(next)()
}

exports.runService = function(service, createPipeline, next) {
  debug('[%s] runService()', service.name)
  var pipeline = createPipeline()

  if (service.isRemote) {
    pipeline.pipe(function prepareRemotePipeline(setDep, mainFramework) {
      setDep('service', service)
      setDep('framework', mainFramework)
      setDep('announcement', service.announcement)
    }, ['setDep', 'mainFramework'], ['service', 'announcement', 'framework'])

    pipeline = pipeline.concat(ServicePipeline.initRemoteService)
  } else {
    pipeline = pipeline
      .pipe(function setService(setDep) {
        setDep('service', service)
        setDep('packagePath', service.packagePath)
      }, 'setDep')
      .concat(ServicePipeline.initLocalService)

    if (service.init) {
      var initArgs = argsNames(service.init)
      // Add service.init to pipeline
      pipeline.pipe(service.init, initArgs)
    }

    pipeline = pipeline
      .concat(ServicePipeline.runLocalService)
      .pipe('attachToMainFramework?', ['mainFramework', 'framework'])
      .pipe('generateAnnouncement',
        ['assetInfo', 'routes', 'uses', 'middlewares',
          'service', 'httpPort', 'framework', 'rpcApi',
          'rpcPort', 'rpcType', 'host', 'rpcHost'
        ], 'announcement')
  }

  pipeline
    .pipe(next)
    .error('errorHandler', [null, 'serviceName'])

  pipeline()
}

exports.attachToMainFramework = function(mainFramework, framework) {
  if (mainFramework !== framework) {
    mainFramework.app.use(framework.app)
  }
}

exports.startServer = function(httpServer, port, host, setDep) {
  debug('start http server')
  httpServer.listen(port, host, function() {
    var address = httpServer.address()

    debug('http server started at %s:%s', address.address, address.port)

    setDep({
      httpPort: address.port,
      httpHost: address.address
    })
  })
}
<commit_msg>Only serve asset when balancer has one. #16<commit_after>var ip = require('ip')
var http = require('http')
var path = require('path')
var debug = require('debug')('micromono:server:pipe')
var callsite = require('callsite')
var argsNames = require('js-args-names')
var ServicePipeline = require('../service/pipeline')

exports.getCallerPath = function() {
  var stack = callsite()
  var callerFilename = stack[2].getFileName()
  return path.dirname(callerFilename)
}

exports.getServerOptions = function(options) {
  var serviceNames
  if ('string' === typeof options.service) {
    serviceNames = options.service.split(',')
    if (0 === serviceNames.length) {
      serviceNames = undefined
    }
  }
  return {
    port: options.port || process.env.PORT || 3000,
    host: options.host || process.env.HOST || ip.address() || '0.0.0.0',
    serviceNames: serviceNames,
    serviceDir: options.serviceDir || null
  }
}

exports.requireAllServices = function(serviceNames, serviceDir, require) {
  debug('require all services: ', serviceNames)

  var services = {}
  serviceNames.forEach(function(name) {
    services[name] = require(name, serviceDir)
  })

  return {
    services: services
  }
}

exports.initFramework = function(frameworkType, framework) {
  if (!framework && 'string' === typeof frameworkType) {
    debug('initialize framework adapter for "%s"', frameworkType)
    var FrameworkAdapter = require('../web/framework/' + frameworkType)
    framework = new FrameworkAdapter()
  }

  return {
    framework: framework
  }
}

exports.prepareFrameworkForBalancer = function(framework, app) {
  framework.app = app
  return {
    serveBalancerAsset: function(balancerAsset) {
      if (balancerAsset.publicURL && balancerAsset.publicPath) {
        framework.serveLocalAsset(balancerAsset, 'MicroMonoBalancer')
      }
    },
    attachHttpServer: framework.attachHttpServer.bind(framework)
  }
}

exports.createHttpServer = function(set) {
  var requestHandler

  function setHttpRequestHandler(fn) {
    requestHandler = fn
  }

  function serverHandler(req, res) {
    requestHandler(req, res)
  }

  var httpServer = http.createServer(serverHandler)
  // Set to global superpipe so the children pipelines can use it.
  set('httpServer', httpServer)

  return {
    httpServer: httpServer,
    setHttpRequestHandler: setHttpRequestHandler
  }
}

exports.runServices = function(createPipeline, services, runService, next) {
  var pipeline = createPipeline()
  pipeline.pipe(function setCreatePipeline() {
    return {
      createPipeline: createPipeline
    }
  })

  Object.keys(services).forEach(function(serviceName) {
    var service = services[serviceName]
    var serviceDepName = 'service:' + serviceName
    pipeline.pipe(function setServiceDepName(setDep) {
      setDep(serviceDepName, service)
    }, 'setDep')
    pipeline.pipe(runService, [serviceDepName, 'createPipeline', 'next'])
  })

  pipeline.error('errorHandler')
  pipeline.pipe(next)()
}

exports.runService = function(service, createPipeline, next) {
  debug('[%s] runService()', service.name)
  var pipeline = createPipeline()

  if (service.isRemote) {
    pipeline.pipe(function prepareRemotePipeline(setDep, mainFramework) {
      setDep('service', service)
      setDep('framework', mainFramework)
      setDep('announcement', service.announcement)
    }, ['setDep', 'mainFramework'], ['service', 'announcement', 'framework'])

    pipeline = pipeline.concat(ServicePipeline.initRemoteService)
  } else {
    pipeline = pipeline
      .pipe(function setService(setDep) {
        setDep('service', service)
        setDep('packagePath', service.packagePath)
      }, 'setDep')
      .concat(ServicePipeline.initLocalService)

    if (service.init) {
      var initArgs = argsNames(service.init)
      // Add service.init to pipeline
      pipeline.pipe(service.init, initArgs)
    }

    pipeline = pipeline
      .concat(ServicePipeline.runLocalService)
      .pipe('attachToMainFramework?', ['mainFramework', 'framework'])
      .pipe('generateAnnouncement',
        ['assetInfo', 'routes', 'uses', 'middlewares',
          'service', 'httpPort', 'framework', 'rpcApi',
          'rpcPort', 'rpcType', 'host', 'rpcHost'
        ], 'announcement')
  }

  pipeline
    .pipe(next)
    .error('errorHandler', [null, 'serviceName'])

  pipeline()
}

exports.attachToMainFramework = function(mainFramework, framework) {
  if (mainFramework !== framework) {
    mainFramework.app.use(framework.app)
  }
}

exports.startServer = function(httpServer, port, host, setDep) {
  debug('start http server')
  httpServer.listen(port, host, function() {
    var address = httpServer.address()

    debug('http server started at %s:%s', address.address, address.port)

    setDep({
      httpPort: address.port,
      httpHost: address.address
    })
  })
}
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import { getDisplayName } from './utils'

export default function withSideEffect (reduceComponentsToState, handleStateChangeOnClient) {
  return function wrap (WrappedComponent) {
    let mountedInstances = []
    let state

    function emitChange (component) {
      state = reduceComponentsToState(mountedInstances)

      if (SideEffect.canUseDOM) {
        handleStateChangeOnClient.call(component, state)
      }
    }

    class SideEffect extends Component {
      // Try to use displayName of wrapped component
      static displayName = `SideEffect(${getDisplayName(WrappedComponent)})`

      // Expose canUseDOM so tests can monkeypatch it
      static canUseDOM = typeof window !== 'undefined'

      static peek () {
        return state
      }

      static rewind () {
        if (process.env.NODE_ENV !== 'production' && SideEffect.canUseDOM) {
          throw new Error('You may only call rewind() on the server. Call peek() to read the current state.')
        }

        const recordedState = state
        state = undefined
        mountedInstances = []
        return recordedState
      }

      componentWillMount () {
        mountedInstances.push(this)
        emitChange(this)
      }

      componentDidUpdate () {
        emitChange(this)
      }

      componentWillUnmount () {
        const index = mountedInstances.indexOf(this)
        if (index >= 0) {
          mountedInstances.splice(index, 1)
        }
        emitChange(this)
      }

      render () {
        return <WrappedComponent>{ this.props.children }</WrappedComponent>
      }
    }

    return SideEffect
  }
}
<commit_msg>Remove static var from side effect<commit_after>import React, { Component } from 'react'
import { getDisplayName } from './utils'

const canUseDOM = typeof window !== 'undefined'

export default function withSideEffect (reduceComponentsToState, handleStateChangeOnClient) {
  return function wrap (WrappedComponent) {
    let mountedInstances = []
    let state

    function emitChange (component) {
      state = reduceComponentsToState(mountedInstances)

      if (canUseDOM) {
        handleStateChangeOnClient.call(component, state)
      }
    }

    class SideEffect extends Component {
      // Try to use displayName of wrapped component
      static displayName = `SideEffect(${getDisplayName(WrappedComponent)})`

      static peek () {
        return state
      }

      static rewind () {
        if (process.env.NODE_ENV !== 'production' && canUseDOM) {
          throw new Error('You may only call rewind() on the server. Call peek() to read the current state.')
        }

        const recordedState = state
        state = undefined
        mountedInstances = []
        return recordedState
      }

      componentWillMount () {
        mountedInstances.push(this)
        emitChange(this)
      }

      componentDidUpdate () {
        emitChange(this)
      }

      componentWillUnmount () {
        const index = mountedInstances.indexOf(this)
        if (index >= 0) {
          mountedInstances.splice(index, 1)
        }
        emitChange(this)
      }

      render () {
        return <WrappedComponent>{ this.props.children }</WrappedComponent>
      }
    }

    return SideEffect
  }
}
<|endoftext|>


<commit_before>'use strict';

var request = require('request');

// Stolen from https://github.com/kkamkou/node-akamai-http-api
var solus = Object.create(null, {
        base_config: {
            writable: false,
            value: {
                apiId: null,
                apiKey: null,
                host: null,
                port: 80,
                ssl: false,
                verbose: false
            }
        },
        config: {
            writable: true,
            value: {}
        },
    });

// Stolen from http://stackoverflow.com/a/4673436
solus.strFormat = function (format) {
    var args = Array.prototype.slice.call(arguments, 1);
    return format.replace(/\{(\d+)\}/g, function (match, number) {
        return args[number] === undefined ? match : args[number];
    });
};

// Stolen from http://stackoverflow.com/a/1714899
solus.serializeParams = function (obj, prefix) {
    var prop, k, v, str = [];
    for (prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            k = prefix ? prefix + "[" + prop + "]" : prop;
            v = obj[prop];

            if (typeof v === 'object') {
                str.push(solus.serializeParams(v, k));
            } else {
                str.push(encodeURIComponent(k) + "=" + encodeURIComponent(v));
            }
        }
    }
    return str.join("&");
};

solus.generateHostUrl = function (params) {
    if (solus.config.host === null) {
        // Stolen from http://stackoverflow.com/a/1137209
        throw {
            name:     "ConfigError",
            level:    "FATAL",
            message:  "No 'host' value provided.",
            toString: function () {return this.name + ": " + this.message; }
        };
    }

    var schema = solus.config.ssl ? 'https' : 'http',
        suffix = 'api/admin/command.php',
        host = solus.config.host,
        port = solus.config.port;

    return solus.strFormat('{0}://{1}:{2}/{3}?{4}',
                           schema, host, port, suffix,
                           solus.serializeParams(params));
};

solus.setConfig = function (conf) {
    var key;

    conf = conf === undefined ? {} : conf;

    for (key in this.base_config) {
        if (this.base_config.hasOwnProperty(key)) {
            this.config[key] = this.base_config[key];
        }
    }
    for (key in conf) {
        if (conf.hasOwnProperty(key)) {
            this.config[key] = conf[key];
        }
    }

    return this;
};

solus.sQuery = function (params) {
    // Set Query defaults
    params.rdtype = 'json';
    params.id = solus.config.apiId;
    params.key = solus.config.apiKey;

    // execute response
    return request.get(solus.generateHostUrl(params));
};
<commit_msg>Adding initial API functions<commit_after>'use strict';

var request = require('request');

// Stolen from https://github.com/kkamkou/node-akamai-http-api
var solus = Object.create(null, {
        base_config: {
            writable: false,
            value: {
                apiId: null,
                apiKey: null,
                host: null,
                port: 80,
                ssl: false,
                verbose: false
            }
        },
        config: {
            writable: true,
            value: {}
        },
    });

// Stolen from http://stackoverflow.com/a/4673436
solus.strFormat = function (format) {
    var args = Array.prototype.slice.call(arguments, 1);
    return format.replace(/\{(\d+)\}/g, function (match, number) {
        return args[number] === undefined ? match : args[number];
    });
};

// Stolen from http://stackoverflow.com/a/1714899
solus.serializeParams = function (obj, prefix) {
    var prop, k, v, str = [];
    for (prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            k = prefix ? prefix + "[" + prop + "]" : prop;
            v = obj[prop];

            if (typeof v === 'object') {
                str.push(solus.serializeParams(v, k));
            } else {
                str.push(encodeURIComponent(k) + "=" + encodeURIComponent(v));
            }
        }
    }
    return str.join("&");
};

solus.generateHostUrl = function (params) {
    if (solus.config.host === null) {
        // Stolen from http://stackoverflow.com/a/1137209
        throw {
            name:     "ConfigError",
            level:    "FATAL",
            message:  "No 'host' value provided.",
            toString: function () {return this.name + ": " + this.message; }
        };
    }

    var schema = solus.config.ssl ? 'https' : 'http',
        suffix = 'api/admin/command.php',
        host = solus.config.host,
        port = solus.config.port;

    return solus.strFormat('{0}://{1}:{2}/{3}?{4}',
                           schema, host, port, suffix,
                           solus.serializeParams(params));
};

solus.setConfig = function (conf) {
    var key;

    conf = conf === undefined ? {} : conf;

    for (key in this.base_config) {
        if (this.base_config.hasOwnProperty(key)) {
            this.config[key] = this.base_config[key];
        }
    }
    for (key in conf) {
        if (conf.hasOwnProperty(key)) {
            this.config[key] = conf[key];
        }
    }

    return this;
};

solus.sQuery = function (params, callback) {
    // Set Query defaults
    params.rdtype = 'json';
    params.id = solus.config.apiId;
    params.key = solus.config.apiKey;

    // execute response
    return request.get(solus.generateHostUrl(params), callback);
};

solus.listNodesById = function (virtType, callback) {
    this.sQuery({action: 'node-idlist', type: virtType}, callback);
};

solus.listNodesByName = function (virtType, callback) {
    this.sQuery({action: 'listnodes', type: virtType}, callback);
};

solus.listVirtualServers = function (nodeId, callback) {
    this.sQuery({action: 'node-virtualservers', nodeid: nodeId}, callback);
};

solus.virtualServerInfo = function (vserverId, callback) {
    this.sQuery({action: 'vserver-info', vserverid: vserverId}, callback);
};
<|endoftext|>


<commit_before>var cheerio = require('cheerio')
var Datauri = require('datauri')
var Glob = require('glob').sync
var htmlToJson = require('html-to-json')
var path = require('path')
var readFileSync = require('./read-file-sync')
var writeFileSync = require('./write-file-sync')

function svgToJson (dest, options, methods) {
  var files = new Glob(dest + '/svg/*.svg')
  var datauri = new Datauri()

  files.forEach(function (file, i) {
    var iconName = path.basename(file, '.svg')
    var filename = path.basename(file)
    var input = path.resolve(path.dirname(file), filename)
    var output = path.resolve(dest + '/data', iconName) + '.json'
    var content = readFileSync(input)

    if (!checkGroupElement(content, filename)) return

    var promise = htmlToJson.parse(content, {
      'name': function ($root) {
        return iconName
      },
      'viewBox': function ($root) {
        var svg = $root.find('svg')
        return svg[0].attribs.viewbox
      },
      'path': ['path', {
        'd': function ($path) {
          return $path.attr('d')
        },
        'fill': function ($path) {
          return $path.attr('fill')
        },
        'stroke': function ($path) {
          return $path.attr('stroke')
        },
        'stroke-width': function ($path) {
          return $path.attr('stroke-width')
        },
        'stroke-dasharray': function ($path) {
          return $path.attr('stroke-dasharray')
        },
        'stroke-linecap': function ($path) {
          return $path.attr('stroke-linecap')
        },
        'stroke-miterlimit': function ($path) {
          return $path.attr('stroke-miterlimit')
        },
      }],
      'base64': function ($root) {
        return datauri.format(filename, content).content
      },
    })
    return promise.done(function (result) {
      writeFileSync(output, JSON.stringify(result, null, '  '))

      if (i === files.length - 1) {
        dataMerge(dest, options, methods)
      }
    })
  })
}

function dataMerge (dest, options, methods) {
  var files = new Glob(path.resolve(dest + '/data/*.json'))
  var contents = []

  files.forEach(function (file, i) {
    var dir = path.dirname(file)
    var filename = path.basename(file)
    var content = readFileSync(dir + '/' + filename)

    contents.push(content)
  })

  var props = '{ "icons": [' + contents + '] }'
  var result = path.resolve(dest + '/' + options.name + '.json')

  writeFileSync(result, props)

  methods.build(dest, options)
}

function checkGroupElement (content, filename) {
  var $ = cheerio.load(content)
  var $g = $('svg').find('g')
  var $gFill = $g.attr('fill')
  var $gStroke = $g.attr('stroke')

  // 'g' element exists in this svg file
  if ($gFill || $gStroke) throw new Error('SVGPack -> g element exists in the' + filename)

  return true
}

module.exports = svgToJson
<commit_msg>remove unnecessary method<commit_after>var cheerio = require('cheerio')
var Datauri = require('datauri')
var Glob = require('glob').sync
var htmlToJson = require('html-to-json')
var path = require('path')
var readFileSync = require('./read-file-sync')
var writeFileSync = require('./write-file-sync')

function svgToJson (dest, options, methods) {
  var files = new Glob(dest + '/svg/*.svg')
  var datauri = new Datauri()

  files.forEach(function (file, i) {
    var iconName = path.basename(file, '.svg')
    var filename = path.basename(file)
    var input = path.resolve(path.dirname(file), filename)
    var output = path.resolve(dest + '/data', iconName) + '.json'
    var content = readFileSync(input)

    if (!checkGroupElement(content, filename)) return

    var promise = htmlToJson.parse(content, {
      'name': function ($root) {
        return iconName
      },
      'viewBox': function ($root) {
        var svg = $root.find('svg')
        return svg[0].attribs.viewbox
      },
      'path': ['path', {
        'd': function ($path) {
          return $path.attr('d')
        },
        'fill': function ($path) {
          return $path.attr('fill')
        },
        'stroke': function ($path) {
          return $path.attr('stroke')
        },
      }],
      'base64': function ($root) {
        return datauri.format(filename, content).content
      },
    })
    return promise.done(function (result) {
      writeFileSync(output, JSON.stringify(result, null, '  '))

      if (i === files.length - 1) {
        dataMerge(dest, options, methods)
      }
    })
  })
}

function dataMerge (dest, options, methods) {
  var files = new Glob(path.resolve(dest + '/data/*.json'))
  var contents = []

  files.forEach(function (file, i) {
    var dir = path.dirname(file)
    var filename = path.basename(file)
    var content = readFileSync(dir + '/' + filename)

    contents.push(content)
  })

  var props = '{ "icons": [' + contents + '] }'
  var result = path.resolve(dest + '/' + options.name + '.json')

  writeFileSync(result, props)

  methods.build(dest, options)
}

function checkGroupElement (content, filename) {
  var $ = cheerio.load(content)
  var $g = $('svg').find('g')
  var $gFill = $g.attr('fill')
  var $gStroke = $g.attr('stroke')

  // 'g' element exists in this svg file
  if ($gFill || $gStroke) throw new Error('SVGPack -> g element exists in the' + filename)

  return true
}

module.exports = svgToJson
<|endoftext|>


<commit_before>/**
 *  class Wire
 **/

"use strict";

// 3rd-party
var _ = require("underscore");

////////////////////////////////////////////////////////////////////////////////

// "dummy" handler
function noop() {}

////////////////////////////////////////////////////////////////////////////////

// Structure to hold handler data
function WireHandler(channel, options, func) {
  this.channel  = channel;
  this.func     = func;
  this.sync     = 1 === func.length;
  this.once     = Boolean(options.once);
  this.ensure   = Boolean(options.ensure);
  this.priority = Number(options.priority || 0);
  this.ncalled  = 0;
  this.pattern  = new RegExp("^" + channel.replace(/\*+/g, function (m) {
                    // '*' - anything but "dot"
                    // '**' -
                    return '*' === m ? '[^.]+?' : '.+?';
                  }) + "$");
}

////////////////////////////////////////////////////////////////////////////////

function Wire() {
  this.__handlers__       = [];
  this.__sortedCache__    = [];
  this.__knownChannels__  = {};
}

Wire.prototype.getHandlers = function (channel) {
  if (!this.__sortedCache__[channel]) {
    this.__sortedCache__[channel] = _.chain(this.__handlers__)
      .filter(function (wh) {
        return wh.match(channel);
      }).sort(function (a, b) {
        if (a.priority === b.priority) {
          return 0;
        }

        return (a.priority < b.priority) ? -1 : 1;
      }).value();
  }

  return this.__sortedCache__[channel];
};

/**
 *  Wire#emit(channel, params[, callback]) -> Void
 *  - channel (String):
 *  - params (Mixed):
 *  - callback (Function):
 *
 *  Sends message with `params` into the `channel`. Once all sync and ascync
 *  handlers finished, optional `callback(err)` (if specified) fired.
 **/
Wire.prototype.emit = function (channel, params, callback) {
  callback = callback || noop;

  if (!this.isKnown(channel)) {
    callback("Unknown channel");
    return;
  }

  // async logic will be here
  throw "Not implemented yet";
};

/**
 *  Wire#on(channel[, options], handler) -> Void
 *  - channel (String):
 *  - options (Object):
 *  - handler (Function):
 *
 *  Registers `handler` to be executed upon messages in the `channel`. Handler
 *  can be either sync function:
 *
 *      wire.on('foobar', function (params) {
 *        // do stuff here
 *      });
 *
 *  Or it might be an async function with `callback(err)` second argument:
 *
 *      wire.on('foobar', function (params, callback) {
 *        // do stuff here
 *        callback(null);
 *      });
 *
 *
 *  ##### Options
 *
 *  - `priority` (Number, Default: 0)
 *  - `exclude` (String|RegExp, Default: Null)
 *    Glob or RegExp patther to exclude channels from being listened.
 *  - `ensure` (Boolean, Default: false)
 *    If `true`, will run handler even if one of previous fired error.
 **/
Wire.prototype.on = function (channel, options, handler) {
  if (!handler) {
    handler = options;
    options = null;
  }

  options = options || {};

  if (!_.isFunction(handler)) {
    throw "Not a function";
  }

  if (handler.length < 1 && 2 < handler.length) {
    throw "Function must accept exactly 1 (sync) or 2 (async) arguments";
  }

  // got channel handler (no wildcards)
  if (-1 === channel.indexOf('*')) {
    this.__knownChannels__[channel] = (this.__knownChannels__[channel] || 0) + 1;
  }

  this.__sortedCache__ = [];
  this.__handlers__.push(new WireHandler(channel, options, handler));
};

/**
 *  Wire#once(channel[, options], handler) -> Void
 *  - channel (String):
 *  - options (Object):
 *  - handler (Function):
 *
 *  Same as [[Wire#on]] but runs handler one time only.
 **/
Wire.prototype.once = function (channel, options, handler) {
  var self = this, realHandler;

  if (!handler) {
    handler = options;
    options = null;
  }

  Wire.prototype.on(channel, _.extend(options, { once: true }), handler);
};

/**
 *  Wire#before(channel[, options], handler) -> Void
 *  - channel (String):
 *  - options (Object):
 *  - handler (Function):
 *
 *  Same as [[Wire#on]] but with "fixed" priority of `-10`
 **/
Wire.prototype.before = function (channel, options, handler) {
  if (!handler) {
    handler = options;
    options = null;
  }

  options = _.extend({ priority: 10 }, options);

  if (0 <= options.priority) {
    throw "before() requires priority lower than 0";
  }

  return this.on(channel, options, handler);
};

/**
 *  Wire#after(channel[, options], handler) -> Void
 *  - channel (String):
 *  - options (Object):
 *  - handler (Function):
 *
 *  Same as [[Wire#on]] but with default priority of `10`
 **/
Wire.prototype.after = function (channel, options, handler) {
  if (!handler) {
    handler = options;
    options = null;
  }

  options = _.extend({ priority: 10 }, options);

  if (0 >= options.priority) {
    throw "after() requires priority greater than 0";
  }

  return this.on(channel, options, handler);
};

/**
 *  Wire#off(channel[, handler]) -> Void
 *  - channel (String):
 *  - handler (Function):
 *
 *  Removes `handler` of a channel, or removes ALL handlers of a channel if
 *  `handler` is not given.
 **/
Wire.prototype.off = function (channel, handler) {
  // got channel handler (no wildcards)
  if (-1 === channel.indexOf('*')) {
    this.__knownChannels__[channel] -= 1;
  }

  _.each(this.__handlers__, function (wh) {
    if ((channel !== wh.channel) || (handler && handler !== wh.func)) {
      return;
    }

    handler.sync = true;
    handler.func = noop;
  });
};

/**
 *  Wire#has(channel[, options][, handler]) -> Void
 *  - channel (String):
 *  - handler (Function):
 *
 *  Returns if `handler` is listening `channel`, or if `channel`
 *  has at least one subscriber if `handler` is not given.
 *
 *
 *  ##### Options
 *
 *  - `priority` (Number)
 *  - `ensure` (Boolean)
 *    Search for handlers with `ensure` flag only.
 **/
Wire.prototype.isKnown = function (channel) {
  return Boolean(this.__knownChannels__[channel]);
};

/**
 *  Wire#stat([match = "*"][, options]) -> String
 *  - `match` (String|RegExp):
 *    List info about channels matching given Glob|RegExp pattern only.
 *  - options (Object):
 *
 *  Returns statistics that includes by default all channels list alphabetically
 *  sorted with subscribers count; For each sbscriber it shows names and count
 *  of times it was triggered by far.
 *
 *  ##### Options
 *
 *  - `subscribers` (Boolean, Default: true): List subscribers with their names
 *    and amount of times they were fired.
 **/
Wire.prototype.stat = function (match, options) {
  throw "Not implemented yet";
};

////////////////////////////////////////////////////////////////////////////////

module.exports = Wire;
<commit_msg>Implement wire emitter<commit_after>/**
 *  class Wire
 **/

"use strict";

// 3rd-party
var _ = require("underscore");

////////////////////////////////////////////////////////////////////////////////

// "dummy" handler
function noop() {}

////////////////////////////////////////////////////////////////////////////////

// Structure to hold handler data
function WireHandler(channel, options, func) {
  this.channel  = channel;
  this.func     = func;
  this.sync     = 1 === func.length;
  this.once     = Boolean(options.once);
  this.ensure   = Boolean(options.ensure);
  this.priority = Number(options.priority || 0);
  this.ncalled  = 0;
  this.pattern  = new RegExp("^" + channel.replace(/\*+/g, function (m) {
                    // '*' - anything but "dot"
                    // '**' -
                    return '*' === m ? '[^.]+?' : '.+?';
                  }) + "$");
}

////////////////////////////////////////////////////////////////////////////////

function Wire() {
  this.__handlers__       = [];
  this.__sortedCache__    = [];
  this.__knownChannels__  = {};
}

Wire.prototype.getHandlers = function (channel) {
  if (!this.__sortedCache__[channel]) {
    this.__sortedCache__[channel] = _.chain(this.__handlers__)
      .filter(function (wh) {
        return wh.match(channel);
      }).sort(function (a, b) {
        if (a.priority === b.priority) {
          return 0;
        }

        return (a.priority < b.priority) ? -1 : 1;
      }).value();
  }

  return this.__sortedCache__[channel];
};

/**
 *  Wire#emit(channel, params[, callback]) -> Void
 *  - channel (String):
 *  - params (Mixed):
 *  - callback (Function):
 *
 *  Sends message with `params` into the `channel`. Once all sync and ascync
 *  handlers finished, optional `callback(err)` (if specified) fired.
 **/
Wire.prototype.emit = function (channel, params, callback) {
  var stash;

  callback = callback || noop;

  if (!this.isKnown(channel)) {
    callback("Unknown channel");
    return;
  }

  // get array of associated handlers
  stash = this.getHandlers(channel).slice();

  // helps to prevent from double-firing callback
  // when developer forgot to interrupt:
  //
  //    function doSomething(params, next) {
  //      try {
  //        // ...
  //      } catch (err) {
  //        next(err);
  //      }
  //
  //      next();
  //    }
  function done(err) {
    var _callback = callback;

    stash    = [];
    callback = noop;

    _callback(err);
  }

  // iterates through handlers of stash
  function walk(err) {
    var wh;

    if (err || !stash.length) {
      done(err);
      return;
    }

    while (stash.length) {
      wh = stash.shift();
      fn = wh.func;

      wh.ncalled += 1;

      if (wh.once) {
        self.off(wh.handler, fn);
      }

      if (!wh.sync) {
        fn(params, walk);
        return;
      }

      err = fn(params);

      if (err) {
        done(err);
        return;
      }
    }
  }

  // start stash walker
  walk();
};

/**
 *  Wire#on(channel[, options], handler) -> Void
 *  - channel (String):
 *  - options (Object):
 *  - handler (Function):
 *
 *  Registers `handler` to be executed upon messages in the `channel`. Handler
 *  can be either sync function:
 *
 *      wire.on('foobar', function (params) {
 *        // do stuff here
 *      });
 *
 *  Or it might be an async function with `callback(err)` second argument:
 *
 *      wire.on('foobar', function (params, callback) {
 *        // do stuff here
 *        callback(null);
 *      });
 *
 *
 *  ##### Options
 *
 *  - `priority` (Number, Default: 0)
 *  - `exclude` (String|RegExp, Default: Null)
 *    Glob or RegExp patther to exclude channels from being listened.
 *  - `ensure` (Boolean, Default: false)
 *    If `true`, will run handler even if one of previous fired error.
 **/
Wire.prototype.on = function (channel, options, handler) {
  if (!handler) {
    handler = options;
    options = null;
  }

  options = options || {};

  if (!_.isFunction(handler)) {
    throw "Not a function";
  }

  if (handler.length < 1 && 2 < handler.length) {
    throw "Function must accept exactly 1 (sync) or 2 (async) arguments";
  }

  // got channel handler (no wildcards)
  if (-1 === channel.indexOf('*')) {
    this.__knownChannels__[channel] = (this.__knownChannels__[channel] || 0) + 1;
  }

  this.__sortedCache__ = [];
  this.__handlers__.push(new WireHandler(channel, options, handler));
};

/**
 *  Wire#once(channel[, options], handler) -> Void
 *  - channel (String):
 *  - options (Object):
 *  - handler (Function):
 *
 *  Same as [[Wire#on]] but runs handler one time only.
 **/
Wire.prototype.once = function (channel, options, handler) {
  var self = this, realHandler;

  if (!handler) {
    handler = options;
    options = null;
  }

  Wire.prototype.on(channel, _.extend(options, { once: true }), handler);
};

/**
 *  Wire#before(channel[, options], handler) -> Void
 *  - channel (String):
 *  - options (Object):
 *  - handler (Function):
 *
 *  Same as [[Wire#on]] but with "fixed" priority of `-10`
 **/
Wire.prototype.before = function (channel, options, handler) {
  if (!handler) {
    handler = options;
    options = null;
  }

  options = _.extend({ priority: 10 }, options);

  if (0 <= options.priority) {
    throw "before() requires priority lower than 0";
  }

  return this.on(channel, options, handler);
};

/**
 *  Wire#after(channel[, options], handler) -> Void
 *  - channel (String):
 *  - options (Object):
 *  - handler (Function):
 *
 *  Same as [[Wire#on]] but with default priority of `10`
 **/
Wire.prototype.after = function (channel, options, handler) {
  if (!handler) {
    handler = options;
    options = null;
  }

  options = _.extend({ priority: 10 }, options);

  if (0 >= options.priority) {
    throw "after() requires priority greater than 0";
  }

  return this.on(channel, options, handler);
};

/**
 *  Wire#off(channel[, handler]) -> Void
 *  - channel (String):
 *  - handler (Function):
 *
 *  Removes `handler` of a channel, or removes ALL handlers of a channel if
 *  `handler` is not given.
 **/
Wire.prototype.off = function (channel, handler) {
  // got channel handler (no wildcards)
  if (-1 === channel.indexOf('*')) {
    this.__knownChannels__[channel] -= 1;
  }

  _.each(this.__handlers__, function (wh) {
    if ((channel !== wh.channel) || (handler && handler !== wh.func)) {
      return;
    }

    handler.sync = true;
    handler.func = noop;
  });
};

/**
 *  Wire#has(channel[, options][, handler]) -> Void
 *  - channel (String):
 *  - handler (Function):
 *
 *  Returns if `handler` is listening `channel`, or if `channel`
 *  has at least one subscriber if `handler` is not given.
 *
 *
 *  ##### Options
 *
 *  - `priority` (Number)
 *  - `ensure` (Boolean)
 *    Search for handlers with `ensure` flag only.
 **/
Wire.prototype.isKnown = function (channel) {
  return Boolean(this.__knownChannels__[channel]);
};

/**
 *  Wire#stat([match = "*"][, options]) -> String
 *  - `match` (String|RegExp):
 *    List info about channels matching given Glob|RegExp pattern only.
 *  - options (Object):
 *
 *  Returns statistics that includes by default all channels list alphabetically
 *  sorted with subscribers count; For each sbscriber it shows names and count
 *  of times it was triggered by far.
 *
 *  ##### Options
 *
 *  - `subscribers` (Boolean, Default: true): List subscribers with their names
 *    and amount of times they were fired.
 **/
Wire.prototype.stat = function (match, options) {
  throw "Not implemented yet";
};

////////////////////////////////////////////////////////////////////////////////

module.exports = Wire;
<|endoftext|>


<commit_before>'use strict';

var util = require('util');
var DefaultRegistry = require('undertaker-registry');
var vfs = require('vinyl-fs');
var merge = require('merge-stream');
var resolveRequire = require('resolve-require');

function ViewsRegistry() {

  DefaultRegistry.call(this);

  this.set('ng:src/views', function(cb) {

    // Lazy load expensive modules
    var factory = resolveRequire('factory-' + this.factory);
    var reload = require('browser-sync').reload;

    var paths = this.paths;
    var views = vfs.src(paths.views, {cwd: paths.cwd, base: paths.cwd})
      .pipe(factory.views.src.bind(this)())
      .pipe(reload({stream: true}));
    var index = vfs.src(paths.index, {cwd: paths.cwd, base: paths.cwd})
      .pipe(factory.index.src.bind(this)())
      .pipe(reload({stream: true}));
    return merge(views, index);

  });

  this.set('ng:dist/views', function(cb) {

    // Lazy load expensive modules
    var factory = resolveRequire('factory-' + this.factory);
    var reload = require('browser-sync').reload;

    var paths = this.paths;
    return vfs.src(paths.index, {cwd: paths.cwd, base: paths.cwd})
      .pipe(factory.index.dist.bind(this)())
      .pipe(reload({stream: true})); // properly closes the stream

  });

}

util.inherits(ViewsRegistry, DefaultRegistry);

module.exports = ViewsRegistry;
<commit_msg>fix(views): remove browser-sync hack to properly close the stream<commit_after>'use strict';

var util = require('util');
var DefaultRegistry = require('undertaker-registry');
var vfs = require('vinyl-fs');
var merge = require('merge-stream');
var resolveRequire = require('resolve-require');

function ViewsRegistry() {

  DefaultRegistry.call(this);

  this.set('ng:src/views', function(cb) {

    // Lazy load expensive modules
    var factory = resolveRequire('factory-' + this.factory);
    var reload = require('browser-sync').reload;

    var paths = this.paths;
    var views = vfs.src(paths.views, {cwd: paths.cwd, base: paths.cwd})
      .pipe(factory.views.src.bind(this)())
      .pipe(reload({stream: true}));
    var index = vfs.src(paths.index, {cwd: paths.cwd, base: paths.cwd})
      .pipe(factory.index.src.bind(this)())
      .pipe(reload({stream: true}));
    return merge(views, index);

  });

  this.set('ng:dist/views', function(cb) {

    // Lazy load expensive modules
    var factory = resolveRequire('factory-' + this.factory);

    var paths = this.paths;
    return vfs.src(paths.index, {cwd: paths.cwd, base: paths.cwd})
      .pipe(factory.index.dist.bind(this)());

  });

}

util.inherits(ViewsRegistry, DefaultRegistry);

module.exports = ViewsRegistry;
<|endoftext|>


<commit_before>var ANSIBuffer = require('./ansi-buffer'),
    async = require('async'),
    child_process = require('child_process'),
    fs = require('fs'),
    server = require('./server'),
    sourceMap = require('./source-map'),
    testServer = require('./test-server'),
    util = require('./util');

require('colors');

var ANDROID_UA = 'Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus S Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1';
var IPHONE_UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3';

exports.run = function(options, complete) {
  var superCode = 0,
      queue = async.queue(function(task, callback) { task(callback); }, 1);

  var testPlatforms = options.testPlatforms.slice(),
      webOnly = options.webOnly,
      moduleName = options.module,
      xunit = options.xunit;

  complete = complete || function(code) { process.exit(code); };

  function runPhantom(platform, androidUserAgent, xunit, callback) {
    console.log(
        'Running platform: ' + platform
        + (androidUserAgent ? ' androidUserAgent ' : '')
        + (moduleName ? ' module: ' + moduleName : ''));

    var userAgent = androidUserAgent ? ANDROID_UA : IPHONE_UA;
    var args = ['-A', userAgent],
        url = 'http://localhost:' + port + '/r/phoenix/' + platform + '/test.html';
    if (moduleName) {
      url += '?module=' + moduleName;
    }
    args.push(url);
    if (xunit) {
      args.push('-R', 'xunit');
    } else {
      args.push('-R', 'dot');
    }

    var phantom = child_process.spawn(__dirname + '/../node_modules/.bin/mocha-phantomjs', args);

    var buffer = new ANSIBuffer();
    phantom.stdout.on('data', function (data) {
      queue.push(function(callback) {
        buffer.append(data);
        if (!xunit) {
          data = buffer.trim(0);
          if (data) {
            return rewriteLines(data, mochaTests && xunit, function(err, data) {
              util.streamData('  phantom: ', data);
              callback();
            });
          }

          callback();
        }
      });
    });
    phantom.stderr.on('data', function (data) {
      queue.push(function(callback) {
        util.streamData('  phantom err: ', data);
        callback();
      });
    });
    phantom.on('exit', function(code) {
      queue.push(function(queueCallback) {
        superCode = superCode || code;
        if (!xunit) {
          util.streamData('  phantom: ', buffer.toString());
        }
        if (!xunit && code) {
          util.streamData('  phantom: exit code: ', code + '\n');
        }
        queueCallback();
        callback(code, buffer);
      });
    });
  }

  var port;
  function exec() {
    var platform = testPlatforms.shift();
    if (webOnly && !platform.webOnly) {
      complete(superCode);
      return;
    }

    runPhantom(platform.platform, platform.androidUA, xunit, function(code, buffer) {
      if (xunit) {
        fs.writeFileSync('build/' + platform.platform + (platform.androidUA ? '_android' : '') + '.xml', buffer);
      }

      if (!testPlatforms.length) {
        complete(superCode);
      } else {
        exec();
      }
    });
  }

  testServer.exec(options.projectDir, function(_port) {
    port = _port;
    exec();
  });
};

function rewriteLines(data, noFormat, callback) {
  // Parse the incoming data for exception urls
  var tokens = data.toString().split(/(https?:\/\/localhost:.+:\d+)/g);
  async.map(tokens, function(token, callback) {
      var match = /(https?:\/\/localhost:.+):(\d+)/.exec(token);
      if (match) {
        sourceMap.map(match[1], match[2], 1, function(err, file, line) {
          file = file + ':' + line;
          if (!noFormat && !/phoenix-build/.test(file)) {
            file = file.underline.bold;
          }
          // Replace the file reference
          callback(undefined, file);
        });
      } else {
        callback(undefined, token);
      }
    },
    function(err, data) {
      if (err) {
        throw err;
      }

      callback(undefined, data.join(''));
    });
}
<commit_msg>Remove missing var reference<commit_after>var ANSIBuffer = require('./ansi-buffer'),
    async = require('async'),
    child_process = require('child_process'),
    fs = require('fs'),
    server = require('./server'),
    sourceMap = require('./source-map'),
    testServer = require('./test-server'),
    util = require('./util');

require('colors');

var ANDROID_UA = 'Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus S Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1';
var IPHONE_UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3';

exports.run = function(options, complete) {
  var superCode = 0,
      queue = async.queue(function(task, callback) { task(callback); }, 1);

  var testPlatforms = options.testPlatforms.slice(),
      webOnly = options.webOnly,
      moduleName = options.module,
      xunit = options.xunit;

  complete = complete || function(code) { process.exit(code); };

  function runPhantom(platform, androidUserAgent, xunit, callback) {
    console.log(
        'Running platform: ' + platform
        + (androidUserAgent ? ' androidUserAgent ' : '')
        + (moduleName ? ' module: ' + moduleName : ''));

    var userAgent = androidUserAgent ? ANDROID_UA : IPHONE_UA;
    var args = ['-A', userAgent],
        url = 'http://localhost:' + port + '/r/phoenix/' + platform + '/test.html';
    if (moduleName) {
      url += '?module=' + moduleName;
    }
    args.push(url);
    if (xunit) {
      args.push('-R', 'xunit');
    } else {
      args.push('-R', 'dot');
    }

    var phantom = child_process.spawn(__dirname + '/../node_modules/.bin/mocha-phantomjs', args);

    var buffer = new ANSIBuffer();
    phantom.stdout.on('data', function (data) {
      queue.push(function(callback) {
        buffer.append(data);
        if (!xunit) {
          data = buffer.trim(0);
          if (data) {
            return rewriteLines(data, xunit, function(err, data) {
              util.streamData('  phantom: ', data);
              callback();
            });
          }

          callback();
        }
      });
    });
    phantom.stderr.on('data', function (data) {
      queue.push(function(callback) {
        util.streamData('  phantom err: ', data);
        callback();
      });
    });
    phantom.on('exit', function(code) {
      queue.push(function(queueCallback) {
        superCode = superCode || code;
        if (!xunit) {
          util.streamData('  phantom: ', buffer.toString());
        }
        if (!xunit && code) {
          util.streamData('  phantom: exit code: ', code + '\n');
        }
        queueCallback();
        callback(code, buffer);
      });
    });
  }

  var port;
  function exec() {
    var platform = testPlatforms.shift();
    if (webOnly && !platform.webOnly) {
      complete(superCode);
      return;
    }

    runPhantom(platform.platform, platform.androidUA, xunit, function(code, buffer) {
      if (xunit) {
        fs.writeFileSync('build/' + platform.platform + (platform.androidUA ? '_android' : '') + '.xml', buffer);
      }

      if (!testPlatforms.length) {
        complete(superCode);
      } else {
        exec();
      }
    });
  }

  testServer.exec(options.projectDir, function(_port) {
    port = _port;
    exec();
  });
};

function rewriteLines(data, noFormat, callback) {
  // Parse the incoming data for exception urls
  var tokens = data.toString().split(/(https?:\/\/localhost:.+:\d+)/g);
  async.map(tokens, function(token, callback) {
      var match = /(https?:\/\/localhost:.+):(\d+)/.exec(token);
      if (match) {
        sourceMap.map(match[1], match[2], 1, function(err, file, line) {
          file = file + ':' + line;
          if (!noFormat && !/phoenix-build/.test(file)) {
            file = file.underline.bold;
          }
          // Replace the file reference
          callback(undefined, file);
        });
      } else {
        callback(undefined, token);
      }
    },
    function(err, data) {
      if (err) {
        throw err;
      }

      callback(undefined, data.join(''));
    });
}
<|endoftext|>


<commit_before>(function(exports) {

  exports.torque = exports.torque || {};

  var Event = {};
  Event.on = function(evt, callback) {
      var cb = this._evt_callbacks = this._evt_callbacks || {};
      var l = cb[evt] || (cb[evt] = []);
      l.push(callback);
      return this;
  };

  Event.trigger = function(evt) {
      var c = this._evt_callbacks && this._evt_callbacks[evt];
      for(var i = 0; c && i < c.length; ++i) {
          c[i].apply(this, Array.prototype.slice.call(arguments, 1));
      }
      return this;
  };

  Event.fire = Event.trigger;

  Event.off = function (evt, callback) {
      var c = this._evt_callbacks && this._evt_callbacks[evt];
      if (c && !callback) {
        delete this._evt_callbacks[evt];
        return this;
     }
     var remove = [];
     for(var i = 0; c && i < c.length; ++i) {
       if(c[i] === callback) remove.push(i);
     }
     while((i = remove.pop()) !== undefined) c.splice(i, 1);
    return this;
  };

  Event.callbacks = function(evt) {
    return (this._evt_callbacks && this._evt_callbacks[evt]) || [];
  };

  exports.torque.Event = Event;
  exports.torque.extend = function(a, b) {
    for (var k in b) {
      a[k] = b[k];
    }
    return a
  }

  exports.torque.clone = function(a) {
    return exports.torque.extend({}, a);
  }

  exports.torque.isFunction = function(f) {
    return typeof f == 'function' || false;
  }

  exports.torque.isArray = function(value) {
      return value && typeof value == 'object' && Object.prototype.toString.call(value) == '[object Array]';
  };

  // types
  exports.torque.types = {
    Uint8Array: typeof(window['Uint8Array']) !== 'undefined' ? window.Uint8Array : Array,
    Uint32Array: typeof(window['Uint32Array']) !== 'undefined' ? window.Uint32Array : Array,
    Int32Array: typeof(window['Int32Array']) !== 'undefined' ? window.Int32Array: Array
  };

  exports.torque.isBrowserSupported = function() {
    return !!document.createElement('canvas');
  };

  exports.torque.flags = {
    sprites_to_images: navigator.userAgent.indexOf('Safari') === -1
  }

})(typeof exports === "undefined" ? this : exports);
<commit_msg>Make extend compatible with underscore's one<commit_after>(function(exports) {

  exports.torque = exports.torque || {};

  var Event = {};
  Event.on = function(evt, callback) {
      var cb = this._evt_callbacks = this._evt_callbacks || {};
      var l = cb[evt] || (cb[evt] = []);
      l.push(callback);
      return this;
  };

  Event.trigger = function(evt) {
      var c = this._evt_callbacks && this._evt_callbacks[evt];
      for(var i = 0; c && i < c.length; ++i) {
          c[i].apply(this, Array.prototype.slice.call(arguments, 1));
      }
      return this;
  };

  Event.fire = Event.trigger;

  Event.off = function (evt, callback) {
      var c = this._evt_callbacks && this._evt_callbacks[evt];
      if (c && !callback) {
        delete this._evt_callbacks[evt];
        return this;
     }
     var remove = [];
     for(var i = 0; c && i < c.length; ++i) {
       if(c[i] === callback) remove.push(i);
     }
     while((i = remove.pop()) !== undefined) c.splice(i, 1);
    return this;
  };

  Event.callbacks = function(evt) {
    return (this._evt_callbacks && this._evt_callbacks[evt]) || [];
  };

  function extend() {
      var objs = arguments;
      var a = objs[0];
      for (var i = 1; i < objs.length; ++i) {
          var b = objs[i];
          for (var k in b) {
              a[k] = b[k];
          }
      }
      return a;
  }

  exports.torque.clone = function(a) {
    return exports.torque.extend({}, a);
  }

  exports.torque.isFunction = function(f) {
    return typeof f == 'function' || false;
  }

  exports.torque.isArray = function(value) {
      return value && typeof value == 'object' && Object.prototype.toString.call(value) == '[object Array]';
  };

  // types
  exports.torque.types = {
    Uint8Array: typeof(window['Uint8Array']) !== 'undefined' ? window.Uint8Array : Array,
    Uint32Array: typeof(window['Uint32Array']) !== 'undefined' ? window.Uint32Array : Array,
    Int32Array: typeof(window['Int32Array']) !== 'undefined' ? window.Int32Array: Array
  };

  exports.torque.isBrowserSupported = function() {
    return !!document.createElement('canvas');
  };

  exports.torque.flags = {
    sprites_to_images: navigator.userAgent.indexOf('Safari') === -1
  }

})(typeof exports === "undefined" ? this : exports);
<|endoftext|>


<commit_before>'use strict';
const CoinbaseExchange = require('coinbase-exchange');
const assert = require('assert');

const no_data = {
    updated: undefined,
    data: undefined
};

class TradingBot {
    constructor(options) {
        this.busy_executing = false;
        options = options || {};
        this.log = options.log || console.log;
        this.product = options.product || 'BTC-USD';
        this._timer = null;
        if (!options.client) {
            if (!options.auth) {
                throw new Error('TradingBot: Either a Coinbase client or an auth object must be provided');
            }
            let auth = options.auth;
            this.client = new CoinbaseExchange.AuthenticatedClient(auth.key, auth.secret, auth.passphrase, auth.apiURI);
        }
        else {
            this.client = options.client;
        }
        assert(this.client);
        this.ws_client = null;
        if (options.websocketClient) {
            this.ws_client = options.websocketClient;
        } else if (options.websocketURI) {
            this.ws_client = this.get_default_ws_client(options.websocketURI);
        }
        this.init_state();
    }

    init_state() {
        this._ticker = { updated: undefined, data: undefined, errors: [] };
        this._orderbook = { updated: undefined, data: undefined, errors: [] };
        this._myorders = { updated: undefined, data: undefined, errors: [] };
    }

    get ticker() {
        return this._ticker;
    }

    get price() {
        const info = this._ticker.data;
        if (info) {
            return {
                updated: this._ticker.updated,
                data: info.price,
                errors: info.errors
            }
        }
        return no_data;
    }

    get midmarket_price() {
        const info = this._ticker.data;
        if (info) {
            return {
                updated: this._ticker.updated,
                data: 0.5 * (+info.ask + (+info.bid)),
                errors: info.errors
            }
        }
        return no_data;
    }

    get order_book() {
        return this._orderbook;
    }

    get my_orders() {
        return this._myorders;
    }

    get is_trading() {
        return this._timer !== null;
    }

    /**
     * Starts trading with the bot.
     * @param options
     * @param options.interval the length of time (in ms) between firing the strategy (default: 1000ms)
     * @returns {Promise}
     */
    start_trading(options) {
        const self = this;
        options = options || {};
        return self.stop_trading({ cancel: false }).then(() => {
            const interval = options.interval || 1000;
            self._timer = setInterval(self.execute_strategy.bind(self), interval);
            return Promise.resolve();
        });
    }

    /**
     * Stop the trading bot
     * @param options
     * @param options.cancel {boolean} if true, calls #cancel_all_orders before stopping
     * @returns {Promise}
     */
    stop_trading(options) {
        if (!this.is_trading) {
            return Promise.resolve();
        }
        options = options || { cancel: false };
        const self = this;
        let cancel = options.cancel ? self.cancel_all_orders() : Promise.resolve();
        return cancel.then(() => {
            clearInterval(this._timer);
            this._timer = null;
            return Promise.resolve();
        });
    }

    /**
     * Returns a promise to cancel an order
     * @param order_id {string}
     * @returns {Promise}
     */
    cancel_order(order_id) {
        return new Promise((resolve, reject) => {
            this.client.cancelOrder(order_id, (err, result) => {
                if (err) {
                    return reject(err);
                }
                resolve(result);
            })
        });
    }

    /**
     * Returns a promise to cancel all orders
     */
    cancel_all_orders() {
        return this.cancel_order(null);
    }

    execute_strategy() {
        const self = this;
        if (self.busy_executing) {
            self.log({ message: 'The last trade execution is still busy. Skipping this round' });
            return;
        }
        self.busy_executing = true;
        setImmediate(() => {
            self._execute_trading_strategy().then(() => {
                this.busy_executing = false;
            });
        });
    }

    /**
     * Sub-classes override this method to enact their trading strategy
     * @private
     * @returns {Promise}
     */
    _execute_trading_strategy() {
        return Promise.resolve();
    }

    get_default_ws_client(wss) {
        this.log({ message: 'Attempting to obtain websocket feed from ' + wss });
        let websocket = new CoinbaseExchange.WebsocketClient(product, wss);
        websocket.on('close', function() {
            setTimeout(function() {
                websocket.connect();
            }, 1000);
        });
        return websocket;
    }

    /**
     * Returns a promise for the latest ticker price. Does not update state
     */
    fetch_ticker() {
        let self = this;
        return new Promise((resolve, reject) => {
            self.client.getProductTicker((err, ticker) => {
                if (err) {
                    return reject(err);
                }
                resolve(ticker);
            })
        });
    }

    /**
     * Returns a promise for the order book. Does not update state
     * @returns {Promise}
     */
    fetch_orderbook() {
        let self = this;
        return new Promise((resolve, reject) => {
            self.client.getProductOrderBook({ level: 2 }, (err, order_book) => {
                if (err) {
                    return reject(err);
                }
                resolve(order_book);
            })
        });
    }

    /**
     * Returns a promise for the order book. Does not update state
     * @returns {Promise}
     */
    fetch_myorders() {
        let self = this;
        return new Promise((resolve, reject) => {
            self.client.getOrders((err, orders) => {
                if (err) {
                    return reject(err);
                }
                resolve(orders);
            })
        });
    }

    /**
     * Request all indicators to refresh themselves.
     */
    refresh_indicators() {
        const self = this;

        function update_item(promise, obj) {
            return promise.then(data => {
                obj.updated = new Date();
                obj.data = data;
                return data;
            }).catch(err => {
                obj.errors.push({
                    timestamp: new Date(),
                    error: err
                });
            })
        }

        update_item(self.fetch_ticker(), self._ticker);
        update_item(self.fetch_orderbook(), self._orderbook);
        update_item(self.fetch_myorders(), self._myorders);
    }
}

module.exports = TradingBot;<commit_msg>Fix get_default_ws_client<commit_after>'use strict';
const CoinbaseExchange = require('coinbase-exchange');
const assert = require('assert');

const no_data = {
    updated: undefined,
    data: undefined
};

class TradingBot {
    constructor(options) {
        this.busy_executing = false;
        options = options || {};
        this.log = options.log || console.log;
        this.product = options.product || 'BTC-USD';
        this._timer = null;
        if (!options.client) {
            if (!options.auth) {
                throw new Error('TradingBot: Either a Coinbase client or an auth object must be provided');
            }
            let auth = options.auth;
            this.client = new CoinbaseExchange.AuthenticatedClient(auth.key, auth.secret, auth.passphrase, auth.apiURI);
        }
        else {
            this.client = options.client;
        }
        assert(this.client);
        this.ws_client = null;
        if (options.websocketClient) {
            this.ws_client = options.websocketClient;
        } else if (options.websocketURI) {
            this.ws_client = this.get_default_ws_client(options.websocketURI);
        }
        this.init_state();
    }

    init_state() {
        this._ticker = { updated: undefined, data: undefined, errors: [] };
        this._orderbook = { updated: undefined, data: undefined, errors: [] };
        this._myorders = { updated: undefined, data: undefined, errors: [] };
    }

    get ticker() {
        return this._ticker;
    }

    get price() {
        const info = this._ticker.data;
        if (info) {
            return {
                updated: this._ticker.updated,
                data: info.price,
                errors: info.errors
            }
        }
        return no_data;
    }

    get midmarket_price() {
        const info = this._ticker.data;
        if (info) {
            return {
                updated: this._ticker.updated,
                data: 0.5 * (+info.ask + (+info.bid)),
                errors: info.errors
            }
        }
        return no_data;
    }

    get order_book() {
        return this._orderbook;
    }

    get my_orders() {
        return this._myorders;
    }

    get is_trading() {
        return this._timer !== null;
    }

    /**
     * Starts trading with the bot.
     * @param options
     * @param options.interval the length of time (in ms) between firing the strategy (default: 1000ms)
     * @returns {Promise}
     */
    start_trading(options) {
        const self = this;
        options = options || {};
        return self.stop_trading({ cancel: false }).then(() => {
            const interval = options.interval || 1000;
            self._timer = setInterval(self.execute_strategy.bind(self), interval);
            return Promise.resolve();
        });
    }

    /**
     * Stop the trading bot
     * @param options
     * @param options.cancel {boolean} if true, calls #cancel_all_orders before stopping
     * @returns {Promise}
     */
    stop_trading(options) {
        if (!this.is_trading) {
            return Promise.resolve();
        }
        options = options || { cancel: false };
        const self = this;
        let cancel = options.cancel ? self.cancel_all_orders() : Promise.resolve();
        return cancel.then(() => {
            clearInterval(this._timer);
            this._timer = null;
            return Promise.resolve();
        });
    }

    /**
     * Returns a promise to cancel an order
     * @param order_id {string}
     * @returns {Promise}
     */
    cancel_order(order_id) {
        return new Promise((resolve, reject) => {
            this.client.cancelOrder(order_id, (err, result) => {
                if (err) {
                    return reject(err);
                }
                resolve(result);
            })
        });
    }

    /**
     * Returns a promise to cancel all orders
     */
    cancel_all_orders() {
        return this.cancel_order(null);
    }

    execute_strategy() {
        const self = this;
        if (self.busy_executing) {
            self.log({ message: 'The last trade execution is still busy. Skipping this round' });
            return;
        }
        self.busy_executing = true;
        setImmediate(() => {
            self._execute_trading_strategy().then(() => {
                this.busy_executing = false;
            });
        });
    }

    /**
     * Sub-classes override this method to enact their trading strategy
     * @private
     * @returns {Promise}
     */
    _execute_trading_strategy() {
        return Promise.resolve();
    }

    get_default_ws_client(wss) {
        this.log({ message: 'Attempting to obtain websocket feed from ' + wss });
        let websocket = new CoinbaseExchange.WebsocketClient(this.product, wss);
        websocket.on('close', function() {
            setTimeout(function() {
                websocket.connect();
            }, 1000);
        });
        return websocket;
    }

    /**
     * Returns a promise for the latest ticker price. Does not update state
     */
    fetch_ticker() {
        let self = this;
        return new Promise((resolve, reject) => {
            self.client.getProductTicker((err, ticker) => {
                if (err) {
                    return reject(err);
                }
                resolve(ticker);
            })
        });
    }

    /**
     * Returns a promise for the order book. Does not update state
     * @returns {Promise}
     */
    fetch_orderbook() {
        let self = this;
        return new Promise((resolve, reject) => {
            self.client.getProductOrderBook({ level: 2 }, (err, order_book) => {
                if (err) {
                    return reject(err);
                }
                resolve(order_book);
            })
        });
    }

    /**
     * Returns a promise for the order book. Does not update state
     * @returns {Promise}
     */
    fetch_myorders() {
        let self = this;
        return new Promise((resolve, reject) => {
            self.client.getOrders((err, orders) => {
                if (err) {
                    return reject(err);
                }
                resolve(orders);
            })
        });
    }

    /**
     * Request all indicators to refresh themselves.
     */
    refresh_indicators() {
        const self = this;

        function update_item(promise, obj) {
            return promise.then(data => {
                obj.updated = new Date();
                obj.data = data;
                return data;
            }).catch(err => {
                obj.errors.push({
                    timestamp: new Date(),
                    error: err
                });
            })
        }

        update_item(self.fetch_ticker(), self._ticker);
        update_item(self.fetch_orderbook(), self._orderbook);
        update_item(self.fetch_myorders(), self._myorders);
    }
}

module.exports = TradingBot;<|endoftext|>


<commit_before>"use strict";

module.exports = array_storage_config;

function array_storage_config (bits, store) {
  var number_keys = require("../balanced_storage/sorted_number_keys");
  var storage = require("../balanced_storage/storage");

  return storage({
    keys: number_keys(bits),
    is_it: is_it,
    store: store,
    extend: extend,
    props: props
  });
}

function is_it (value) {
  return value instanceof Array;
}

function props (old_props, action, key) {
  var size = old_props.size || 0;
  if (typeof key === "string") {
    key = parseInt(key, 10);
  }

  size = Math.max(size, key + 1);

  return { size: size };
}

function extend (api, store) {
  api.push = push;
  api.pop = pop;
  api.filter = filter;
  api.slice = slice;

  api.size = 0;

  function push (value) {
    return api.set(api.size, value);
  }

  function filter (fn) {
    return api.reduce(function (result, value, key) {
      return (fn(value, key)
              ? result.push(value)
              : result);
    }, store([]));
  }

  function slice (start, end) {
    if (arguments.length === 1) {
      end = api.size;
    } else if (end < 0) {
      end = api.size + end;
    }

    return api.filter(function (_, key) {
      return key >= start && key < end;
    });
  }

  function pop () {
    var new_size = api.size - 1;

    return api.filter(function (_, key) {
      return key < new_size;
    });
  }
}
<commit_msg>Implement pop with slice.<commit_after>"use strict";

module.exports = array_storage_config;

function array_storage_config (bits, store) {
  var number_keys = require("../balanced_storage/sorted_number_keys");
  var storage = require("../balanced_storage/storage");

  return storage({
    keys: number_keys(bits),
    is_it: is_it,
    store: store,
    extend: extend,
    props: props
  });
}

function is_it (value) {
  return value instanceof Array;
}

function props (old_props, action, key) {
  var size = old_props.size || 0;
  if (typeof key === "string") {
    key = parseInt(key, 10);
  }

  size = Math.max(size, key + 1);

  return { size: size };
}

function extend (api, store) {
  api.push = push;
  api.pop = pop;
  api.filter = filter;
  api.slice = slice;

  api.size = 0;

  function push (value) {
    return api.set(api.size, value);
  }

  function filter (fn) {
    return api.reduce(function (result, value, key) {
      return (fn(value, key)
              ? result.push(value)
              : result);
    }, store([]));
  }

  function slice (start, end) {
    if (arguments.length === 1) {
      end = api.size;
    } else if (end < 0) {
      end = api.size + end;
    }

    return api.filter(function (_, key) {
      return key >= start && key < end;
    });
  }

  function pop () {
    return slice(0, -1);
  }
}
<|endoftext|>


<commit_before>const { list: validators } = require('../validators');
const { body, restore, template } = require('./template');
const { joinPath } = require('./');

function State(schema = {}, env) {
  Object.assign(this, {
    resolution: [0],
    context: [],
    entries: new Map(),
    env,
  });

  this.push(schema);
}

function generate(env, schema, state = new State(schema, env), options) {
  const tpl = template(state, options);
  tpl.visit(schema);

  const source = body(tpl, state, options);
  return restore(source, schema, options);
}

State.prototype = Object.assign(Object.create(Array.prototype), {
  // template related methods
  addEntry(url, schema) {
    if (typeof schema !== 'object') {
      return schema;
    }

    const options = { inner: true };
    const entry = this.entries.get(schema) || generate(this.env, schema, this, options);
    this.entries.set(schema, entry);
    this.revealReference(url);

    return this.context.push(entry);
  },
  addReference(url, schema) {
    const schemaIndex = this.indexOf(schema);
    if (schemaIndex !== -1 && schemaIndex !== this.length - 1) {
      // has already been added to process queue
      return this.context.push(url);
    }
    return false;
  },
  revealReference(url) {
    for (
      let doubled = this.context.indexOf(url);
      doubled !== -1;
      doubled = this.context.indexOf(url)
    ) {
      this.context[doubled] = this.context.length;
    }
  },
  reference(url) {
    const initialStateLength = this.length;

    const schema = this.resolve(url);
    const entry = this.addReference(url, schema) || this.addEntry(url, schema);

    const hasStateChanged = initialStateLength !== this.length;
    if (hasStateChanged) {
      this.length = this.resolution.pop();
    }

    return entry;
  },
  // pure scope resolution methods
  push(schema) {
    if (schema && schema.id && this.length) {
      this.resolution.push(this.length);
    }
    Array.prototype.push.call(this, schema);
  },
  ascend(uri) {
    const indexOfParent = this.resolution[this.resolution.length - 1];
    if (uri === '#') {
      return this[indexOfParent];
    }
    if (Object.prototype.hasOwnProperty.call(this, uri)) {
      return this.env.resolved[uri].schema;
    }

    const parentSchemaParts = this.slice(indexOfParent + 1)
      .map(({ id }) => id)
      .concat(uri);

    const subSchemaPath = joinPath(parentSchemaParts);
    const parentSchema = this.env.resolved[subSchemaPath].schema;

    return parentSchema;
  },
  descent(name, parentSchema) {
    let currentSchema = parentSchema;

    const components = name && name.split('/');
    while (components && components.length > 0) {
      const currentPath = decodeURIComponent(components[0].replace(/~1/g, '/').replace(/~0/g, '~'));
      if (!Object.prototype.hasOwnProperty.call(currentSchema, currentPath)) {
        throw new Error('Schema not found');
      }

      currentSchema = currentSchema[currentPath];
      components.shift();
    }

    return currentSchema;
  },
  resolve(reference) {
    if (reference === '#') {
      return 0;
    }
    if (typeof reference !== 'string') {
      return reference;
    }

    const referenceParts = reference.split(/#\/?/);
    const name = referenceParts[1];
    const parentReference = referenceParts[0] || '#';
    const parentSchema = this.ascend(parentReference);

    this.push(parentSchema);

    return this.descent(name, parentSchema);
  },
  visit(schema, tpl) {
    const initialStateLength = this.length;

    this.push(schema);
    validators.forEach(validator => validator(schema, tpl));
    this.length = initialStateLength;
  },
});

module.exports = {
  State,
  generate,
};
<commit_msg>refactor(state): Change ascend method to solve parentSchema<commit_after>const { list: validators } = require('../validators');
const { body, restore, template } = require('./template');
const { joinPath } = require('./');

function State(schema = {}, env) {
  Object.assign(this, {
    resolution: [0],
    context: [],
    entries: new Map(),
    env,
  });

  this.push(schema);
}

function generate(env, schema, state = new State(schema, env), options) {
  const tpl = template(state, options);
  tpl.visit(schema);

  const source = body(tpl, state, options);
  return restore(source, schema, options);
}

State.prototype = Object.assign(Object.create(Array.prototype), {
  // template related methods
  addEntry(url, schema) {
    if (typeof schema !== 'object') {
      return schema;
    }

    const options = { inner: true };
    const entry = this.entries.get(schema) || generate(this.env, schema, this, options);
    this.entries.set(schema, entry);
    this.revealReference(url);

    return this.context.push(entry);
  },
  addReference(url, schema) {
    const schemaIndex = this.indexOf(schema);
    if (schemaIndex !== -1 && schemaIndex !== this.length - 1) {
      // has already been added to process queue
      return this.context.push(url);
    }
    return false;
  },
  revealReference(url) {
    for (
      let doubled = this.context.indexOf(url);
      doubled !== -1;
      doubled = this.context.indexOf(url)
    ) {
      this.context[doubled] = this.context.length;
    }
  },
  reference(url) {
    const schema = this.resolve(url);
    const entry = this.addReference(url, schema) || this.addEntry(url, schema);

    return entry;
  },
  // pure scope resolution methods
  push(schema) {
    if (schema && schema.id && this.length) {
      this.resolution.push(this.length);
    }
    Array.prototype.push.call(this, schema);
  },
  /**
   * @name ascend
   * @type {function}
   * @description
   * Search for a parent schema by uri reference.
   * Iterates over the chain of schemas.
   * @param {string} uri
   * @returns {object} parentSchema
   */
  ascend(uri) {
    const indexOfParent = this.resolution[this.resolution.length - 1];
    let parentSchema;

    if (uri === '#') {
      parentSchema = this[indexOfParent];
    } else {
      const parentSchemaParts = this.slice(indexOfParent + 1)
        .map(({ id }) => id)
        .concat(uri);

      const subSchemaPath = joinPath(parentSchemaParts);
      parentSchema = this.env.resolved[subSchemaPath].schema;
    }

    this.push(parentSchema);
    return parentSchema;
  },
  descent(name, parentSchema) {
    let currentSchema = parentSchema;

    const components = name && name.split('/');
    while (components && components.length > 0) {
      const currentPath = decodeURIComponent(components[0].replace(/~1/g, '/').replace(/~0/g, '~'));
      if (!Object.prototype.hasOwnProperty.call(currentSchema, currentPath)) {
        throw new Error(`Schema ${name} not found`);
      }

      currentSchema = currentSchema[currentPath];
      components.shift();
    }

    return currentSchema;
  },
  resolve(reference) {
    if (reference === '#') {
      return 0;
    }
    if (typeof reference !== 'string') {
      return reference;
    }

    const referenceParts = reference.split(/#\/?/);
    const name = referenceParts[1];
    const parentReference = referenceParts[0] || '#';
    const parentSchema = this.ascend(parentReference);

    return this.descent(name, parentSchema);
  },
  visit(schema, tpl) {
    const initialStateLength = this.length;
    const initialResolutionLength = this.resolution.length;
    this.push(schema);

    validators.forEach(validator => validator(schema, tpl));

    this.length = initialStateLength;
    this.resolution.length = initialResolutionLength;
  },
});

module.exports = {
  State,
  generate,
};
<|endoftext|>