git ssb

0+

Piet / ssb-loomio



Tree: 0701482d7338e40c8d2785755d69295759fea46e

Files: 0701482d7338e40c8d2785755d69295759fea46e / poll / async / get.js

3297 bytesRaw
1const pull = require('pull-stream')
2const sort = require('ssb-sort')
3const getContent = require('ssb-msg-content')
4const { isPoll, isPosition, isChooseOnePoll, isChooseOnePosition } = require('ssb-poll-schema')
5isPoll.chooseOne = isChooseOnePoll
6isPosition.chooseOne = isChooseOnePosition
7const buildResults = require('../../results/sync/buildResults')
8const { CHOOSE_ONE, ERROR_POSITION_TYPE } = require('../../types')
9const publishChooseOnePosition = require('../../position/async/buildChooseOne')
10
11module.exports = function (server) {
12 return function get (key, cb) {
13 const myKey = server.id
14
15 server.get(key, (err, value) => {
16 if (err) return cb(err)
17
18 var poll = { key, value }
19 if (!isPoll(poll)) return cb(new Error('scuttle-poll could not get poll, key provided was not a valid poll key'))
20
21 pull(
22 createBacklinkStream(key),
23 pull.collect((err, msgs) => {
24 if (err) return cb(err)
25
26 cb(null, decoratePoll(poll, msgs, myKey))
27 })
28 )
29 })
30 }
31
32 function createBacklinkStream (key) {
33 var filterQuery = {
34 $filter: {
35 dest: key
36 }
37 }
38
39 return server.backlinks.read({
40 query: [filterQuery],
41 index: 'DTA' // use asserted timestamps
42 })
43 }
44}
45
46function decoratePoll (rawPoll, msgs = [], myKey) {
47 const {
48 author,
49 content: {
50 title,
51 body,
52 channel,
53 details: { type }
54 },
55 recps,
56 mentions
57 } = rawPoll.value
58
59 const poll = Object.assign({}, rawPoll, {
60 type,
61 author,
62 title,
63 body,
64 channel,
65 recps,
66 mentions,
67
68 actions: {
69 publishPosition
70 },
71 positions: [],
72 results: {},
73 errors: [],
74 decorated: true
75 })
76
77 function publishPosition (opts, cb) {
78 if (poll.type === CHOOSE_ONE) {
79 publishChooseOnePosition({
80 poll,
81 choice: opts.choice,
82 reason: opts.reason
83 }, cb)
84 }
85 }
86
87 // TODO add missingContext warnings to each msg
88 msgs = sort(msgs)
89
90 poll.positions = msgs
91 .filter(msg => msg.value.content.root === poll.key)
92 .filter(isPosition[type])
93 .map(position => {
94 return decoratePosition({position, poll})
95 })
96
97 poll.myPosition = poll.positions
98 .filter(p => p.value.author === myKey)
99 .sort((a, b) => {
100 return a.value.timestamp > b.value.timestamp ? -1 : +1
101 })[0]
102
103 poll.errors = msgs
104 .filter(msg => msg.value.content.root === poll.key)
105 .filter(msg => isPosition(msg) && !isPosition[type](msg))
106 .map(position => {
107 return {
108 type: ERROR_POSITION_TYPE,
109 message: `Position responses need to be off the ${type} type for this poll`,
110 position
111 }
112 })
113
114 const {results, errors} = buildResults({ poll, positions: poll.positions })
115 poll.results = results
116 poll.errors = poll.errors.concat(errors)
117
118 return poll
119}
120
121function decoratePosition ({position: rawPosition, poll: rawPoll}) {
122 var position = getContent(rawPosition)
123 var poll = getContent(rawPoll)
124
125 // NOTE this isn't deep enough to be a safe clone
126 var newPosition = Object.assign({}, rawPosition)
127 newPosition.reason = position.reason
128
129 if (isPoll.chooseOne(poll)) {
130 var choiceIndex = position.details.choice
131 newPosition.choice = poll.details.choices[choiceIndex]
132 }
133 return newPosition
134}
135

Built with git-ssb-web