SheetForge Web
SheetForge distribuye una app web complementaria en web.sheetforge.workers.dev. Lleva la creación, la validación y el reflejo de la hoja al navegador — sin Unity, sin instalación.
El mismo núcleo, no una reimplementación
La app web compila las mismas fuentes exactas del núcleo C# — las que ejecuta el arnés de pruebas de .NET sin interfaz (headless) — a un ensamblado browser-wasm de .NET. No hay una segunda copia del parser ni del validador, así que los dos nunca pueden desviarse entre sí: una regla corregida una vez queda corregida en ambos lugares.
Dos cosas se derivan directamente de ese diseño.
- Tus DLL de plugin compiladas cargan sin modificaciones, y activan los mismos slots aquí que en el editor (más abajo).
- Las reglas de sintaxis de hoja de este sitio se cumplen de forma idéntica en el navegador. Los marcadores, el sistema de tipos,
@overlap,@style,@enum,@locy la integridad de referencias se comportan todos de la misma manera, porque es el mismo código el que responde. Eso incluye la paridad deIntId@TabyLocRef@Tab— consulta Sintaxis de la hoja.
Un plugin, doce slots, dos hosts
Un plugin no tiene un "subconjunto web". El ensamblaje — instanciación, ordenamiento, aislamiento y la barrera de compatibilidad — es una única función pura del Core que ambos hosts invocan. Solo difiere el descubrimiento: Unity indexa los tipos del proyecto, mientras que el navegador escanea el ensamblado que subiste.
Así que los doce slots que un plugin puede llenar son los mismos en ambos lados:
| Slot | En el navegador |
|---|---|
| Enums · analizadores de celda · tipos wrapper | Las celdas se analizan, validan y hacen round-trip a través de tu propia notación |
| Validadores de dominio | Tus reglas aparecen en Problems junto a las del núcleo |
| Contribuyentes de aristas | Los enlaces enterrados en tu notación se dibujan en el lienzo y se cuentan en el índice de referencias |
| Marcadores estructurales | Tus filas @marker se aceptan y se validan |
| Plantillas de hoja | Tus plantillas aparecen en Create sheet |
| Aumentadores de lienzo | Nodos virtuales, aristas adicionales, indicios de capa y de visualización |
| Registros de código | Las claves que viven en código dejan de dibujarse como referencias rotas |
| Preajustes de color | Se mapean sobre las variables CSS de la app |
| UI declarativa de studio | Tus acciones, paneles, insignias de columna y pistas de editor de celda, renderizados en React |
| Cadenas de UI | Tus etiquetas siguen el idioma del usuario mediante la misma superposición que consulta t() |
| Observadores de canalización | Notificados al final de un ciclo de importación, exactamente igual que en el editor |
Las superficies declarativas son la razón por la que las extensiones de creación de un plugin existen aquí en absoluto. Un contrato que devolviera un elemento de UIToolkit nunca podría cargar en un navegador, así que la carcasa se describe como datos — un id, una clave de etiqueta, una ubicación, un tono — y cada host la dibuja con sus propios widgets.
Donde un paquete necesita algo que el vocabulario no puede decir, registra un panel enriquecido exclusivo del editor bajo el mismo id. El editor dibuja ese, el navegador dibuja el descrito, y la extensión nunca simplemente falta.
Dos reglas se sostienen en el momento del renderizado. El texto que llega de un plugin se escapa, y una acción cuya situación cambió desde que se dibujó responde con un no-op honesto en lugar de actuar sobre un id obsoleto.
Un ensamblado de plugin también puede declarar para qué generación del formato de plugin se construyó. Si cae fuera de lo que este host lee, el ensamblado completo se rechaza con un motivo legible en lugar de cargarse a medias. Es la misma barrera, que lee la misma declaración, en la ruta del mercado, la ruta de carga lateral y un archivo local. Consulta Creación de plugins.
Lo que se queda en Unity
El codegen y el bake siguen siendo una responsabilidad exclusiva de Unity. El navegador no puede emitir archivos .cs ni escribir ScriptableObjects, y no pretende poder hacerlo. La misma honestidad cubre la localización: una hoja de localización se crea y valida por completo aquí, pero sincronizar las StringTables de Unity Localization es trabajo del editor — el navegador no tiene un proyecto de Unity donde escribir las tablas. Lo mismo aplica a cualquier cosa que necesite el propio proyecto: el selector de asset, arrastrar y soltar desde la ventana Project y los registros de Addressables que preparan existen solo en el editor; el <Type> de AssetRef@Group<Type> se analiza y se muestra en el navegador, pero se resuelve — y se comprueba su tipo — solo donde están cargados los tipos del proyecto; y las miniaturas, vistas ampliadas y reproducción de audio de assets del editor no tienen equivalente en la web, porque el navegador no tiene assets de proyecto que leer — una celda de asset en la cuadrícula web es su texto de dirección.
La salida web es la hoja reflejada — el origen validado y con round-trip aplicado — no assets generados mediante bake. Creas y validas en el navegador, y luego ejecutas una importación en Unity cuando quieres clases fuertemente tipadas y SO generados mediante bake. La hoja es la única fuente de verdad en ambos casos, así que las dos superficies se encuentran en la hoja.
Qué hace la app web
Todo hace round-trip a través de un único contrato de límite JSON hacia el núcleo de WebAssembly, así que la UI del navegador nunca vuelve a derivar una regla que el núcleo ya posee.
| Área | Qué obtienes |
|---|---|
| Sesión de creación | Importación, proyección, y un panel Problems alimentado por el mismo validador de importación — diagnósticos de pre-flight, no una comprobación separada. La importación acepta archivos TSV y CSV y libros .xlsx — cada hoja de un libro llega como su propia pestaña, leída por el mismo lector que usa el editor (compilado a WebAssembly), y cuando algo tuvo que interpretarse — el valor en caché de una fórmula, una fecha como texto yyyy-MM-dd, un formato no leído — el diálogo de importación lo indica en una nota "Cómo se leyó este libro". |
| Edición de tabla | Widgets de celda por tipo, undo, fijado de columnas, orden, búsqueda, agrupación y color @style — más el conjunto de columnas de hoja de cálculo que tiene el editor: arrastra el tirador del encabezado para ajustar el ancho de una columna (doble clic para autoajustar; se guarda por hoja en este navegador), oculta y muestra columnas mientras las letras y una marca de límite se mantienen honestas, filtros de valor por columna que se combinan con la búsqueda, y vaciar datos de columna como un solo paso de deshacer. + Row prepara una fila de inmediato con una clave sugerida — las columnas de id entero vienen prerrellenadas — lista para renombrar en la celda de clave, y una hoja sin columna clave lo deshabilita, con el motivo indicado. Las celdas de enum y de booleano opcional abren el mismo selector con búsqueda que usan las celdas de referencia — y solo hay una ventana de selector abierta a la vez: abrir otra cierra la anterior, y hacer clic fuera o pulsar Esc la cierra. Los números de fila y las letras de columna se seleccionan (Ctrl añade, Shift toma el tramo), el encabezado y el cuerpo resaltan la selección, la celda seleccionada dibuja un contorno que sigue al teclado, y una selección se arrastra a una nueva posición con una línea de inserción — una selección no contigua llega agrupada en el punto de destino en el orden en que se seleccionó, como un solo paso de deshacer — mientras los menús de clic derecho aplican ancho, autoajuste, ocultar, mover, eliminar y vaciar datos a todas las columnas seleccionadas (los movimientos y la eliminación a todas las filas seleccionadas), con los elementos de un solo objetivo aparte en su propia sección. Las hojas de definición de enum tienen el mismo eje de ancho de columna que las hojas de datos — arrastrar, doble clic para autoajustar, ancho exacto, autoajustar a los datos, ocultar. Por encima de 200 filas, la cuadrícula renderiza solo la ventana visible (más overscan), con espaciadores que sostienen la altura de scroll real — el mismo umbral que usa la tabla del editor, así que ambas se sienten igual en una hoja grande. |
| Valores visuales | Las celdas Color, AnimationCurve y Gradient muestran una vista previa que llena la celda — una muestra de color, una polilínea de curva, una barra de degradado — y abren un editor completo en un popover: un editor de color con un cuadrado HSV, deslizadores de tono y alfa y un campo hexadecimal (el input de color nativo del navegador no tiene alfa, así que no se usa); un editor de curva con una cuadrícula con zoom, claves y asas de tangente arrastrables, modos de tangente (Free, Auto, Linear, Constant, ClampedAuto — clic derecho en una clave o usa el selector), interruptores de rota y ponderada, campos numéricos, ajuste previo/posterior y los preajustes Lineal / Entrada-salida suave / Constante; un editor de degradado con claves de color y alfa arrastrables (hasta 8 de cada una), un selector de modo y un selector de espacio de color. Cada cambio hace round-trip a través del núcleo de WebAssembly — el análisis, el recálculo de tangentes y el muestreo son C#, no JavaScript — y el texto confirmado es la misma forma canónica que escribe el editor, byte a byte. Los cambios se confirman en el momento en que los haces, exactamente igual que los campos nativos del editor: la celda, el lienzo y Problems siguen el ritmo mientras el editor está abierto, una sesión de edición se fusiona en un solo paso de undo sin importar cuántos cambios haga, y volver a abrir el editor inicia un paso nuevo. No hay un botón Apply — el único botón es Cerrar (Esc también cierra, y en el editor de color Esc también restaura el valor previo a la sesión); revertir es Ctrl+Z. Abrir y cerrar sin cambiar nada no prepara nada. Una columna opcional muestra — cuando está vacía y ofrece Vaciar (predeterminado) en un menú de clic derecho; un List<> de los tres es una lista de chips cuyos gestos de añadir / quitar / reordenar / editar son cada uno un paso de undo. La franja de vista previa cabe dentro de la altura de fila estándar, igual que en la tabla del editor. Las filas de valor del lienzo usan los mismos componentes. |
| Edición de estructura | Añadir / eliminar / mover columnas, el formulario de columna de cuatro campos ✎, renombrado de pestaña (intercambios mutuos y ciclos incluidos; las pestañas xlsx están bloqueadas), crear/eliminar hoja, y un menú desplegable de ajustes activos — cada uno preparado como un solo paso de undo. Las hojas de definición de enum se editan de la misma manera — define un enum nuevo, renombra (con cada @type que lo referencia reescrito en el mismo lote), elimina, reordena columnas, edita el tipo subyacente y la descripción — bajo las mismas reglas que el editor, porque es el mismo código el que decide. |
| Búsqueda entre hojas | La entrada All de la barra lateral busca por coincidencia parcial en los ids y valores de campo de todas las hojas, listando hoja · clave · campo · valor, 50 filas por página — la misma coincidencia, orden y tamaño de página que el editor. Lee los valores que la sesión muestra en este momento, ediciones preparadas incluidas, así que un valor que acabas de cambiar se encuentra al instante. Haz doble clic en un resultado — o selecciónalo y pulsa Enter — y esa hoja se abre con la celda coincidente seleccionada; como la búsqueda lee la propia sesión, todos los resultados se pueden abrir. |
| Localización | Las hojas de localización son hojas ordinarias aquí — creación, validación y cobertura por configuración regional incluidas. La celda LocRef de una hoja de datos muestra en línea el texto de la configuración regional de origen de la entrada y abre el mismo selector de claves que tienen otras referencias; escribir en una celda vacía genera la clave, su texto de origen y la referencia como un solo paso de deshacer, exactamente como hace el editor. La lente de configuración regional alterna las columnas de configuración regional visibles (solo visualización), y el libro de traducción exporta las configuraciones regionales elegidas a xlsx y reimporta el archivo devuelto como una fusión de solo columnas de configuración regional. Sincronizar las StringTables de Unity Localization sigue siendo cosa del editor. |
| Lienzo de registros | Los materiales y consumidores de un registro son tarjetas que conectas arrastrando cables — el lienzo reutiliza el mismo código puro de layout, cableado y cadena de edición que el editor, así que la aritmética de píxeles vive en C#, no en una librería de grafos de JS. Las tarjetas muestran la misma proyección que la tabla: una columna preparada en este lote ya aparece en la tarjeta marcada como pendiente, un renombrado preparado muestra el nombre nuevo sobre el valor original, y una eliminación preparada quita la fila también aquí. |
| Salida | Descarga TSV / CSV por hoja, una descarga de libro .xlsx que lleva todas las hojas elegidas en un solo archivo (un nombre de hoja que las reglas del libro no puedan admitir se ajusta y se reporta, nunca se renombra en silencio), y lectura/escritura de Hojas de Google, con los menús desplegables de validación de datos de la hoja actualizados automáticamente después de cada push (ver más abajo). |
Hecho idéntico, no meramente similar
La UI web coincide con Data Studio del editor a propósito, hasta la lógica compartida.
- Respuestas compartidas. Los predicados del encabezado (
pending/edited), el modal de diff, y el orden de composición de la proyección son C# compartido, así que ambas superficies dan la misma respuesta a la misma pregunta. - Frases compartidas. Donde la web refleja una pantalla de Studio, usa las propias claves de string de Studio, y los valores se generan a partir de las tablas de idioma del editor en el momento de la build en lugar de volver a teclearse. Añadir una frase que ambas superficies muestran es una clave en
Lang*.cs; la desviación es estructuralmente imposible en lugar de meramente desalentada. Dos cosas se mantienen deliberadamente separadas, y una comprobación en el momento de la build impone el límite:- las cadenas que son genuinamente solo-web permanecen en el catálogo web;
- los diagnósticos e informes los renderiza el núcleo de WebAssembly, no se reformulan en la UI.
- Apariencia compartida. El grafo y la hoja se muestran juntos en un panel dividido redimensionable que refleja el comportamiento de clamp de lienzo del editor, y cada color viene del conjunto de tokens
.aw-rootdel editor como única fuente de verdad — sin paleta codificada a mano. - Kit de componentes compartido. La UI está construida sobre un kit
awpropio cuyos nombres de clase, tokens y ubicación de popups coinciden uno a uno con el USS del editor y el mockup HTML canónico. Un solo mockup ahora alimenta dos puertos — la app web y el editor de UIToolkit — en lugar de que la web se desvíe por su cuenta.web/Docs/ui-parity.mdregistra cómo la web sigue a studio cuando este cambia. - Editores de celda compartidos. Qué widget recibe una celda lo decide la pista de editor de celda del núcleo — primero el registro de un paquete, luego la tabla integrada (
BuiltinCellEditorHints) — así que un tipo de plugin que declara el arquetipoColorPicker,CurveEditoroGradientEditorabre aquí los mismos editores que abre en Unity, y los dos hosts no pueden elegir widgets distintos para el mismo nombre de tipo. - Paridad de lienzo. Arrastrar y soltar alcanzó paridad completa con el editor: paneo con arrastre del botón central o Alt-arrastre, menús en cascada de espacio vacío, inspectores de cable y de nodo, efecto fantasma del cable seleccionado, y eliminación de término con un diálogo de confirmación. El rango de zoom es el del editor (25–200 %), y las métricas de tarjeta vienen del núcleo en lugar de una segunda copia en JavaScript.
- Lista de tipos compartida. El menú desplegable de
@typeofrece lo que el registro de parsers realmente conoce, agrupado exactamente como lo agrupa el editor: los escalares integrados (Color,AnimationCurveyGradientincluidos), las clavesRecordId/IntId, las referenciasRecordId@TabeIntId@Tab,Enum<…>,AssetRef@Group, y cualquier tipo o wrapper que un plugin cargado haya registrado. Un plugin que registra un tipo nuevo por lo tanto aparece en el navegador sin ningún cambio web. (Antes de que el núcleo de WebAssembly termine de arrancar, el primer pintado recae en los cuatro escalares integrados.)
Cuándo usar cada uno
- Usa el navegador para creación rápida, validación y ediciones de hoja desde cualquier lugar, y para compañeros de equipo que no abren Unity.
- Usa Unity cuando necesites clases C# generadas y ScriptableObjects generados mediante bake — los pasos de importación, codegen y bake.
Ambos escriben en la misma hoja, así que un cambio hecho en uno lo recoge el otro en la siguiente lectura.
Páginas relacionadas
- Sintaxis de la hoja — las reglas que impone el núcleo del navegador, sin cambios
- Hojas de localización — hojas de texto de juego, en el navegador y en el editor
- Mercado de plugins web — instalar y cargar lateralmente plugins en el navegador
- Acceso web a Hojas de Google — leer y escribir hojas desde el sitio desplegado
- Data Studio — la superficie de creación en el editor que refleja la app web