Así codeamos con Claude · 04: persistencia
Capítulo cortito. La feature es simple y casi invisible: no perder el dibujo al refrescar la página. Pero la simpleza de afuera esconde unas decisiones que vale la pena anotar.
new aparece a la izquierda del cluster de acciones de la toolbar.Que no se pierda nada
Cada cambio en el sprite dispara un save a localStorage. Hay debounce de 250ms para no escribir en cada píxel pintado durante un stroke (sería absurdo escribir cien veces por segundo). Al cargar la app leemos localStorage; si hay un sprite válido lo restauramos en el store, si no arrancamos con un sprite vacío 16×16.
Tres detalles que importan:
- Los píxeles van en base64 dentro del JSON. Un sprite máximo (128×128) son 64KB raw, que en base64 quedan ~88KB. localStorage típicamente da 5MB de quota por origen. Sobra.
- El history no se persiste. Si guardáramos las 100 entries × 64KB serían 6.4MB y la quota se rompe al primer crash. Al cargar, el history se resetea a un solo snapshot con el sprite cargado, así que las primeras undo no van a un estado raro.
- Antes de restaurar, validamos cada campo: versión del schema, integers, ranges, longitud de píxeles igual a width×height. Si algo no cuadra, arrancamos con defaults sin avisar.
Empezar de cero
Botón new en la toolbar. Hotkey ⌘⌥N (no usamos ⌘N porque el browser lo agarra para abrir una ventana, y pelearle a esa convención es perder tiempo y romper expectativas).
new: keycap con el shortcut completo + tooltip.El modal tiene tres bloques: presets de tamaño (8 / 16 / 32 / 64), inputs custom W × H clampeados a 128 cada lado, y un campo de nombre opcional. Si W y H coinciden con un preset, el botón correspondiente se marca activo.
Lo más importante visualmente: el warning en peach. "Esto reemplaza el sprite actual sin pedir confirmación." Es una acción destructiva: al confirmar perdés todo lo que tenías y empezás de cero. El usuario tiene que saberlo antes de tocar Crear.