Files: 32b164d60557329be7e8cfcbcffc9b0644742e2b / feed / obs / thread.js
2473 bytesRaw
1 | var nest = require('depnest') |
2 | var pull = require('pull-stream') |
3 | var pullCat = require('pull-cat') |
4 | var sort = require('ssb-sort') |
5 | var ref = require('ssb-ref') |
6 | var { map, computed } = require('mutant') |
7 | |
8 | exports.needs = nest({ |
9 | 'sbot.pull.links': 'first', |
10 | 'sbot.async.get': 'first', |
11 | 'lib.obs.pullLookup': 'first', |
12 | 'message.sync.unbox': 'first' |
13 | }) |
14 | |
15 | exports.gives = nest('feed.obs.thread') |
16 | |
17 | exports.create = function (api) { |
18 | return nest('feed.obs.thread', function (rootId, {branch}) { |
19 | if (!ref.isLink(rootId)) throw new Error('an id must be specified') |
20 | |
21 | var rootMessageStream = pull( |
22 | pull.values([rootId]), |
23 | pull.asyncMap((key, cb) => { |
24 | return api.sbot.async.get(key, (err, value) => cb(err, {key, value})) |
25 | }) |
26 | ) |
27 | |
28 | var messageLookup = api.lib.obs.pullLookup(pull( |
29 | pullCat([ |
30 | rootMessageStream, |
31 | api.sbot.pull.links({ rel: branch ? 'branch' : 'root', dest: rootId, keys: true, values: true, live: true }) |
32 | ]), |
33 | unboxIfNeeded() |
34 | ), 'key') |
35 | |
36 | var orderedIds = computed(messageLookup, (lookup) => { |
37 | var msgs = Object.keys(lookup).map(k => lookup[k]) |
38 | return sort(msgs).map(getKey) |
39 | }) |
40 | |
41 | var messages = map(orderedIds, (id) => { |
42 | return messageLookup.get(id) |
43 | }) |
44 | |
45 | var result = { |
46 | messages, |
47 | lastId: computed(messages, (messages) => { |
48 | var last = messages[messages.length - 1] |
49 | if (last) { |
50 | return last.key |
51 | } |
52 | }), |
53 | rootId: computed(messages, (messages) => { |
54 | if (branch && messages.length) { |
55 | return messages[0].value.content.root |
56 | } else { |
57 | return rootId |
58 | } |
59 | }), |
60 | branchId: computed(messages, (messages) => { |
61 | if (branch) { |
62 | return rootId |
63 | } |
64 | }), |
65 | previousKey: function (msg) { |
66 | return PreviousKey(result.messages, msg) |
67 | } |
68 | } |
69 | |
70 | result.sync = messageLookup.sync |
71 | |
72 | return result |
73 | }) |
74 | |
75 | function unboxIfNeeded () { |
76 | return pull.map(function (msg) { |
77 | if (msg.sync || (msg.value && typeof msg.value.content === 'object')) { |
78 | return msg |
79 | } else { |
80 | return api.message.sync.unbox(msg) |
81 | } |
82 | }) |
83 | } |
84 | } |
85 | |
86 | function getKey (msg) { |
87 | return msg.key |
88 | } |
89 | |
90 | function PreviousKey (collection, item) { |
91 | return computed(collection, (c) => { |
92 | var index = collection.indexOf(item) |
93 | if (~index) { |
94 | var previous = c[index - 1] |
95 | if (previous) { |
96 | return previous.key |
97 | } |
98 | } |
99 | }) |
100 | } |
101 |
Built with git-ssb-web