From ba76c5df4936bd7692d776287ea734642dc7b52f Mon Sep 17 00:00:00 2001 From: 1ynx Date: Sun, 10 May 2026 20:40:14 +0200 Subject: [PATCH] * update readme --- README.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/sync.ts | 2 +- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0217c70..dcdcfd9 100644 --- a/README.md +++ b/README.md @@ -1 +1,56 @@ -# P2P Poll App \ No newline at end of file +# Polly - P2P Poll App + +A lightweight, real-time collaborative polling application that uses Yjs and WebRTC to allow multiple users to create options, vote, and see live results without a centralized database or back-end server. + +### 🚀 Features + +- Real-time Collaboration: Instant synchronization of poll titles, options, and votes across all connected peers using CRDTs (Conflict-free Replicated Data Types). +- P2P Connectivity: Uses WebRTC via y-webrtc for direct browser-to-browser communication. +- Dynamic Voting: * Add new options on the fly. + - Live-updating progress bars and vote tallies. + - Automatic sorting of options by vote count. +- Voting Deadline: A shared countdown timer (2 minutes) that locks the poll for all participants once expired. +- Awareness & Presence: A status bar showing connection health and the number of active peers currently in the room. +- Local Persistence: Uses y-indexeddb to save the poll state locally in your browser, ensuring data isn't lost if you refresh or lose connection. +- No Setup Required: Unique "rooms" are created via URL parameters, making it easy to share a link and start a poll instantly. + +### 🛠 Tech Stack + +- Language: TypeScript +- State Management: Yjs (Shared data types: Y.Doc, Y.Map, Y.Text) +- Networking: y-webrtc (WebRTC provider for Yjs) +- UI: Vanilla DOM manipulation (No heavy frameworks like React or Vue) + +### 💡 How It Works + +- Room Creation: When you open the app, it checks for a ?room= parameter. If none exists, it generates a unique ID and updates the URL. +- State Synchronization: The y-webrtc provider connects users with the same room ID. Any change to sync.options or sync.votes is propagated to all users. +- Local Reactivity: Components use .observe() and .observeDeep() on Yjs types to trigger a re-render of the UI whenever the shared state changes. +- Voting: Votes are stored in a Y.Map where the key is the User ID and the value is the Option ID. This ensures each user can only have one active vote at a time. + +You can simulate a second user by opening an incognito Tab. + +### 🔧 Installation, Development and Deployment + +- Install dependencies: + + ```npm install yjs y-webrtc y-indexeddb``` + +- Development: + + ```npm run dev``` + +- Deployment: + - The code currently uses an Y-Webrtc-Signaling-Server at localhost that starts with `npm run dev` for development (PORT=4444 npx y-webrtc ). + - To deploy the App, you need to set up a publicly available signaling server and set the address in the `synx.ts`. E.g. with Docker: + + ```version: '3.1' +services: + y-webrtc-signaling: + container_name: y-webrtc-signaling + image: funnyzak/y-webrtc-signaling:latest + restart: always + network_mode: bridge + ports: + - "4444:4444" + dns: 8.8.8.8``` \ No newline at end of file diff --git a/src/sync.ts b/src/sync.ts index ec65fcf..01cfec5 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -29,7 +29,7 @@ export function initSync(roomId: string): AppSync { : "offline"; const provider = new WebrtcProvider(roomId, doc,{ - signaling: ["ws://localhost:4444", "ws://lynxpi.ddns.net:4444"] + signaling: ["ws://localhost:4444"] }); const persistence = new IndexeddbPersistence(roomId, doc);