yannickschuchmann a7b81d5791 Add README documentation and refactor test suite
Replace minimal README with full project docs (setup, usage, architecture).
Remove trivial tests and add meaningful edge case coverage.
2026-03-08 20:39:15 +00:00
2026-03-08 18:01:28 +00:00
2026-03-08 18:01:28 +00:00
2026-03-08 18:01:28 +00:00
2026-03-08 18:01:28 +00:00
2026-03-08 18:01:28 +00:00
2026-03-08 18:01:28 +00:00
2026-03-08 18:01:28 +00:00

P2P Poll App

A peer-to-peer polling application where users can create polls, add options, and vote — all without a central server. Built for the Evocracy democratic coding research experiment.

How It Works

Data is synchronized directly between peers using Automerge CRDTs (Conflict-free Replicated Data Types). There is no backend database — every client holds a full copy of the poll document and changes merge automatically, even when made offline or concurrently.

Sync layers:

  • WebSocket (wss://sync.automerge.org) — cross-device sync via a public relay
  • BroadcastChannel — instant cross-tab sync within the same browser
  • IndexedDB — local persistence across page reloads and offline use

Requirements

  • Bun (standalone runtime, no Node.js needed)

Getting Started

bun install        # Install dependencies
bun run dev        # Start dev server (http://localhost:3000)

Usage

  1. Create a poll — Enter a title on the home page and click "Create"
  2. Share it — Copy the shareable link and send it to others
  3. Vote — Click an option to vote; click again to unvote
  4. Add options — Anyone with the link can add new poll options

Each browser gets a stable peer ID (stored in localStorage) so votes are tracked per-device and double-voting is prevented.

Tech Stack

Layer Technology
Runtime Bun
Framework Waku (React Server Components)
Styling Tailwind CSS v4
P2P sync Automerge + automerge-repo
Storage IndexedDB (client-side)

Project Structure

src/
├── pages/                  # Waku page router
│   ├── _root.tsx           # HTML document shell
│   ├── _layout.tsx         # Root layout + Providers
│   ├── index.tsx           # Home page (create/join polls)
│   └── poll/[id].tsx       # Poll view page
├── components/
│   ├── Providers.tsx       # Automerge Repo initialization
│   ├── HomeClient.tsx      # Create/join poll UI
│   ├── PollPageClient.tsx  # Poll ID validation
│   ├── PollView.tsx        # Poll display, voting, options
│   └── ConnectionStatus.tsx # P2P connection indicator
├── lib/
│   ├── types.ts            # Poll & PollOption interfaces
│   ├── repo.ts             # Automerge Repo singleton
│   ├── poll.ts             # Pure poll mutation functions
│   ├── peer.ts             # Peer ID management
│   └── __tests__/          # Unit tests
└── styles/
    └── global.css          # Tailwind CSS

Testing

bun test

Covers poll creation, voting/unvoting, double-vote prevention, option management, and peer ID persistence.

Architecture Notes

  • Pure business logic — Poll mutations in src/lib/poll.ts are pure functions, used inside Automerge's changeDoc() for CRDT-safe updates
  • No server state — The WebSocket relay only forwards sync messages; it never stores or processes poll data
  • Offline-first — The app works fully offline; changes sync when connectivity resumes
  • Conflict-free — Concurrent edits (e.g., two users voting at the same time) merge automatically without conflicts

Built With

This project was built in collaboration with Claude Code, Anthropic's agentic coding tool.

License

MIT

Description
No description provided
Readme 3.9 MiB