Repository navigation
Runtime es
🌐 Esta página en: English · Português · Español · Français · Deutsch
El Runtime de eQuantic.UI es la biblioteca que da vida a la aplicación en el navegador. Es responsable de transformar el árbol virtual que genera el código compilado en elementos del DOM reales y de reaccionar a los cambios de estado.
El runtime se distribuye como un único archivo empaquetado (runtime.js; su tamaño no se cita aquí, porque su tamaño gzip es un presupuesto que ServedRuntimeBudgetTests hace cumplir, vea Flujo de build) que incluye:
- Runtime central: el reconciliador de DOM virtual, el ciclo de vida de los componentes
- Gestión de estado: el sistema de estado reactivo
- Sistema de eventos: el seguimiento de eventos basado en WeakMap
- Puente de Server Actions: la comunicación RPC entre cliente y servidor
- Herramientas de desarrollo: logger y overlay de errores (solo en desarrollo)
- Proveedor de servicios: el contenedor de inyección de dependencias
El runtime viaja dentro del paquete que lo sirve, eQuantic.UI.Server: el Server incrusta el
bundle y responde /_equantic/runtime.js con él, y lleva los mismos bytes como archivo en
tools/runtime/runtime.js. El SDK copia ese archivo al wwwroot/_equantic/ de la aplicación durante
el build (el target de MSBuild CopyEQuanticRuntime) para las herramientas que cargan los módulos de
una aplicación fuera de un servidor, como la vista previa de VS Code; a una aplicación en marcha
siempre se le responde con el bundle incrustado.
Flujo de build:
Fuente TypeScript (src/eQuantic.UI.Runtime/src) + boot.ts (src/eQuantic.UI.Sdk/Resources)
↓ target BundleRuntime de eQuantic.UI.Server (bun embebido), antes de cada build
src/eQuantic.UI.Server/wwwroot/runtime.js (UN bundle, y su único escritor)
├─ incrustado en eQuantic.UI.Server.dll → servido en /_equantic/runtime.js
↓ target CollectServedRuntime, al empaquetar
eQuantic.UI.Server.nupkg/tools/runtime/runtime.js
↓ el SDK lo resuelve vía $(PkgeQuantic_UI_Server)
↓ target de MSBuild CopyEQuanticRuntime
wwwroot/_equantic/runtime.js del consumidor (los mismos bytes)
Beneficios de la arquitectura:
- ✅ Un solo escritor: el bundle se escribe una vez, por el paquete que lo sirve; el SDK solo lo referencia
- ✅ La copia ES el runtime servido: lo que una aplicación encuentra en
wwwroot/_equantic/runtime.jses byte por byte lo que responde/_equantic/runtime.js - ✅ Sin duplicación: una única fuente de verdad para runtime.js
- ✅ Cero dependencias: quien lo consume recibe el runtime automáticamente, sin Node.js ni npm
A diferencia de los frameworks que recrean el DOM entero, el Reconciler de eQuantic.UI compara la página actual con la nueva versión deseada y aplica solo los cambios mínimos necesarios.
-
Comparación de tipo: si un nodo cambió de etiqueta (por ejemplo, de
divaspan), se reemplaza por completo. - Actualización de atributos: solo los atributos modificados se cambian en el DOM.
- Gestión de hijos: el reconciliador recorre recursivamente la lista de hijos.
El reconciliador soporta el Keyed Diffing a través de la propiedad key.
- Si dos nodos en posiciones distintas tienen la misma clave, el framework entiende que el elemento se movió, y preserva el estado interno del navegador (como la posición del cursor en un campo o el estado del scroll).
Para prevenir fugas de memoria, el runtime usa un sistema de seguimiento de eventos basado en WeakMap.
- Los listeners de eventos se mapean directamente al
HTMLElement. - Cuando un elemento se retira del DOM y no quedan más referencias a él, el recolector de basura del navegador puede limpiar automáticamente los metadatos del evento, lo que asegura que el consumo de memoria de la aplicación se mantenga estable incluso en sesiones largas.
Desde 0.2.0-preview.24
El espejo de HtmlElement baja las propiedades on* a nombres de eventos del DOM, con la grafía
propia del DOM allí donde pasarlo a minúsculas no basta: OnDoubleClick registra dblclick (la
única divergencia del EventNameMap de C#: un listener de doubleclick se engancha bien y no se
dispara nunca). Y fijar OnSubmit toma la PROPIEDAD del envío: el runtime llama a
preventDefault() antes de invocar, así que el envío con navegación propio del navegador nunca
corre, y el manejador valida y llama a una server action en su lugar. Un formulario que quiere el
envío nativo simplemente no fija ningún manejador. click conserva los valores por defecto del
navegador que siempre tuvo: un clic en una etiqueta debe seguir alternando su casilla.
Desde 0.2.0-preview.24
Las capas de overlay modales llegan de los dos productores llevando role="dialog", aria-modal,
tabindex="-1" y un marcador data-eq-trap. El controlador del cliente reconcilia las trampas
contra el DOM en el mismo momento en que el conjunto de Shortcuts se confirma después de cada pasada
del reconciliador: una capa que apareció registra a quien la invocó y toma el foco después del
siguiente frame (una capa que se desvanece desde visibility:hidden no es enfocable hasta que el
estilo aterriza); Tab y Shift+Tab circulan dentro, y una guarda de focusin recupera lo que se
escapa; una capa que dejó de estar marcada (retirada, cerrada manteniéndose montada, o reparentada
para su animación de salida) devuelve el foco a quien la invocó. Descubrir por marcador en lugar de
por ruta es lo que mantiene a los dos productores idénticos byte a byte.
El runtime soporta el proceso de "hidratación", en el que toma el control del HTML que el servidor ya renderizó (SSR). En lugar de destruir y recrear, el runtime solo engancha los listeners de eventos necesarios a los elementos existentes, lo que asegura una carga inicial instantánea.
El runtime detecta el entorno vía el flag window.__EQ_DEV__ (que fija el servidor a partir de IWebHostEnvironment.IsDevelopment()).
Sistema de logging profesional que solo emite en modo de desarrollo:
import { logger } from './utils/logger';
logger.debug('Boot process started'); // Solo en desarrollo
logger.info('Component rendered'); // Solo en desarrollo
logger.warn('Deprecated API used'); // Siempre registra
logger.error('Failed to load data'); // Siempre registraTodos los logs llevan el prefijo [eQuantic.UI] para filtrarlos con facilidad.
Overlay de errores al estilo de Next.js que muestra los errores de runtime en una interfaz a pantalla completa (solo en desarrollo):
- Captura automática: errores no manejados y rechazos de promesas
- Stack traces: el contexto completo del error con información de la fuente
-
Soporte de teclado: pulsa
Escpara cerrar - UX limpia: similar al overlay de errores de Next.js
El overlay de errores se importa y se activa automáticamente cuando window.__EQ_DEV__ === true.
En los builds de producción:
-
logger.debug()ylogger.info()quedan silenciados - El overlay de errores nunca se carga
- Solo
logger.warn()ylogger.error()emiten a la consola - Coste mínimo de runtime: un bundle, cuyo tamaño gzip es un presupuesto que la suite hace cumplir, en lugar de un número citado aquí
El tema de la aplicación es C# tipado en el servidor (IAppTheme, seleccionado vía UseTheme, vea
DesignSystem). El servidor serializa el tema seleccionado en
window.__EQ_THEME__ al lado de la configuración de boot, y el puente de tema del runtime
(shared/theme-bridge.ts) lo adopta en el boot, así que los píxeles del SSR y el lowering del
cliente resuelven los mismos tokens, y un cambio claro/oscuro en tiempo de ejecución voltea una sola
declaración color-scheme.
🏁 Empieza aquí
🏗️ Arquitectura
- Visión general de la arquitectura
- Componentes write-once
- Superficie declarativa
- Arquitectura de paquetes
- Componentes
- Estilos
- Localización
- Analytics y GTM
📱 Write-once
- Motor Photon
- Design System
- Capacidades
- Almacenamiento
- Formularios
- Editor de código
- Markdown
- Mermaid
- Renderizado de email
⚙️ Compilación
⚡ Runtime
🔌 Servidor
🎨 Ecosistema
🚀 Desarrollo