Minimal collaboration MVP with:
- backend: Node + y-websocket (WebSocket server for Yjs)
- frontend: Vite + React + Excalidraw + Yjs + Supabase storage integration
- periodic upload of preview.svg and Y.Doc snapshot to Supabase Storage
Now also supports:
- dynamic project/room IDs via URL params
- loading the latest Y.Doc snapshot from Supabase at startup
- configurable WebSocket server URL via env
-
Backend
cd backend npm install npm start -
Frontend
cd frontend npm install # create .env cat > .env << 'EOF' VITE_SUPABASE_URL=https://<your>.supabase.co VITE_SUPABASE_ANON_KEY=<anon-key> # optional: WebSocket server # Local dev backend default: ws://localhost:1234 # Docker default (baked via compose build arg): ws://localhost:9134 VITE_YWS_URL=ws://localhost:1234 EOF npm run dev
-
Supabase
- create a storage bucket named
projects - optionally set it public or keep private (signed URLs used for preview)
- create a storage bucket named
- Open the app with URL params to set IDs:
- project ID (also used for local IndexedDB key):
?project=my-project - room ID (for Yjs websocket room, defaults to project):
&room=my-room
- project ID (also used for local IndexedDB key):
Example:
xdg-open "http://localhost:5173/?project=my-project&room=my-room"- On startup, the app tries to download
snapshots/<projectId>.binfrom theprojectsbucket and applies it to the Y.Doc. - Periodically, it uploads:
previews/<projectId>.svgsnapshots/<projectId>.bin
- Skopiuj
.env.exampledo.env(w root) i uzupełnij:VITE_SUPABASE_URL,VITE_SUPABASE_ANON_KEY- porty:
FRONTEND_PORT,BACKEND_PORT,BACKEND_INTERNAL_PORT VITE_YWS_URL(powinien wskazywać na hostowy port backendu, np.ws://localhost:9134)
- Zbuduj i uruchom:
make docker-build # wymagane po zmianie .env (VITE_* bake'owane do bundla) make docker-up - Wejdź na:
http://localhost:${FRONTEND_PORT}/?project=my-project&room=my-room(domyślnie 8089) - Backend (Yjs ws):
ws://localhost:${BACKEND_PORT}(domyślnie 9134)
Uwaga: wewnątrz sieci Docker frontend łączy się z backendem przez VITE_YWS_URL ustawione w build args; na produkcji zalecane jest podawanie publicznego adresu ws/https.
Opcja A (korzysta z dev serwerów):
make electron-install
# upewnij się, że frontend działa (np. make dev-frontend) lub Docker (make docker-up)
ELECTRON_APP_URL=http://localhost:${FRONTEND_PORT:-8089} make electron-startOpcja B (statyczne pliki):
make frontend-build
make electron-install && make electron-startW menu File → Open Preview SVG… możesz wskazać preview.svg. Aplikacja odczyta <metadata> i załaduje projekt (przez ?project=...).
Endpointy pomocne przy wycenie i integracjach:
- GET
/preview/metadata?url=<URL_DO_SVG> - POST
/preview/metadata(body: cały SVG,Content-Type: image/svg+xml)
Przykłady:
curl "http://localhost:${BACKEND_PORT:-9134}/preview/metadata?url=https://.../preview.svg"
curl -X POST -H "Content-Type: image/svg+xml" --data-binary @preview.svg \
http://localhost:${BACKEND_PORT:-9134}/preview/metadatamake help
make dev-backend # ws :1234 lokalnie
make dev-frontend # Vite :5173 lokalnie
make docker-build
make docker-up
make docker-down # lub: make stop
make docker-logs
make frontend-build
make electron-install
make electron-start- This is a minimal starting point. For production:
- add sanitization (DOMPurify) before rendering uploaded SVGs
- secure Supabase keys and rules
- replace periodic snapshot with event-driven saves