ColorRM Pro
A real-time collaborative PDF annotation and drawing application built with modern web technologies.
Architecture Overview
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Frontend β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β color_rm.html β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββββββ β β
β β β ColorRm β β ColorRm β β ColorRm β β β
β β β Session.js ββββ Renderer.js ββββ LiveSync.js β β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Backend β
β ββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ β
β β Cloudflare Workers β β HuggingFace Spaces β β
β β ββββββββββββββββββ β β βββββββββββββββββββββββββ β β
β β β worker.ts β β β β Vite Dev Server β β β
β β β - API Routes β β β β - Static files β β β
β β β - R2 Storage β β β β - PDF Convert (7861) β β β
β β ββββββββββββββββββ β β βββββββββββββββββββββββββ β β
β β ββββββββββββββββββ β βββββββββββββββββββββββββββββββ β
β β β Durable Objectsβ β β
β β β - ColorRm DO β β βββββββββββββββββββββββββββββββ β
β β ββββββββββββββββββ β β Liveblocks β β
β ββββββββββββββββββββββββ β - Real-time sync β β
β β - Presence β β
β β - Room management β β
β βββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Modules
Frontend (public/scripts/modules/)
| Module |
Description |
ColorRmSession.js |
Main application controller. Handles state, tools, page management, import/export |
ColorRmRenderer.js |
Canvas rendering engine. Draws strokes, shapes, images, handles transformations |
ColorRmStorage.js |
IndexedDB and R2 storage. Manages local persistence and cloud sync |
ColorRmLiveSync.js |
Liveblocks integration. Real-time collaboration, cursors, history sync |
ColorRmSvgImporter.js |
SVG parsing and import. Converts SVG elements to ColorRM history items |
ColorRmSvgExporter.js |
SVG export. Renders history to vector SVG format |
Backend (worker/)
| File |
Description |
worker.ts |
Main Cloudflare Worker entry point. Routes API requests |
colorRmAssets.ts |
R2 storage handlers for pages, history, modifications |
pdfToSvg.ts |
PDF conversion job management (placeholder for CF Workers) |
ColorRmDurableObject.ts |
Durable Object for room state management |
Commands (cmd/)
| Script |
Description |
pdf_convert_server.mjs |
Local PDF to SVG server using pdf2svg binary |
hf_init.mjs |
HuggingFace authentication initialization |
hf_backup.mjs |
Periodic backup to HuggingFace Hub |
hf_restore.mjs |
Restore from HuggingFace Hub on startup |
Data Flow
SVG Import Flow
1. User selects SVG file
β
2. ColorRmSvgImporter.importSvg() parses SVG
β
3. Elements are classified:
βββ Images/Text β Rasterized to background blob
βββ Strokes/Shapes β Kept as vector history items
β
4. Page object created with blob + history
β
5. Sync to cloud:
βββ Blob β R2 via _uploadPageBlob()
βββ History β R2 via /api/color_rm/history/:sessionId/:pageId
βββ Structure β Liveblocks via _syncPageStructureToLive()
β
6. Other users receive notification via Liveblocks
β
7. Other users fetch page blob from R2
History Sync (Delta Architecture)
For pages with base history (SVG imports):
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β R2 Storage (Base) β
β /api/color_rm/history/:sessionId/:pageId β
β - Original SVG items (large, stored once) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Liveblocks (Deltas Only) β
β - New strokes added by users β
β - Modifications to base items (position, color, etc.) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
=
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Final Rendered Page β
β BaseHistory + Deltas + Modifications β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Thresholds
| Condition |
Threshold |
Action |
| SVG page history |
> 400 items |
Use R2 for base, Liveblocks for deltas |
| Regular page history |
> 2000 items |
Convert to hybrid R2/Liveblocks |
| Modifications |
> 100 items |
Store in R2, sync metadata via Liveblocks |
API Endpoints
Page Management
| Method |
Endpoint |
Description |
| POST |
/api/color_rm/page/:sessionId/:pageId |
Upload page blob |
| GET |
/api/color_rm/page/:sessionId/:pageId |
Download page blob |
| DELETE |
/api/color_rm/page/:sessionId/:pageId |
Delete page |
History
| Method |
Endpoint |
Description |
| POST |
/api/color_rm/history/:sessionId/:pageId |
Upload base history |
| GET |
/api/color_rm/history/:sessionId/:pageId |
Get base history |
Page Structure
| Method |
Endpoint |
Description |
| GET |
/api/color_rm/page_structure/:sessionId |
Get page order |
| POST |
/api/color_rm/page_structure/:sessionId |
Update page order |
PDF Conversion (Local Server)
| Method |
Endpoint |
Description |
| POST |
/convert/pdf |
Upload PDF for conversion |
| GET |
/convert/status/:jobId |
Check conversion status |
| GET |
/convert/page/:jobId/:pageNum |
Download converted SVG page |
Development
Local Development
npm install
npm run dev
HuggingFace Spaces Deployment
The Dockerfile runs:
hf_init.mjs - Authenticate with HF
hf_restore.mjs - Restore previous state
npm run dev - Vite dev server (port 7860)
hf_backup.mjs - Periodic backup worker
pdf_convert_server.mjs - PDF conversion (port 7861)
Environment Variables
| Variable |
Description |
HF_TOKEN |
HuggingFace API token |
LIVEBLOCKS_SECRET_KEY |
Liveblocks API key |
PORT |
Dev server port (default: 7860) |
Tools
| Tool |
Shortcut |
Description |
| Move |
V |
Select and move objects |
| Hand |
H |
Pan the canvas |
| Lasso |
L |
Free-form selection |
| Pen |
P |
Freehand drawing |
| Shape |
S |
Draw shapes (rect, ellipse, arrow, etc.) |
| Text |
T |
Add text annotations |
| Eraser |
E |
Erase strokes |
| Box/Capture |
B |
Capture region to clipboard |
Collaboration Features
- Real-time cursors: See other users' cursors
- Live history sync: Strokes appear instantly for all users
- Page structure sync: Page order synchronized across users
- Presence indicators: See who's online in the room