5.3 KiB
Testing R2 Data Conversion
This guide helps you test the data conversion from old tldraw sync format to new automerge sync format using actual data from your R2 bucket.
Overview
The conversion system handles three data formats:
- Automerge Array Format:
[{ state: {...} }, ...] - Store Format:
{ store: { "recordId": {...}, ... }, schema: {...} }(already converted) - Old Documents Format:
{ documents: [{ state: {...} }, ...] }(legacy tldraw sync)
Testing Steps
1. Identify Test Rooms
First, identify rooms in your R2 bucket that use the old format:
# List all rooms in R2
# You can use wrangler CLI or Cloudflare dashboard
wrangler r2 object list TLDRAW_BUCKET --prefix "rooms/"
2. Check Data Format
For each room, check its format:
// Example: Check a room's format
const roomId = "your-room-id"
const doc = await r2.get(`rooms/${roomId}`)
const data = await doc.json()
// Check format
if (Array.isArray(data)) {
console.log("Format: Automerge Array")
} else if (data.store) {
console.log("Format: Store Format (already converted)")
} else if (data.documents) {
console.log("Format: Old Documents Format (needs conversion)")
} else {
console.log("Format: Unknown")
}
3. Test Conversion
The conversion happens automatically when a room is loaded. To test:
- Load the room in your app - The
AutomergeDurableObject.getDocument()method will automatically detect and convert the format - Check the logs - Look for conversion statistics in the worker logs:
📊 Automerge to Store conversion statistics📊 Documents to Store migration statistics📊 Shape migration statistics
4. Verify Data Integrity
After conversion, verify:
- All shapes are present: Check that shape count matches
- Custom shapes preserved: Verify ObsNote, Holon, etc. have all their properties
- Custom records preserved: Check that obsidian_vault records are present
- No validation errors: Shapes should render without errors
Expected Log Output
When a room is converted, you should see logs like:
Converting Automerge document format to store format for room abc123
📊 Automerge to Store conversion statistics: {
total: 150,
converted: 148,
skipped: 2,
errors: 0,
storeKeys: 148,
customRecordCount: 1,
customRecordIds: ['obsidian_vault:test'],
errorCount: 0
}
✅ Verified 1 custom records preserved during conversion
🔄 Server-side: Starting shape migration for room abc123
📊 Shape migration statistics: {
total: 120,
migrated: 45,
skipped: 75,
errors: 0,
shapeTypes: { geo: 50, arrow: 20, ObsNote: 10, ... },
customShapesCount: 10,
customShapeIds: ['shape:obs1', 'shape:holon1', ...],
errorCount: 0
}
✅ Verified 10 custom shapes preserved during migration
Manual Testing Script
You can create a test script to verify conversion:
// test-r2-room.ts
import { AutomergeDurableObject } from './worker/AutomergeDurableObject'
async function testRoomConversion(roomId: string) {
// This would need to be run in a Cloudflare Worker context
// or use wrangler dev to test locally
const env = {
TLDRAW_BUCKET: yourR2Bucket
}
// Create a mock Durable Object state
const ctx = {
storage: {
get: async (key: string) => roomId,
put: async (key: string, value: any) => {}
},
blockConcurrencyWhile: async (fn: () => Promise<void>) => await fn()
}
const do = new AutomergeDurableObject(ctx as any, env as any)
// Load and convert
const doc = await do.getDocument()
// Verify
console.log('Conversion complete:', {
storeKeys: Object.keys(doc.store).length,
shapes: Object.values(doc.store).filter((r: any) => r.typeName === 'shape').length,
customRecords: Object.values(doc.store).filter((r: any) =>
r.id && typeof r.id === 'string' && r.id.startsWith('obsidian_vault:')
).length
})
}
Common Issues and Solutions
Issue: Records are skipped during conversion
Cause: Missing required fields (id, typeName, state)
Solution: Check the error details in logs. The conversion will skip invalid records but log warnings.
Issue: Custom shapes missing properties
Cause: Shape migration may have failed
Solution: Check shape migration logs. Custom shape props should be preserved automatically.
Issue: Custom records (obsidian_vault) missing
Cause: They were filtered out during conversion
Solution: This shouldn't happen - custom records are preserved. Check logs for customRecordCount.
Validation Checklist
After conversion, verify:
- All shapes are present (count matches)
- Custom shapes (ObsNote, Holon, etc.) have all properties
- Custom records (obsidian_vault) are preserved
- No validation errors when loading the room
- Shapes render correctly in the UI
- All text content is preserved
- All metadata is preserved
Rollback Plan
If conversion fails:
- The original data in R2 is not modified until the first save
- You can restore from backup if needed
- Check worker logs for specific errors
- The conversion creates a new document if it fails, so original data is safe
Next Steps
- Test with a few sample rooms first
- Monitor logs for any warnings or errors
- Verify data integrity after conversion
- Once confident, the conversion will happen automatically for all rooms