Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Keyo — Real-Time Collaborative Editor

A WebSocket-based collaborative editing platform using RGA CRDTs for conflict-free concurrent editing, live cursors, and presence awareness. Supports 500+ concurrent users.

Quick Start

npm install
npm start
# → http://localhost:3001

Open the URL in two or more browser tabs, enter a name and the same room ID, and start editing together.

Architecture

Keyo/
├── server/
│   ├── server.js        # Express + WebSocket server
│   ├── room-manager.js  # Room lifecycle + disk persistence
│   └── crdt.js          # Server-side RGA CRDT (authoritative)
├── client/
│   ├── index.html       # App shell (join screen + editor)
│   ├── style.css        # Dark glassmorphism design system
│   ├── crdt.js          # Browser RGA CRDT (same algorithm)
│   ├── ws-client.js     # WebSocket + reconnection wrapper
│   ├── cursors.js       # Remote cursor overlay (mirror-div)
│   └── app.js           # Main orchestrator
├── data/rooms/          # Persisted room documents (auto-created)
└── package.json

How It Works

CRDT — RGA (Replicated Growable Array)

Every character holds a globally unique ID { clock, siteId }. Concurrent inserts at the same position are deterministically ordered by (higher clock first, then siteId descending) — so all clients always converge to the same document regardless of message arrival order.

Op Description
insert Inserts char after a target character ID
delete Tombstones a character (stays in structure, invisible)

Both operations are commutative and idempotent — duplicate or reordered messages are safe.

WebSocket Protocol

Message Direction Purpose
join C→S Join a room with name + optional userId
init S→C Full document snapshot + presence list
op C↔S CRDT operation (insert / delete)
cursor C↔S Cursor index update (throttled 30fps)
join S→C New user arrived notification
leave S→C User disconnected notification
ping/pong C↔S Keepalive every 20s

Disk Persistence

Documents are saved to data/rooms/<roomId>.json automatically, debounced 2 seconds after each operation. They are loaded back on server restart. Empty rooms are evicted from memory (but kept on disk) after 10 seconds.

Scalability (500+ users)

  • Room isolation — ops are broadcast only within a room, never globally
  • Return-path skip — server never echoes an op back to its sender
  • Cursor throttle — client rate-limits cursor broadcasts to ~30fps
  • Heartbeat TTL — WebSocket ping/pong every 20s; stale connections auto-close
  • Memory eviction — idle empty rooms are flushed from memory

Environment Variables

Variable Default Description
PORT 3001 HTTP + WebSocket port

About

A WebSocket-based collaborative editing platform using **RGA CRDTs** for conflict-free concurrent editing, live cursors, and presence awareness. Supports 500+ concurrent users.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages