blob: 7def41647e56883559e6ca36bb10f1c8805d60bc [file] [log] [blame]
Ali Ghassemi5b408882015-01-16 14:58:00 -08001var mercury = require('mercury');
2var EventEmitter = require('events').EventEmitter;
3
4var freeze = require('../../lib/mercury/freeze');
5
6var namespaceService = require('../namespace/service');
7var smartService = require('../smart/service');
8
9var log = require('../../lib/log')('services:recommendations:service');
10
11var LEARNER_KEY = 'learner-shortcut';
12var MAX_NUM_RECOMMENDATIONS = 10;
13
14module.exports = {
15 getAll: getAll
16};
17
18// Singleton state for all the bookmarks.
19var recommendationsObs = mercury.array([]);
20
21smartService.loadOrCreate(
22 LEARNER_KEY,
23 smartService.constants.LEARNER_SHORTCUT, {
24 k: MAX_NUM_RECOMMENDATIONS
25 }
26).catch(function(err) {
27 log.error(err);
28});
29
30/*
31 * Gets all the namespace items that are recommended based on our learning agent
32 * As new recommendations become available/removed the observable array will
33 * change to reflect the changes.
34 *
35 * The observable result has an events property which is an EventEmitter
36 * and emits 'end', 'itemError' events.
37 *
38 * @return {Promise.<mercury.array>} Promise of an observable array
39 * of recommended items
40 */
41function getAll() {
42
43 // Empty out the array
44 recommendationsObs.splice(0, recommendationsObs.getLength());
45 var immutableRecommendationsObs = freeze(recommendationsObs);
46 immutableRecommendationsObs.events = new EventEmitter();
47
48 return smartService.predict(LEARNER_KEY).then(getRecommendationItems);
49
50 function getRecommendationItems(recs) {
51 var allItems = recs.map(function(rec) {
52 var name = rec.item;
53 return addNamespaceItem(name).catch(function(err) {
54 immutableRecommendationsObs.events.emit('itemError', {
55 name: name,
56 error: err
57 });
58 log.error('Failed to create item for "' + name + '"', err);
59 });
60 });
61
62 Promise.all(allItems).then(function() {
63 immutableRecommendationsObs.events.emit('end');
64 }).catch(function() {
65 immutableRecommendationsObs.events.emit('end');
66 });
67
68 return immutableRecommendationsObs;
69 }
70}
71
72/*
73 * Gets the namespace items for a name and adds it to the observable array
74 */
75function addNamespaceItem(name) {
76 return namespaceService.getNamespaceItem(name)
77 .then(function(item) {
78 recommendationsObs.push(item);
79 });
80}