diffusion
Version:
Diffusion JavaScript client
167 lines (135 loc) • 7.13 kB
JavaScript
var _implements = require('util/interface')._implements;
var Services = require('services/services');
var Emitter = require('events/emitter');
var Result = require('events/result');
var CommandService = require('client/command-service');
var registration = require('control/registration');
var api = require('../../features/topic-notifications');
var logger = require('util/logger').create('Session.Notifications');
var parseSelector = require('topics/topic-selector-parser');
module.exports = _implements(api.TopicNotifications, function TopicNotificationsImpl(internal) {
var serviceLocator = internal.getServiceLocator();
var conversationSet = internal.getConversationSet();
var TOPIC_NOTIFICATION_SELECTION = serviceLocator.obtain(Services.TOPIC_NOTIFICATION_SELECTION);
var TOPIC_NOTIFICATION_DESELECTION = serviceLocator.obtain(Services.TOPIC_NOTIFICATION_DESELECTION);
var TOPIC_NOTIFICATION_DEREGISTRATION = serviceLocator.obtain(Services.TOPIC_NOTIFICATION_DEREGISTRATION);
var serviceRegistry = internal.getServiceRegistry();
this.TopicNotificationType = api.TopicNotificationType;
var eventService = CommandService.create(function(internal, request, callback) {
callback.respond();
internal.getConversationSet().respond(request.cid, request);
});
serviceRegistry.add(Services.TOPIC_NOTIFICATION_EVENTS, eventService);
serviceRegistry.add(Services.TOPIC_DESCENDANT_EVENTS, eventService);
this.addListener = function (listener) {
var emitter = new Emitter();
var result = new Result(emitter);
if (!listener) {
emitter.error(new Error('Topic Notification Listener is null or undefined'));
return result;
}
if (internal.checkConnected(emitter)) {
logger.debug('Adding Topic Notification Listener');
var adapter = {
active : function(close, cid) {
logger.debug('Topic Notification Listener active');
var topicNotificationRegistration = {
select: function (topicSelector) {
var selectEmitter = new Emitter();
var selectResult = new Result(selectEmitter);
var selector;
if (!topicSelector) {
selectEmitter.error(new Error('No topic selector provided'));
return selectResult;
}
try {
selector = (arguments.length>1)
? parseSelector(Array.prototype.slice.call(arguments))
: parseSelector(topicSelector);
} catch (err) {
selectEmitter.error(err);
return selectResult;
}
TOPIC_NOTIFICATION_SELECTION.send({ cid : cid, selector: selector },
function(err) {
if (err) {
conversationSet.discard(cid, err);
selectEmitter.error(err);
} else {
selectEmitter.emit('complete');
}
});
return selectResult;
},
deselect: function (topicSelector) {
var deselectEmitter = new Emitter();
var deselectResult = new Result(deselectEmitter);
var selector;
if (!topicSelector) {
deselectEmitter.error(new Error('No topic selector provided'));
return deselectResult;
}
try {
selector = (arguments.length>1)
? parseSelector(Array.prototype.slice.call(arguments))
: parseSelector(topicSelector);
} catch (err) {
deselectEmitter.error(err);
return deselectResult;
}
TOPIC_NOTIFICATION_DESELECTION.send({ cid : cid, selector: selector },
function(err) {
if (err) {
conversationSet.discard(cid, err);
deselectEmitter.error(err);
} else {
deselectEmitter.emit('complete');
}
});
return deselectResult;
},
close: function() {
TOPIC_NOTIFICATION_DEREGISTRATION.send({ cid : cid }, function(err, response) {
if (err) {
conversationSet.discard(cid, err);
logger.debug('Error with topic notification deregistration: ', err);
} else {
listener.onClose();
conversationSet.respondIfPresent(cid, response);
}
});
}
};
emitter.emit('complete', topicNotificationRegistration);
},
respond : function(message) {
if (message.isDescendantEvent) {
listener.onDescendantNotification(message.path, message.type);
} else {
listener.onTopicNotification(
message.path,
message.specification,
message.type);
}
},
close : function(err) {
logger.debug('Topic Notification Listener closed');
if (err) {
listener.onError(err);
} else {
listener.onClose();
}
}
};
var cid = conversationSet.newConversation(
registration.responseHandler(internal, adapter, TOPIC_NOTIFICATION_DEREGISTRATION.send));
var emitterProxy = {
emit : function() {
// no-op because we pass the registration in the conversation handler
}
};
registration.registrationCallback(conversationSet, cid, emitterProxy)();
}
return result;
};
});