git ssb

7+

dinoworm ๐Ÿ› / patchcore



Tree: 452ca9b83a7f4a1dc4fd6398dd62555e98c8fe5b

Files: 452ca9b83a7f4a1dc4fd6398dd62555e98c8fe5b / contact / obs.js

2748 bytesRaw
1var nest = require('depnest')
2var MutantPullReduce = require('mutant-pull-reduce')
3var ref = require('ssb-ref')
4
5exports.needs = nest({
6 'sbot.pull.query': 'first',
7 'keys.sync.id': 'first'
8})
9
10exports.gives = nest({
11 'contact.obs': ['following', 'followers'],
12 'sbot.hook.feed': true
13})
14
15exports.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 (!ref.isFeed(id)) throw new Error('a feed id must be specified')
36 if (!followingCache[id]) {
37 followingCache[id] = reduce(api.sbot.pull.query({
38 query: [
39 makeQuery(id, { $prefix: '@' }),
40 {'$map': {
41 id: ['value', 'content', 'contact'],
42 value: ['value', 'content', 'following'],
43 timestamp: 'timestamp'
44 }}
45 ],
46 live: true
47 }))
48 }
49 return followingCache[id]
50 }
51
52 function followers (id) {
53 if (!ref.isFeed(id)) throw new Error('a feed id must be specified')
54 if (!followerCache[id]) {
55 followerCache[id] = reduce(api.sbot.pull.query({
56 query: [
57 makeQuery({ $prefix: '@' }, id),
58 {'$map': {
59 id: ['value', 'author'],
60 value: ['value', 'content', 'following'],
61 timestamp: 'timestamp'
62 }}
63 ],
64 live: true
65 }))
66 }
67 return followerCache[id]
68 }
69}
70
71function reduce (stream) {
72 var newestValues = {}
73 return MutantPullReduce(stream, (result, item) => {
74 if (!ref.isFeed(item.id)) return result // invalid message, skip this item
75 newestValues[item.id] = newestValues[item.id] || 0
76 if (newestValues[item.id] < item.timestamp) {
77 newestValues[item.id] = item.timestamp
78 if (item.value != null) {
79 if (item.value) {
80 result.add(item.id)
81 } else {
82 result.delete(item.id)
83 }
84 }
85 }
86 return result
87 }, {
88 startValue: new Set()
89 })
90}
91
92function makeQuery (a, b) {
93 return {'$filter': {
94 value: {
95 author: a,
96 content: {
97 type: 'contact',
98 contact: b
99 }
100 }
101 }}
102}
103
104function isContact (msg) {
105 return msg.value && msg.value.content && msg.value.content.type === 'contact'
106}
107

Built with git-ssb-web