UNPKG

diffusion

Version:

Diffusion JavaScript client

164 lines (130 loc) 5.23 kB
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); }; });