Spaces:
Sleeping
Sleeping
| # 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 | |
| ```bash | |
| npm install | |
| npm run dev | |
| ``` | |
| ### HuggingFace Spaces Deployment | |
| The Dockerfile runs: | |
| 1. `hf_init.mjs` - Authenticate with HF | |
| 2. `hf_restore.mjs` - Restore previous state | |
| 3. `npm run dev` - Vite dev server (port 7860) | |
| 4. `hf_backup.mjs` - Periodic backup worker | |
| 5. `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 | |