diffusion
Version:
Diffusion JavaScript client
108 lines (84 loc) • 2.25 kB
JavaScript
/*eslint valid-jsdoc: "off"*/
var functions = require('util/function');
var array = require('util/array');
var Stream = require('events/stream');
/**
* <P>
* An internal class to construct implementations of {@link events.Stream} with
* a privately scoped emit function.
* <P>
* This allows safe construction of event-based interfaces without exposing the
* means of emitting events.
*
* @class Emitter
*/
function Emitter(e, fn, events) {
var listeners = {};
var listener = function() { };
var closed = false;
var emit = function(event, args) {
args = args || [];
var dispatch = function(listener) {
functions.callWithArguments(listener, args);
};
process.nextTick(function() {
if (listeners[event]) {
listeners[event].forEach(dispatch);
}
});
listener(event, args);
};
// A safer, publicly exposed version of emit
var publicEmit = function(event) {
if (closed || !event) {
return;
}
var args = array.argumentsToArray(arguments);
args.shift();
emit(event, args);
};
var error = function(reason) {
emit('error', [reason]);
close();
};
var close = function(reason) {
if (closed) {
return;
}
closed = true;
emit('close', [reason]);
};
var stream = new Stream(listeners, error, close, events);
if (e !== undefined) {
stream.on(e, fn);
}
this.listen = function(fn) {
listener = fn;
};
this.get = function() {
return stream;
};
this.close = close;
this.error = error;
this.emit = publicEmit;
this.assign = function(instance) {
for (var k in stream) {
instance[k] = stream[k];
}
};
}
/**
* Create an emitter for an existing object instance.
*
* @param {Object} instance - The instance to assign to
* @returns {Emitter} The emitter for the provided instance
*/
Emitter.assign = function(instance) {
var emitter = new Emitter();
var s = emitter.get();
for (var k in s) {
instance[k] = s[k];
}
return emitter;
};
module.exports = Emitter;