Undo/Redo System
Two-layer architecture combining fast local snapshots with Automerge CRDT operation log.
Architecture
Layer 1: Snapshot-based Local Undo (fast)
- Before each operation, capture a JSON snapshot of the entire scene
- Undo = restore the previous snapshot (< 5ms)
- Redo = restore the next snapshot
- Stack-based: undo stack + redo stack
Layer 2: Automerge Operation Log (collaborative)
- Every operation is also recorded in the Automerge document
- Enables collaborative undo (each user undoes their own ops)
- Persistent across sessions via IndexedDB/R2
Operation Types
| Op | Recorded Data | Undo Behavior |
|---|---|---|
add | type, id, params | Remove the added object |
translate | objectId, dx, dy, dz | Reverse the translation |
boolean | op, idA, idB, resultId | Restore both input objects |
delete | objectId, snapshot | Restore deleted object |
clear | snapshot | Restore entire scene |
Grouping
Related operations are grouped into single undo steps:
- Adding a primitive + auto-offset = one undo step
- This prevents partial undos (e.g., object added but not positioned)
Timeline UI
The timeline strip shows recent operations as clickable chips. Each chip represents one undo step.
UUID Stability
All objects have stable UUIDs (v4). UUIDs persist through:
- Translations
- Scene export/import
- Undo/redo cycles
- Cross-tab sync
Performance
- Snapshot capture: < 5ms
- Snapshot restore: < 5ms
- Scene replay (10 ops): ~200ms