From 1b172d7529f19e9954200242850802fa89b3b8d0 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Mon, 10 Nov 2025 22:42:52 -0800 Subject: [PATCH] update x & y coordinates --- src/automerge/AutomergeToTLStore.ts | 16 ++++++++++++++-- worker/AutomergeDurableObject.ts | 5 +++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/automerge/AutomergeToTLStore.ts b/src/automerge/AutomergeToTLStore.ts index 230db72..237072e 100644 --- a/src/automerge/AutomergeToTLStore.ts +++ b/src/automerge/AutomergeToTLStore.ts @@ -99,6 +99,17 @@ export function applyAutomergePatchesToTLStore( let record = updatedObjects[id] || (existingRecord ? JSON.parse(JSON.stringify(existingRecord)) : defaultRecord) + // CRITICAL: For shapes, ensure x and y are always present (even if record came from updatedObjects) + // This prevents coordinates from being lost when records are created from patches + if (record.typeName === 'shape') { + if (typeof record.x !== 'number' || record.x === null || isNaN(record.x)) { + record = { ...record, x: defaultRecord.x || 0 } + } + if (typeof record.y !== 'number' || record.y === null || isNaN(record.y)) { + record = { ...record, y: defaultRecord.y || 0 } + } + } + // CRITICAL: Ensure typeName matches ID pattern (fixes misclassification) // Note: obsidian_vault records are skipped above, so we don't need to handle them here if (typeof id === 'string') { @@ -328,8 +339,9 @@ export function sanitizeRecord(record: any): TLRecord { // For shapes, only ensure basic required fields exist if (sanitized.typeName === 'shape') { // Ensure required shape fields exist - if (typeof sanitized.x !== 'number') sanitized.x = 0 - if (typeof sanitized.y !== 'number') sanitized.y = 0 + // CRITICAL: Check for non-number, null, undefined, or NaN values + if (typeof sanitized.x !== 'number' || sanitized.x === null || isNaN(sanitized.x)) sanitized.x = 0 + if (typeof sanitized.y !== 'number' || sanitized.y === null || isNaN(sanitized.y)) sanitized.y = 0 if (typeof sanitized.rotation !== 'number') sanitized.rotation = 0 if (typeof sanitized.isLocked !== 'boolean') sanitized.isLocked = false if (typeof sanitized.opacity !== 'number') sanitized.opacity = 1 diff --git a/worker/AutomergeDurableObject.ts b/worker/AutomergeDurableObject.ts index e9d6ae9..9c22893 100644 --- a/worker/AutomergeDurableObject.ts +++ b/worker/AutomergeDurableObject.ts @@ -1069,11 +1069,12 @@ export class AutomergeDurableObject { } // Ensure other required shape properties exist - if (record.x === undefined) { + // CRITICAL: Check for undefined, null, or non-number values (including NaN) + if (record.x === undefined || record.x === null || typeof record.x !== 'number' || isNaN(record.x)) { record.x = 0 needsUpdate = true } - if (record.y === undefined) { + if (record.y === undefined || record.y === null || typeof record.y !== 'number' || isNaN(record.y)) { record.y = 0 needsUpdate = true }