fix: convert props.text to richText for text shape sync (task-026)

Text shapes arriving from other clients had props.text but the
deserialization code was initializing richText to empty before
deleting props.text, causing content loss.

Added text → richText conversion in AutomergeToTLStore.ts before
the empty initialization, similar to the existing conversion for
geo shapes.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2025-12-25 18:34:52 -05:00
parent 9a4cf18e13
commit 0fc80f7496
1 changed files with 31 additions and 0 deletions

View File

@ -1159,6 +1159,37 @@ export function sanitizeRecord(record: any): TLRecord {
// CRITICAL: Fix richText structure for text shapes - REQUIRED field // CRITICAL: Fix richText structure for text shapes - REQUIRED field
if (sanitized.type === 'text') { if (sanitized.type === 'text') {
// CRITICAL: Convert props.text to props.richText for text shapes (fixes sync issue)
// Text shapes may arrive from other clients with props.text instead of props.richText
// We must convert BEFORE initializing richText to empty, otherwise content is lost
if ('text' in sanitized.props && typeof sanitized.props.text === 'string' && sanitized.props.text.trim()) {
const textContent = sanitized.props.text
// Only use text content if richText is missing or empty
const hasRichTextContent = sanitized.props.richText &&
typeof sanitized.props.richText === 'object' &&
sanitized.props.richText.content &&
Array.isArray(sanitized.props.richText.content) &&
sanitized.props.richText.content.length > 0
if (!hasRichTextContent) {
// Convert text string to richText format for tldraw
sanitized.props.richText = {
type: 'doc',
content: [{
type: 'paragraph',
content: [{
type: 'text',
text: textContent
}]
}]
}
console.log(`🔧 AutomergeToTLStore: Converted props.text to richText for text shape ${sanitized.id}`)
}
// Preserve original text in meta for backward compatibility
if (!sanitized.meta) sanitized.meta = {}
sanitized.meta.text = textContent
}
// Text shapes MUST have props.richText as an object - initialize if missing // Text shapes MUST have props.richText as an object - initialize if missing
if (!sanitized.props.richText || typeof sanitized.props.richText !== 'object' || sanitized.props.richText === null) { if (!sanitized.props.richText || typeof sanitized.props.richText !== 'object' || sanitized.props.richText === null) {
sanitized.props.richText = { content: [], type: 'doc' } sanitized.props.richText = { content: [], type: 'doc' }