diffusion
Version:
Diffusion JavaScript client
104 lines (85 loc) • 3.42 kB
JavaScript
var ValueStreamImpl = require('features/topics/value-stream');
var ValueStreamAdapter = require('features/topics/value-stream-adapter');
var DataTypes = require('data/datatypes');
var TopicType = require('../../../topics/topics').TopicType;
var Emitter = require('events/emitter');
/**
* Internal proxy for Subscriptions with an underlying datatype.
*
* @param {StreamRegistry} registry - StreamRegistry
* @param {TopicSelector} selector - Topic selector
* @param {DataType} datatype - The datatype
* @param {Boolean} fallback - Whether this is a fallback stream or not
* @param {Function} callback - Optional callback for subscription notification
*/
module.exports = function ValueStreamProxy(registry, selector, datatype, fallback, callback) {
var emitter = new Emitter();
var stream = emitter.get();
var self = this;
var subscription = new ValueStreamImpl(registry, stream, selector);
var pending = true;
stream.on('close', function() {
registry.remove(self);
});
this.subscription = subscription;
this.emitter = emitter;
this.selects = function(specification) {
if (specification) {
if (specification.type === TopicType.TIME_SERIES) {
var eventType = DataTypes.get(specification.properties.TIME_SERIES_EVENT_VALUE_TYPE);
return eventType && eventType.canReadAs(datatype.valueClass);
} else {
return DataTypes.getByValue(specification.type).canReadAs(datatype.valueClass);
}
}
return false;
};
this.adapter = function(specification) {
if ((specification.type === TopicType.TIME_SERIES)
|| (specification.type === TopicType[datatype.name().toUpperCase()])) {
return this;
} else {
return new ValueStreamAdapter(this, datatype, specification.type);
}
};
this.onOpen = function() {
emitter.emit('open', subscription);
};
this.onDelta = function(topic, details, specification, received, delta, oldValue, newValue) {
emitter.emit('value', topic, specification, newValue, oldValue);
};
this.onValue = function(topic, details, specification, received, oldValue, newValue) {
emitter.emit('value', topic, specification, newValue, oldValue);
};
this.onSubscription = function(topic, details, specification) {
emitter.emit('subscribe', topic, specification);
};
this.onUnsubscription = function(topic, details, specification, reason) {
emitter.emit('unsubscribe', topic, specification, reason);
};
this.onSubscriptionError = function(error) {
emitter.error(error);
registry.remove(self);
};
if (callback) {
subscription.on('value', callback);
if (fallback) {
registry.addFallback(self);
} else {
registry.add(selector, self);
}
} else {
// Monkey-patch so that we will only register this stream if it is subsequently used
subscription.on = function(event, fn) {
if (pending) {
if (fallback) {
registry.addFallback(self);
} else {
registry.add(selector, self);
}
pending = false;
}
return stream.on.call(subscription, event, fn);
};
}
};