Files: 06f2cf64aba94839fa02b58ea578954fba561c5d / contact / obs.js
2562 bytesRaw
1 | var nest = require('depnest') |
2 | var MutantPullReduce = require('mutant-pull-reduce') |
3 | var ref = require('ssb-ref') |
4 | |
5 | exports.needs = nest({ |
6 | 'sbot.pull.query': 'first', |
7 | 'keys.sync.id': 'first' |
8 | }) |
9 | |
10 | exports.gives = nest({ |
11 | 'contact.obs': ['following', 'followers'], |
12 | 'sbot.hook.feed': true |
13 | }) |
14 | |
15 | exports.create = function (api) { |
16 | var followingCache = {} |
17 | var followerCache = {} |
18 | |
19 | return nest({ |
20 | 'contact.obs': { following, followers }, |
21 | 'sbot.hook.feed': function (msg) { |
22 | if (isContact(msg) && msg.timestamp) { |
23 | var author = msg.value.author |
24 | var contact = msg.value.content.contact |
25 | var following = msg.value.content.following |
26 | var from = followingCache[author] |
27 | var to = followerCache[contact] |
28 | if (from) from.push({id: contact, value: following, timestamp: msg.timestamp}) |
29 | if (to) to.push({id: author, value: following, timestamp: msg.timestamp}) |
30 | } |
31 | } |
32 | }) |
33 | |
34 | function following (id) { |
35 | if (!followingCache[id]) { |
36 | followingCache[id] = reduce(api.sbot.pull.query({ |
37 | query: [ |
38 | makeQuery(id, { $prefix: '@' }), |
39 | {'$map': { |
40 | id: ['value', 'content', 'contact'], |
41 | value: ['value', 'content', 'following'], |
42 | timestamp: 'timestamp' |
43 | }} |
44 | ], |
45 | live: true |
46 | })) |
47 | } |
48 | return followingCache[id] |
49 | } |
50 | |
51 | function followers (id) { |
52 | if (!followerCache[id]) { |
53 | followerCache[id] = reduce(api.sbot.pull.query({ |
54 | query: [ |
55 | makeQuery({ $prefix: '@' }, id), |
56 | {'$map': { |
57 | id: ['value', 'author'], |
58 | value: ['value', 'content', 'following'], |
59 | timestamp: 'timestamp' |
60 | }} |
61 | ], |
62 | live: true |
63 | })) |
64 | } |
65 | return followerCache[id] |
66 | } |
67 | } |
68 | |
69 | function reduce (stream) { |
70 | var newestValues = {} |
71 | return MutantPullReduce(stream, (result, item) => { |
72 | if (!ref.isFeed(item.id)) return |
73 | newestValues[item.id] = newestValues[item.id] || 0 |
74 | if (newestValues[item.id] < item.timestamp) { |
75 | newestValues[item.id] = item.timestamp |
76 | if (item.value != null) { |
77 | if (item.value) { |
78 | result.add(item.id) |
79 | } else { |
80 | result.delete(item.id) |
81 | } |
82 | } |
83 | } |
84 | return result |
85 | }, { |
86 | startValue: new Set() |
87 | }) |
88 | } |
89 | |
90 | function makeQuery (a, b) { |
91 | return {'$filter': { |
92 | value: { |
93 | author: a, |
94 | content: { |
95 | type: 'contact', |
96 | contact: b |
97 | } |
98 | } |
99 | }} |
100 | } |
101 | |
102 | function isContact (msg) { |
103 | return msg.value && msg.value.content && msg.value.content.type === 'contact' |
104 | } |
105 |
Built with git-ssb-web