git ssb

0+

Piet / ssb-loomio



Tree: 19874c0c0d66afbcbbf49555bb33b9b4de8909e4

Files: 19874c0c0d66afbcbbf49555bb33b9b4de8909e4 / poll / async / get.js

2699 bytesRaw
1const pull = require('pull-stream')
2const sort = require('ssb-sort')
3const { isPoll, isPosition, isChooseOnePoll, isChooseOnePosition } = require('ssb-poll-schema')
4isPoll.chooseOne = isChooseOnePoll
5isPosition.chooseOne = isChooseOnePosition
6const { ERROR_POSITION_TYPE } = require('../../types')
7const getResults = require('../../position/sync/chooseOneResults')
8const getMsgContent = require('../../lib/getMsgContent')
9
10module.exports = function (server) {
11 return function get (key, cb) {
12 server.get(key, (err, value) => {
13 if (err) return cb(err)
14
15 var poll = { key, value }
16 if (!isPoll(poll)) return cb(new Error('scuttle-poll could not fetch, key provided was not a valid poll key'))
17
18 pull(
19 createBacklinkStream(key),
20 pull.collect((err, msgs) => {
21 if (err) return cb(err)
22
23 cb(null, decoratedPoll(poll, msgs))
24 })
25 )
26 })
27 }
28
29 function createBacklinkStream (key) {
30 var filterQuery = {
31 $filter: {
32 dest: key
33 }
34 }
35
36 return server.backlinks.read({
37 query: [filterQuery],
38 index: 'DTA' // use asserted timestamps
39 })
40 }
41}
42
43function decoratedPoll (rawPoll, msgs = []) {
44 const {
45 author,
46 content: {
47 title,
48 body,
49 details: { type }
50 }
51 } = rawPoll.value
52
53 const poll = Object.assign({}, rawPoll, {
54 type,
55 author,
56 title,
57 body,
58
59 positions: [],
60 results: {},
61 errors: []
62
63 // publishPosition: TODO ? add pre-filled helper functions to the poll?
64 })
65
66 // TODO add missingContext warnings to each msg
67 msgs = sort(msgs)
68
69 poll.positions = msgs
70 .filter(msg => msg.value.content.root === poll.key)
71 .filter(isPosition[type])
72 .map(position => {
73 return decoratePosition({position, poll})
74 })
75
76 poll.errors = msgs
77 .filter(msg => msg.value.content.root === poll.key)
78 .filter(msg => isPosition(msg) && !isPosition[type](msg))
79 .map(position => {
80 return {
81 type: ERROR_POSITION_TYPE,
82 message: `Position responses need to be off the ${type} type for this poll`,
83 position
84 }
85 })
86
87 const {results, errors} = getResults({ poll, positions: poll.positions })
88 poll.results = results
89 poll.errors = poll.errors.concat(errors)
90
91 return poll
92}
93
94function decoratePosition ({position: rawPosition, poll: rawPoll}) {
95 var position = getMsgContent(rawPosition)
96 var poll = getMsgContent(rawPoll)
97
98 // NOTE this isn't deep enough to be a safe clone
99 var newPosition = Object.assign({}, rawPosition)
100
101 if (isPoll.chooseOne(poll)) {
102 var choiceIndex = position.details.choice
103 newPosition.choice = poll.details.choices[choiceIndex]
104 }
105 return newPosition
106}
107

Built with git-ssb-web