Files: 9ec71e984281e5ef4646b07b557b54375092fbcd / lib / lookup-roots.js
1624 bytesRaw
1 | const HLRU = require('hashlru') |
2 | const pull = require('pull-stream') |
3 | const getRoot = require('./get-root') |
4 | const extend = require('xtend') |
5 | |
6 | module.exports = function LookupRoots ({ ssb, cache }) { |
7 | cache = cache || HLRU(100) |
8 | return pull.asyncMap((msg, cb) => { |
9 | getRootMsg(msg, { ssb, cache }, (_, root) => { |
10 | if (root && root.key !== msg.key) { |
11 | cb(null, extend(msg, { |
12 | rootId: msg.key, root |
13 | })) |
14 | } else { |
15 | cb(null, extend(msg, { rootId: msg.key })) |
16 | } |
17 | }) |
18 | }) |
19 | } |
20 | |
21 | function getRootMsg (msg, { ssb = null, cache = null, visited = null }, cb) { |
22 | visited = visited || new Set() |
23 | visited.add(msg.key) |
24 | |
25 | const rootId = getRoot(msg) |
26 | if (!rootId) { |
27 | // we found the root! |
28 | return cb(null, msg) |
29 | } else { |
30 | getThruCache(rootId, { ssb, cache }, (_, root) => { |
31 | // HACK: the second one (type + root) is for backwards compatibility |
32 | if (msg.value.content.fork || (msg.value.content.root && msg.value.content.type === 'post')) { |
33 | // this message is a forked root |
34 | return cb(null, root) |
35 | } else if (visited.has(root.key)) { |
36 | // recursion detected, abort! |
37 | return cb(null, msg) |
38 | } else { |
39 | // go deeper |
40 | getRootMsg(root, { ssb, cache, visited }, cb) |
41 | } |
42 | }) |
43 | } |
44 | } |
45 | |
46 | function getThruCache (key, { ssb, cache }, cb) { |
47 | if (cache.has(key)) { |
48 | cb(null, cache.get(key)) |
49 | } else { |
50 | // don't do an ooo lookup |
51 | ssb.get({ id: key, raw: true, private: true }, (_, value) => { |
52 | const msg = { key, value } |
53 | if (msg.value) { |
54 | cache.set(key, msg) |
55 | } |
56 | cb(null, msg) |
57 | }) |
58 | } |
59 | } |
60 |
Built with git-ssb-web