Example #1
0
File: core.js Project: jedp/method
function Method(base) {
  /**
  Private Method is a callable private name that dispatches on the first
  arguments same named Method: Method(...rest) => rest[0][Method](...rest)
  Default implementation may be passed in as an argument.
  **/

  // Create an internal unique name if default implementation is passed,
  // use it's name as a name hint.
  var name = Name(base && base.name).toString()

  function dispatch() {
    // Method dispatches on type of the first argument.
    var target = arguments[0]
    // If first argument is `null` or `undefined` use associated property
    // maps for implementation lookups, otherwise use first argument itself.
    // Use default implementation lookup map if first argument does not
    // implements Method itself.
    var implementation = target === null ? Null[name] :
                         target === undefined ? Undefined[name] :
                         target[name] || Default[name]

    // If implementation not found there's not much we can do about it,
    // throw error with a descriptive message.
    if (!implementation)
      throw Error('Type does not implements Method')

    // If implementation is found delegate to it.
    return implementation.apply(implementation, arguments)
  }

  // Define default implementation.
  Default[name] = base

  // Define `Method.toString` returning private name, this hack will enable
  // Method definition like follows:
  // var foo = Method()
  // object[foo] = function() { /***/ }
  dispatch.toString = function() { return name }

  // Copy utility Methods for convenient API.
  dispatch.implement = implementMethod
  dispatch.define = defineMethod

  return dispatch
}
Example #2
0
/* vim:set ts=2 sw=2 sts=2 expandtab */
/*jshint asi: true undef: true es5: true node: true browser: true devel: true
         forin: true latedef: false globalstrict: true */
'use strict';

var Name = require('name')
var Method = require('method')


var core = require('./core'),
    accumulate = core.accumulate, accumulated = core.accumulated,
    end = core.end, convert = core.convert

var input = Name()
var consumers = Name()

function open(hub) {
  var source = hub[input]
  var hubConsumers = hub[consumers]
  hub[input] = null         // mark hub as open
  accumulate(source, function distribute(value) {
    var activeConsumers = hubConsumers.slice(0)
    var count = activeConsumers.length, index = 0
    while (index < count) {
      var consumer = activeConsumers[index++]
      var state = consumer.next(value, consumer.state)
      if (state && state.is === accumulated) {
        var position = hubConsumers.indexOf(consumer)
        if (position >= 0) hubConsumers.splice(position, 1)
        consumer.next(end(), consumer.state)
      } else {
Example #3
0
/* vim:set ts=2 sw=2 sts=2 expandtab */
/*jshint asi: true undef: true es5: true node: true browser: true devel: true
         forin: true latedef: false globalstrict: true */
'use strict';

var Name = require('name')
var Method = require('method')


var core = require('./core'),
    convert = core.convert, accumulate = core.accumulate,
    append = core.append, end = core.end

var hub = require('./hub')

var cached = Name()
var input = Name()

function isBuffering(cache) {
  return cache[cached] !== null
}

function buffer(cache) {
  var source = cache[input]
  var buffered = []
  cache[cached] = append(buffered, source)
  accumulate(source, function(value) {
    buffered.push(value)
    // If source is ended remove reference to the input
    // and replace internal cache with a simple buffered array.
    if (value && value.is === end) {