fix: restore working Automerge sync from pre-Cloudflare version

Reverted to the proven approach from commit 90605be where each client
creates its own Automerge document with repo.create(). The Automerge
binary sync protocol handles synchronization between clients through
the WebSocket network adapter, without requiring shared document IDs.

Key changes:
- Each client calls repo.create() to get a unique document
- Initial content loaded from server via HTTP/R2
- Binary sync messages broadcast between clients keep documents in sync
- No need for shared document ID storage/retrieval

This fixes the "Document unavailable" errors and enables real-time
collaboration across multiple board instances.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2025-11-16 21:59:59 -07:00
parent c18d204814
commit 63b19f7db8
1 changed files with 51 additions and 4 deletions

View File

@ -125,11 +125,58 @@ export function useAutomergeSync(config: AutomergeSyncConfig): TLStoreWithStatus
console.log("🔌 Initializing Automerge Repo with NetworkAdapter for room:", roomId)
if (mounted) {
// SIMPLIFIED: Each client creates its own Automerge document
// Content sync happens via WebSocket (binary Automerge sync protocol)
// Initial content is loaded from server via HTTP below
// CRITICAL: Create a new Automerge document (repo.create() generates a proper document ID)
// Each client gets its own document, but Automerge sync protocol keeps them in sync
// The network adapter broadcasts sync messages between all clients in the same room
const handle = repo.create<TLStoreSnapshot>()
console.log(`📝 Created Automerge document handle: ${handle.documentId}`)
console.log("Created Automerge handle via Repo:", {
handleId: handle.documentId,
isReady: handle.isReady(),
roomId: roomId
})
// Wait for the handle to be ready
await handle.whenReady()
// CRITICAL: Always load initial data from the server
// The server stores documents in R2 as JSON, so we need to load and initialize the Automerge document
console.log("📥 Loading initial data from server...")
try {
const response = await fetch(`${workerUrl}/room/${roomId}`)
if (response.ok) {
const serverDoc = await response.json() as TLStoreSnapshot
const serverShapeCount = serverDoc.store ? Object.values(serverDoc.store).filter((r: any) => r?.typeName === 'shape').length : 0
const serverRecordCount = Object.keys(serverDoc.store || {}).length
console.log(`📥 Loaded document from server: ${serverRecordCount} records, ${serverShapeCount} shapes`)
// Initialize the Automerge document with server data
if (serverDoc.store && serverRecordCount > 0) {
handle.change((doc: any) => {
// Initialize store if it doesn't exist
if (!doc.store) {
doc.store = {}
}
// Copy all records from server document
Object.entries(serverDoc.store).forEach(([id, record]) => {
doc.store[id] = record
})
})
console.log(`✅ Initialized Automerge document with ${serverRecordCount} records from server`)
} else {
console.log("📥 Server document is empty - starting with empty Automerge document")
}
} else if (response.status === 404) {
console.log("📥 No document found on server (404) - starting with empty document")
} else {
console.warn(`⚠️ Failed to load document from server: ${response.status} ${response.statusText}`)
}
} catch (error) {
console.error("❌ Error loading initial document from server:", error)
// Continue anyway - user can still create new content
}
console.log("Found/Created Automerge handle via Repo:", {
handleId: handle.documentId,