import { IndexeddbPersistence } from "y-indexeddb"; import { WebsocketProvider } from "y-websocket"; import * as Y from "yjs"; import { documentsApi } from "../api/document"; const WS_URL = import.meta.env.VITE_WS_URL || "ws://localhost:8080/ws"; export interface YjsProviders { ydoc: Y.Doc; websocketProvider: WebsocketProvider; indexeddbProvider: IndexeddbPersistence; awareness: any; } export const createYjsDocument = async (documentId: string): Promise => { // Create Yjs document const ydoc = new Y.Doc(); // Load initial state from database BEFORE connecting providers try { const state = await documentsApi.getState(documentId); if (state && state.length > 0) { Y.applyUpdate(ydoc, state); console.log('✓ Loaded document state from database'); } } catch { console.log('No existing state in database (new document)'); } // IndexedDB persistence (offline support) const indexeddbProvider = new IndexeddbPersistence(documentId, ydoc); // WebSocket provider (real-time sync) const websocketProvider = new WebsocketProvider(WS_URL, documentId, ydoc); // Awareness for cursors and presence const awareness = websocketProvider.awareness; return { ydoc, websocketProvider, indexeddbProvider, awareness, }; }; export const destroyYjsDocument = (providers: YjsProviders) => { providers.websocketProvider.destroy(); providers.indexeddbProvider.destroy(); providers.ydoc.destroy(); }; // Random color generator for users export const getRandomColor = () => { const colors = [ "#FF6B6B", "#4ECDC4", "#45B7D1", "#FFA07A", "#98D8C8", "#F7DC6F", "#BB8FCE", "#85C1E2", ]; return colors[Math.floor(Math.random() * colors.length)]; }; // Random name generator export const getRandomName = () => { const adjectives = ["Happy", "Clever", "Brave", "Swift", "Kind"]; const animals = ["Panda", "Fox", "Wolf", "Bear", "Eagle"]; return `${adjectives[Math.floor(Math.random() * adjectives.length)]} ${ animals[Math.floor(Math.random() * animals.length)] }`; };