Skip to content

Collect Votes with MEDKit

MEDKit groups numeric viewer choices by a developer-defined vote ID. Use one ID per logical round so earlier submissions cannot be mistaken for current results.

Submit a vote

import Muxy from "@muxy/extensions-js";
Muxy.setup({ clientID: import.meta.env.VITE_MUXY_CLIENT_ID });
const medkit = new Muxy.SDK();
await medkit.loaded();

const pollID = "round-42-map-choice";
const result = await medkit.vote(pollID, 1);

console.log(`Accepted vote ${result.vote}; total votes: ${result.count}`);

vote(id, value) requires a string ID and numeric value. The resolved VoteData is the current aggregate plus the current user's vote when available.

Prefix an ID with global- only when votes should be shared across all channels using the extension. Otherwise, results are channel-scoped.

Read results

const voteData = await medkit.getVoteData(pollID);
console.log({
  count: voteData.count,
  sum: voteData.sum,
  mean: voteData.mean,
  stddev: voteData.stddev,
  optionOneVotes: voteData.specific[1] ?? 0,
  currentViewerVote: voteData.vote,
});

The 2.4.18 type is flat:

{
  "count": 1,
  "mean": 1,
  "specific": [0, 1, 0, 0, 0, 0],
  "stddev": 0,
  "sum": 1,
  "vote": 1
}
Field Meaning
count Number of counted votes
mean Average numeric value
specific Counts indexed by supported non-negative vote values
stddev Approximate standard deviation
sum Sum of numeric values
vote Current user's value when one exists

The package comments disagree about the exact indexed range represented by specific. Keep application choices in the displayed indices you have tested and rely on count, sum, mean, and stddev for other numeric values.

React to updates

listen() returns a handle, not a promise. The vote-update event payload is not strongly typed, so re-read the aggregate in the callback:

const handle = medkit.listen(`vote_update:${pollID}`, async () => {
  renderResults(await medkit.getVoteData(pollID));
});

window.addEventListener(
  "pagehide",
  () => medkit.unlisten(handle),
  { once: true },
);

Debounce rendering or requests if your interface can receive bursts of updates.

Retrieve vote logs

getFullVoteLogs(id) is admin-only and can return a large result. Each entry contains an identifier and numeric value.

const { result: entries } = await medkit.getFullVoteLogs(pollID);
const identifiersByValue = new Map();

for (const { identifier, value } of entries) {
  const identifiers = identifiersByValue.get(value) ?? [];
  identifiers.push(identifier);
  identifiersByValue.set(value, identifiers);
}

Do not expose vote logs to viewers or analytics. Prefer aggregate results unless an approved administrative workflow needs individual entries.