git ssb

10+

Matt McKegg / patchwork



Tree: 99aead0a4c4797532b2986ba64d8c30f3d3c5993

Files: 99aead0a4c4797532b2986ba64d8c30f3d3c5993 / modules / sbot.js

4784 bytesRaw
1var pull = require('pull-stream')
2var ssbKeys = require('ssb-keys')
3var ref = require('ssb-ref')
4var path = require('path')
5var Reconnect = require('pull-reconnect')
6var InfoCache = require('../lib/info-cache')
7
8var config = require('../config')
9var keys = config.keys
10
11function Hash (onHash) {
12 var buffers = []
13 return pull.through(function (data) {
14 buffers.push('string' === typeof data
15 ? new Buffer(data, 'utf8')
16 : data
17 )
18 }, function (err) {
19 if(err && !onHash) throw err
20 var b = buffers.length > 1 ? Buffer.concat(buffers) : buffers[0]
21 var h = '&'+ssbKeys.hash(b)
22 onHash && onHash(err, h)
23 })
24}
25//uncomment this to use from browser...
26//also depends on having ssb-ws installed.
27//var createClient = require('ssb-lite')
28
29var createFeed = require('ssb-feed')
30var cache = CACHE = {}
31
32var connection_status = []
33var infoCache = InfoCache()
34
35var internal = {
36 getLatest: function (id, cb) {
37 sbot.getLatest(id, cb)
38 },
39 add: function (msg, cb) {
40 sbot.add(msg, cb)
41 }
42}
43
44var feed = createFeed(internal, keys, {remote: true})
45
46setImmediate((x) => {
47 connection_status.forEach(fn => fn())
48})
49
50var createClient = require('ssb-client')
51var sbot
52var rec = Reconnect(function (isConn) {
53 function notify (value) {
54 isConn(value); connection_status.forEach(function (fn) { fn(value) })
55 }
56
57 createClient(keys, {
58 manifest: require('patchbay/manifest.json'),
59 remote: config.remote
60 }, function (err, _sbot) {
61 if(err)
62 return notify(err)
63
64 sbot = _sbot
65 sbot.on('closed', function () {
66 sbot = null
67 notify(new Error('closed'))
68 })
69
70 notify()
71 })
72})
73
74module.exports = {
75 connection_status: connection_status,
76 get_id: function () {
77 return keys.id //sbot && sbot.id
78 },
79
80 //move cache into a separate plugin
81 get_likes: function (id) {
82 return infoCache.getLikes(id)
83 },
84 obs_channels: function () {
85 return infoCache.channels
86 },
87 update_cache: function (msg) {
88 infoCache.updateFrom(msg)
89 },
90 // ^^^
91
92 sbot_blobs_add: rec.sink(function (cb) {
93 return pull(
94 Hash(function (err, id) {
95 if(err) return cb(err)
96 //completely UGLY hack to tell when the blob has been sucessfully written...
97 var start = Date.now(), n = 5
98 ;(function next () {
99 setTimeout(function () {
100 sbot.blobs.has(id, function (err, has) {
101 if(has) return cb(null, id)
102 if(n--) next()
103 else cb(new Error('write failed'))
104 })
105 }, Date.now() - start)
106 })()
107 }),
108 sbot.blobs.add()
109 )
110 }),
111 sbot_links: rec.source(function (query) {
112 return sbot.links(query)
113 }),
114 sbot_links2: rec.source(function (query) {
115 return sbot.links2.read(query)
116 }),
117 sbot_query: rec.source(function (query) {
118 return sbot.query.read(query)
119 }),
120 sbot_log: rec.source(function (opts) {
121 return pull(
122 sbot.createLogStream(opts),
123 pull.through(function (e) {
124 CACHE[e.key] = CACHE[e.key] || e.value
125 infoCache.updateFrom(e)
126 })
127 )
128 }),
129 sbot_user_feed: rec.source(function (opts) {
130 return sbot.createUserStream(opts)
131 }),
132 sbot_get: rec.async(function (key, cb) {
133 if(CACHE[key] && CACHE[key].value) cb(null, CACHE[key].value)
134 else sbot.get(key, function (err, value) {
135 if(err) return cb(err)
136 CACHE[key] = {key, value}
137 cb(null, value)
138 })
139 }),
140 sbot_gossip_peers: rec.async(function (cb) {
141 sbot.gossip.peers(cb)
142 }),
143 //liteclient won't have permissions for this
144 sbot_gossip_connect: rec.async(function (opts, cb) {
145 sbot.gossip.connect(opts, cb)
146 }),
147 sbot_publish: rec.async(function (content, cb) {
148 if(content.recps)
149 content = ssbKeys.box(content, content.recps.map(function (e) {
150 return ref.isFeed(e) ? e : e.link
151 }))
152 else if(content.mentions)
153 content.mentions.forEach(function (mention) {
154 if(ref.isBlob(mention.link)) {
155 sbot.blobs.push(mention.link, function (err) {
156 if(err) console.error(err)
157 })
158 }
159 })
160
161 feed.add(content, function (err, msg) {
162 if(err) console.error(err)
163 else if(!cb) console.log(msg)
164 cb && cb(err, msg)
165 })
166 }),
167 sbot_whoami: rec.async(function (cb) {
168 sbot.whoami(cb)
169 }),
170 sbot_progress: rec.source(function () {
171 return sbot.replicate.changes()
172 }),
173 sbot_feed: rec.source(function (opts) {
174 return pull(
175 sbot.createFeedStream(opts),
176 pull.through(function (e) {
177 CACHE[e.key] = CACHE[e.key] || e.value
178 infoCache.updateFrom(e)
179 })
180 )
181 }),
182
183 //this can actually be implemented by filtering gossip.peers
184 sbot_list_local: rec.async(function (cb) {
185 cb(null, [])
186 //return sbot.local.list(cb)
187 })
188}
189

Built with git-ssb-web