More voting stuff, start moving to typescript

This commit is contained in:
Mikah Chapman
2021-03-14 21:02:22 -06:00
parent 4ad8380f55
commit 185789baad
8 changed files with 1697 additions and 32 deletions

89
poll-master.ts Normal file
View File

@@ -0,0 +1,89 @@
const polls: Map<string, Poll> = new Map<string, Poll>()
export function registerNewPoll(key, maxVotes, onComplete, onNoResult): void {
polls.set(key, new Poll(maxVotes, onComplete, onNoResult))
console.log("created poll", key)
}
export function getNewPoll<T>(maxVotes: number, onComplete: (result: T, votes: Map<string, T>) => void, onNoResult: (votes: Map<string, T>) => void) {
return new Poll<T>(maxVotes, onComplete, onNoResult)
}
export function voteInPoll(key, voterId, vote): void {
if (polls.has(key)) {
const poll = polls.get(key)
poll.vote(`${voterId}`, vote)
const result = poll.isMajorityReached()
if (result) {
poll.onComplete(result, poll.votes)
delete polls[key]
console.log("vote finished", key, result)
} else if (poll.currentVotes === poll.maxVotes) {
poll.onNoResult(poll.votes)
delete polls[key]
console.log("vote inconclusive", key)
}
}
}
function isMajorityReached_dep(poll): any {
const minimumConsensus = Math.ceil(poll.maxVotes * 0.5)
const voteTally = {}
for (const vote in poll.votes) {
if (vote != null) {
if (voteTally.hasOwnProperty(poll.votes[vote])) {
voteTally[poll.votes[vote]]++
} else {
voteTally[poll.votes[vote]] = 1
}
}
if (voteTally[poll.votes[vote]] >= minimumConsensus) {
return vote
}
}
return null
}
class Poll<T> {
public currentVotes = 0;
public votes = new Map<string, T>()
constructor(public readonly maxVotes: number, public onComplete: (result: any, votes: Map<string, T>) => void, public onNoResult: (votes: Map<string, T>) => void) {
}
vote(voterId: string, vote: T): void {
this.currentVotes++
this.votes.set(voterId, vote)
this.checkVotes()
}
skipVote(voterId: string): void {
this.currentVotes++
this.checkVotes()
}
private checkVotes(): void {
const minimumConsensus = Math.ceil(this.maxVotes * 0.5)
const voteTally = new Map<T, number>()
this.votes.forEach((vote, voter) => {
// Allow for null votes, can't have a null key in a map
const normalizedVote = vote == null ? new T() : vote
if (voteTally.has(normalizedVote)) {
voteTally.set(normalizedVote, voteTally.get(normalizedVote) + 1)
} else {
voteTally.set(normalizedVote, 1)
}
if (voteTally.get(normalizedVote) >= minimumConsensus) {
this.onComplete(vote, this.votes)
}
})
if (this.currentVotes === this.maxVotes) {
this.onNoResult(this.votes)
}
}
}
module.exports = {
registerNewPoll,
voteInPoll
}