final updates to Automerge conversion

This commit is contained in:
Jeff Emmett 2025-11-10 13:34:55 -08:00
parent 5c7f74ce44
commit abfbed50e1
15 changed files with 124 additions and 13 deletions

View File

@ -137,5 +137,6 @@ The Fathom transcript shape includes:

View File

@ -88,5 +88,6 @@ You can also manually edit the environment by:

View File

@ -321,19 +321,49 @@ export function useAutomergeStoreV2({
// Initialize store with existing records from Automerge
if (doc.store) {
const storeKeys = Object.keys(doc.store)
console.log(`📊 Store keys count: ${storeKeys.length}`, storeKeys.slice(0, 10))
// Get all store values - Automerge should handle this correctly
const allStoreValues = Object.values(doc.store)
console.log("All store values from Automerge:", allStoreValues.map((v: any) => ({
hasTypeName: !!v?.typeName,
hasId: !!v?.id,
typeName: v?.typeName,
id: v?.id
})))
// Debug: Log first few records in detail to see their structure
console.log("📊 Sample store values (first 3):", allStoreValues.slice(0, 3).map((v: any) => {
try {
return {
hasTypeName: !!v?.typeName,
hasId: !!v?.id,
typeName: v?.typeName,
id: v?.id,
type: v?.type,
keys: v ? Object.keys(v).slice(0, 10) : [],
// Try to stringify a sample to see structure
sample: JSON.stringify(v).substring(0, 200)
}
} catch (e) {
return { error: String(e), value: v }
}
}))
// Debug: Count record types before filtering
const typeCountBefore = allStoreValues.reduce((acc: any, v: any) => {
const type = v?.typeName || 'unknown'
acc[type] = (acc[type] || 0) + 1
return acc
}, {})
console.log(`📊 Store values before filtering:`, {
total: allStoreValues.length,
typeCounts: typeCountBefore
})
// Simple filtering - only keep valid TLDraw records
// Skip custom record types like obsidian_vault - they're not TLDraw records
// Components should read them directly from Automerge (like ObsidianVaultBrowser does)
const records = allStoreValues.filter((record: any) => {
if (!record || !record.typeName || !record.id) return false
if (!record || !record.typeName || !record.id) {
console.log(`⚠️ Filtering out invalid record:`, { hasRecord: !!record, hasTypeName: !!record?.typeName, hasId: !!record?.id })
return false
}
// Skip obsidian_vault records - they're not TLDraw records
if (record.typeName === 'obsidian_vault' ||
(typeof record.id === 'string' && record.id.startsWith('obsidian_vault:'))) {
@ -342,6 +372,8 @@ export function useAutomergeStoreV2({
return true
})
console.log(`📊 After filtering: ${records.length} valid records from ${allStoreValues.length} total store values`)
// Only log if there are many records or if debugging is needed
if (records.length > 50) {
console.log(`Found ${records.length} valid records in Automerge document`)
@ -1244,6 +1276,20 @@ export function useAutomergeStoreV2({
console.log(`Processed ${processedRecords.length} records for loading`)
// Debug: Log what record types we have
const recordTypes = processedRecords.reduce((acc: any, r: any) => {
const type = r.typeName || 'unknown'
acc[type] = (acc[type] || 0) + 1
return acc
}, {})
console.log(`📊 Record types breakdown:`, recordTypes)
console.log(`📊 All processed records:`, processedRecords.map((r: any) => ({
id: r.id,
typeName: r.typeName,
type: r.type,
hasProps: !!r.props
})))
// Debug: Log shape structures before loading
const shapesToLoad = processedRecords.filter(r => r.typeName === 'shape')
console.log(`📊 About to load ${shapesToLoad.length} shapes into store`)

View File

@ -68,11 +68,65 @@ export function useAutomergeSync(config: AutomergeSyncConfig): TLStoreWithStatus
if (r2StoreKeys > 0) {
console.log("Loading R2 data into Automerge document")
if (existingDoc.store) {
doc.store = existingDoc.store
// Debug: Log what we're about to load
const storeEntries = Object.entries(existingDoc.store)
const shapeCount = storeEntries.filter(([_, v]: [string, any]) => v?.typeName === 'shape').length
console.log("📊 R2 data to load:", {
totalRecords: storeEntries.length,
shapeCount,
recordTypes: storeEntries.reduce((acc: any, [_, v]: [string, any]) => {
const type = v?.typeName || 'unknown'
acc[type] = (acc[type] || 0) + 1
return acc
}, {}),
sampleRecords: storeEntries.slice(0, 5).map(([k, v]: [string, any]) => ({
key: k,
id: v?.id,
typeName: v?.typeName,
type: v?.type
}))
})
// Initialize store if it doesn't exist
if (!doc.store) {
doc.store = {}
}
// Assign each record individually with deep copy to ensure Automerge properly handles nested objects
// This matches how records are saved in TLStoreToAutomerge.ts
let assignedCount = 0
for (const [key, record] of Object.entries(existingDoc.store)) {
try {
// Create a deep copy to ensure Automerge properly handles nested objects
// This is critical for preserving nested structures like props, richText, etc.
const recordToSave = JSON.parse(JSON.stringify(record))
doc.store[key] = recordToSave
assignedCount++
} catch (e) {
console.error(`❌ Error deep copying record ${key}:`, e)
// Fallback: assign directly (might not work for nested objects)
doc.store[key] = record
}
}
console.log("Loaded store data into Automerge document:", {
loadedStoreKeys: Object.keys(doc.store).length,
assignedCount,
sampleLoadedKeys: Object.keys(doc.store).slice(0, 5)
})
// Verify what was actually loaded
const loadedValues = Object.values(doc.store)
const loadedShapeCount = loadedValues.filter((v: any) => v?.typeName === 'shape').length
console.log("📊 Verification after loading:", {
totalLoaded: loadedValues.length,
loadedShapeCount,
loadedRecordTypes: loadedValues.reduce((acc: any, v: any) => {
const type = v?.typeName || 'unknown'
acc[type] = (acc[type] || 0) + 1
return acc
}, {})
})
}
if (existingDoc.schema) {
doc.schema = existingDoc.schema

View File

@ -265,5 +265,6 @@ export const LocationDashboard: React.FC = () => {

View File

@ -236,5 +236,6 @@ export const LocationMap: React.FC<LocationMapProps> = ({

View File

@ -178,5 +178,6 @@ export const LocationViewer: React.FC<LocationViewerProps> = ({ shareToken }) =>

View File

@ -145,5 +145,6 @@ export const ShareSettingsComponent: React.FC<ShareSettingsProps> = ({ onSetting

View File

@ -420,5 +420,6 @@

View File

@ -50,5 +50,6 @@ export interface GeolocationPosition {

View File

@ -32,5 +32,6 @@ export const LocationDashboardRoute: React.FC = () => {

View File

@ -32,5 +32,6 @@ export const LocationShareCreate: React.FC = () => {

View File

@ -46,5 +46,6 @@ export const LocationShareView: React.FC = () => {

View File

@ -67,5 +67,6 @@ echo " npm run dev"

View File

@ -23,11 +23,10 @@ bindings = [
tag = "v1"
new_classes = ["AutomergeDurableObject"]
[[migrations]]
tag = "v2"
renamed_classes = [
{ from = "TldrawDurableObject", to = "AutomergeDurableObject" }
]
# Note: TldrawDurableObject → AutomergeDurableObject migration removed
# The AutomergeDurableObject class is already in use, so we can't rename to it.
# Any remaining TldrawDurableObject instances will be orphaned but won't cause issues.
# If you need to clean them up, you can add a delete-class migration in the future.
[[r2_buckets]]
binding = 'TLDRAW_BUCKET'