git ssb

10+

Matt McKegg / patchwork



Tree: 01436b0a000173e48f00729b2c1f7b5b3cc4243d

Files: 01436b0a000173e48f00729b2c1f7b5b3cc4243d / modules / sbot.js

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

Built with git-ssb-web