diffusion
Version:
Diffusion JavaScript client
164 lines (130 loc) • 5.23 kB
JavaScript
var _implements = require('util/interface')._implements;
var Emitter = require('events/emitter');
var Result = require('events/result');
var DataTypes = require('../../node_modules/data/datatypes');
var Services = require('services/services');
var parseSelector = require('topics/topic-selector-parser');
var SubscriptionProxy = require('features/topics/subscription-proxy');
var FetchStream = require('features/topics/fetch-stream');
var FetchRequest = require('features/topics/fetch-request');
var Topics = require('../../features/topics');
var CloseReason = require('client/close-reason');
var requireNonNull = require('util/require-non-null');
var logger = require('util/logger').create('Session');
module.exports = _implements(Topics, function TopicsImpl(internal) {
var unsubscribe = internal.getServiceLocator().obtain(Services.UNSUBSCRIBE);
var subscribe = internal.getServiceLocator().obtain(Services.SUBSCRIBE);
var fetch = internal.getServiceLocator().obtain(Services.FETCH);
var streamRegistry = internal.getStreamRegistry();
this.unsubscribe = function(topic) {
var emitter = new Emitter();
var result = new Result(emitter);
var selector;
try {
selector = (arguments.length>1)
? parseSelector(Array.prototype.slice.call(arguments))
: parseSelector(topic);
} catch (err) {
emitter.error(err);
return result;
}
if (internal.checkConnected(emitter)) {
var unsubscribeCallback = function(err) {
if (err) {
logger.debug('Unsubscribe failed', topic);
emitter.error(err);
} else {
logger.debug('Unsubscribe complete', topic);
emitter.emit('complete');
}
};
logger.debug('Unsubscribing', topic);
unsubscribe.send(selector, unsubscribeCallback);
}
return result;
};
this.fetch = function(selector) {
logger.debug('Fetch request for: ', selector);
requireNonNull(selector, "Selector");
selector = (arguments.length>1)
? parseSelector(Array.prototype.slice.call(arguments))
: parseSelector(selector);
var emitter = new Emitter();
var stream = new FetchStream(emitter);
if (internal.checkConnected(emitter)) {
var cid = internal.getConversationSet().newConversation({
onOpen : function() {
emitter.emit('open');
},
onResponse : function(cid, message) {
var content = message.data;
var path = message.topic;
if (path) {
emitter.emit('value', content, path);
return false;
} else if (content.length === 1 && content[0] === 1) {
emitter.close();
return true;
} else {
emitter.error(new Error("Unexpected end of fetch stream"));
return true;
}
},
onDiscard : function(cid, reason) {
if (reason instanceof CloseReason) {
emitter.close();
} else {
emitter.error(reason);
}
}
});
fetch.send({
cid : cid,
selector : selector
}, function(err) {
if (err) {
emitter.error(err);
}
});
}
return stream;
};
this.fetchRequest = function() {
return new FetchRequest(internal);
};
this.select = function (topic) {
var emitter = new Emitter();
var result = new Result(emitter);
logger.debug('Subscribing', topic);
var selector = (arguments.length>1)
? parseSelector(Array.prototype.slice.call(arguments))
: parseSelector(topic);
if (internal.checkConnected(emitter)) {
subscribe.send(selector, function (err) {
if (!err) {
emitter.emit('complete');
}
else {
emitter.error(err);
}
});
}
return result;
};
this.addStream = function (topic, datatype) {
if (arguments.length !== 2) {
throw new Error("Both topic selector and value type are needed");
}
if (!datatype || DataTypes.get(datatype)) {
throw new Error('Data type required');
}
var selector = parseSelector(topic);
return new SubscriptionProxy(streamRegistry, selector, false).subscription.asType(datatype);
};
this.addFallbackStream = function(datatype) {
if (!datatype || DataTypes.get(datatype)) {
throw new Error('Data type required');
}
return new SubscriptionProxy(streamRegistry, null, true).subscription.asType(datatype);
};
});