git ssb

7+

dinoworm ๐Ÿ› / patchcore



Tree: f120707982df391596bae10f1144b72fe1a25960

Files: f120707982df391596bae10f1144b72fe1a25960 / contact / obs.js

3404 bytesRaw
1var nest = require('depnest')
2var { Value, Dict, computed } = require('mutant')
3var pull = require('pull-stream')
4var ref = require('ssb-ref')
5
6exports.needs = nest({
7 'sbot.pull.stream': 'first'
8})
9
10exports.gives = nest({
11 'contact.obs': ['following', 'followers'], //, 'blocking', 'blockers'],
12 'sbot.hook.publish': true
13})
14
15exports.create = function (api) {
16 var cacheLoading = false
17 var cache = Dict()
18 var sync = Value(false)
19
20 return nest({
21 'contact.obs': {
22 following: following,
23 followers: followers,
24 // blocking: (id) => values(get(id), 'blocking', true),
25 // blockers: (id) => values(get(id), 'blockers', true),
26 },
27 'sbot.hook.publish': function (msg) {
28 // TODO ???
29 // if (isContact(msg)) {
30 // // HACK: make interface more responsive when sbot is busy
31 // var source = msg.value.author
32 // var dest = msg.value.content.contact
33
34 // if (typeof msg.value.content.following === 'boolean') {
35 // update(source, {
36 // following: {
37 // [dest]: [msg.value.content]
38 // }
39 // })
40 // update(dest, {
41 // followers: {
42 // [source]: [msg.value.content]
43 // }
44 // })
45 // }
46 // if (typeof msg.value.content.blocking === 'boolean') {
47 // update(source, {
48 // blocking: {
49 // [dest]: [msg.value.content]
50 // }
51 // })
52 // update(dest, {
53 // blockers: {
54 // [source]: [msg.value.content]
55 // }
56 // })
57 // }
58 // }
59 }
60 })
61
62 function following (key) {
63 var obs = computed(get(key), state => {
64 return Object.keys(state)
65 .reduce((sofar, next) => {
66 if (state[next]) return [...sofar, next]
67 else return sofar
68 }, [])
69 })
70
71 obs.sync = sync
72 return obs
73 }
74
75 function followers (key) {
76 var obs = computed(cache, cache => {
77 return Object.keys(cache)
78 .reduce((sofar, next) => {
79 if (cache[next][key]) return [...sofar, next]
80 else return sofar
81 }, [])
82 })
83
84 obs.sync = sync
85 return obs
86 }
87
88 function loadCache () {
89 pull(
90 api.sbot.pull.stream(sbot => sbot.friends.stream({live: true})),
91 pull.drain(item => {
92 for (var source in item) {
93 if (ref.isFeed(source)) update(source, item[source])
94 }
95
96 if (!sync()) {
97 sync.set(true)
98 }
99 })
100 )
101 }
102
103 function update (sourceId, values) {
104 // ssb-friends: values = {
105 // keyA: true|null|false (friend, neutral, block)
106 // keyB: true|null|false (friend, neutral, block)
107 // }
108 var state = get(sourceId)
109 var lastState = state()
110 var changed = false
111 for (var targetId in values) {
112 if (values[targetId] != lastState[targetId]) {
113 lastState[targetId] = values[targetId]
114 changed = true
115 }
116 }
117
118 if (changed) {
119 state.set(lastState)
120 }
121 }
122
123 function get (id) {
124 if (!ref.isFeed(id)) throw new Error('Contact state requires an id!')
125 if (!cacheLoading) {
126 cacheLoading = true
127 loadCache()
128 }
129 if (!cache.has(id)) {
130 cache.put(id, Value({}))
131 }
132 return cache.get(id)
133 }
134}
135
136function isContact (msg) {
137 return msg.value && msg.value.content && msg.value.content.type === 'contact'
138}
139
140

Built with git-ssb-web