Files: 04f70232848d0eb769abc879ff4af69e21fb677b / related.js
1922 bytesRaw
1 | var compare = require('typewiselite') |
2 | var pull = require('pull-stream') |
3 | |
4 | function isString (s) { |
5 | return 'string' === typeof s |
6 | } |
7 | |
8 | function all (stream) { |
9 | return function (cb) { |
10 | pull(stream, pull.collect(cb)) |
11 | } |
12 | } |
13 | |
14 | module.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