git ssb

0+

Piet / ssb-loomio



Tree: 499687916fec256f9f5439cc8479674da2ce180d

Files: 499687916fec256f9f5439cc8479674da2ce180d / poll / async / get.js

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

Built with git-ssb-web