git ssb

1+

Dominic / secure-scuttlebutt



Tree: 3a87ab0f145263cab848f87d3125febdc5561b9a

Files: 3a87ab0f145263cab848f87d3125febdc5561b9a / related.js

1922 bytesRaw
1var compare = require('typewiselite')
2var pull = require('pull-stream')
3
4function isString (s) {
5 return 'string' === typeof s
6}
7
8function all (stream) {
9 return function (cb) {
10 pull(stream, pull.collect(cb))
11 }
12}
13
14module.exports = function (db) {
15 return function (opts, cb) {
16 if(isString(opts)) opts = {key: opts}
17 if(!opts) throw new Error('opts *must* be object')
18 var key = opts.id || opts.key
19 var depth = opts.depth || Infinity
20 var seen = {}
21
22 //filter a list of rel, used to avoid 'branch' rel in patchwork,
23 //which causes messages to be queried twice.
24 var n = 1
25 var msgs = {key: key, value: null}
26 db.get(key, function (err, msg) {
27 msgs.value = msg
28 if (err && err.notFound)
29 err = null // ignore not found
30 done(err)
31 })
32
33 related(msgs, depth)
34
35 function related (msg, depth) {
36 if(depth <= 0) return
37 if (n<0) return
38 n++
39 all(db.links({dest: msg.key, rel: opts.rel, keys: true, values:true, meta: false, type:'msg'}))
40 (function (err, ary) {
41 if(ary && ary.length) {
42 msg.related = ary = ary.sort(function (a, b) {
43 return compare(a.value.timestamp, b.value.timestamp) || compare(a.key, b.key)
44 }).filter(function (msg) {
45 if(seen[msg.key]) return
46 return seen[msg.key] = true
47 })
48 ary.forEach(function (msg) { related (msg, depth - 1) })
49 }
50 done(err)
51 })
52 }
53
54 function count (msg) {
55 if(!msg.related)
56 return msg
57 var c = 0
58 msg.related.forEach(function (_msg) {
59 if(opts.parent) _msg.parent = msg.key
60 c += 1 + (count(_msg).count || 0)
61 })
62 if(opts.count) msg.count = c
63 return msg
64 }
65
66 function done (err) {
67 if(err && n > 0) {
68 n = -1
69 return cb(err)
70 }
71 if(--n) return
72 cb(null, count(msgs))
73 }
74 }
75}
76
77

Built with git-ssb-web