GUI WASM (forja-wasm-gui)

Crate: crates/forja-wasm-gui/ — la GUI de Forja compilada a WebAssembly

¿Por qué existe?

Renderiza interfaces Forja dentro de un <canvas> HTML5 usando la Canvas 2D API. Es una implementación liviana y autónoma del runtime GUI: no depende de winit, Xilem, Masonry ni Vello, por lo que puede ejecutarse en el navegador como un módulo WASM. Es la pieza que habilita el playground web de la documentación para mostrar GUIs Forja sin servidor nativo.

Arquitectura del pipeline:

Código Forja (.fa)
  → forja::compilar_con_ast() → AST
  → extraer_layout() → Layout simplificado
  → renderizar_layout() → Canvas 2D
  → eventos (click) → hit-testing sobre rectángulos
  → ejecutar_funcion() (evaluador tree-walking)

Estructuras clave

ComponenteDescripción
ValorGUIValor dinámico del evaluador: Texto, Entero, Decimal, Booleano, Nulo; con es_verdadero(), to_display(), to_json_value()/from_serde() y to_f64()
LayoutRepresentación intermedia de UI: Column, Row, ZStack, Label, VariableLabel, Button, TextInput, Title, Spacer y Unimplemented (placeholder para widgets no soportados en Canvas)
VariableStoreVariables globales como Rc<RefCell<HashMap<String, serde_json::Value>>> (single-threaded para WASM); los widgets que leen variables se actualizan desde aquí
AmbitoÁmbito de variables del evaluador por llamada de función
WidgetHitAreaRectángulo (x, y, ancho, alto) + referencia al Layout para el hit-testing de eventos
AppStateEstado global en thread_local!: store, declaraciones AST, hit_areas, último layout y tamaño del canvas

Tema Material You simplificado

El renderizador usa una paleta fija basada en Material Design 3: COLOR_PRIMARY #6750A4, COLOR_ON_PRIMARY, COLOR_PRIMARY_CONTAINER, COLOR_SECONDARY, COLOR_SURFACE #F5F0F7, COLOR_ON_SURFACE, COLOR_OUTLINE, COLOR_BACKGROUND #FEF7FF, COLOR_ERROR #B3261E, etc.

Renderizado y eventos

FunciónDescripción
renderizar_layout()Recorre el layout dibujando en el canvas y registrando las WidgetHitArea; devuelve el tamaño usado por cada sub-layout
renderizar_boton()Botón Material (sombra + fondo primario + texto centrado) con radio redondeado; registra su hit area
renderizar_text_input()Campo estilo filled con borde inferior, muestra el valor actual o el placeholder
redondear_rect()Path 2D de rectángulo redondeado
extraer_layout() / expr_a_layout()Busca la función main en el AST y convierte las llamadas de UI (columna, fila, pila, etiqueta, titulo, etiqueta_dinamica, boton, entrada_texto, espacio… y alias en inglés) al enum Layout
procesar_click()Hit-testing de atrás hacia adelante (Z-order); si el widget es un botón, ejecuta su callback con el evaluador; los TextInput solo logean a consola por ahora
configurar_eventos_canvas()Adjunta un listener click al canvas vía add_event_listener_with_callback

Evaluador tree-walking

ejecutar_funcion(), evaluar_bloque(), evaluar_declaracion() y evaluar_expresion() implementan un intérprete simplificado del AST: soporta variables, asignaciones, si/sino, mientras, para, cuando, retornos, aritmética, comparaciones, lógica, arreglos/mapas como JSON, ternarios e indexación. Operaciones sin soporte en WASM (Closure, Hilo, CanalNuevo, Seleccionar, Instanciacion, Match) retornan error explícito. inicializar_estado() evalúa main() para precargar las variables iniciales en el store.

Exports wasm-bindgen

FunciónFirma JSDescripción
version()() → StringRetorna "forja-wasm-gui v0.1.0"
renderizar(canvas_id, codigo)(String, String) → StringCompila el código, inicializa estado, extrae layout, lo dibuja en el canvas y configura eventos; retorna "ok" o un mensaje de error
ejecutar_gui(canvas_id, codigo)(String, String) → StringAtajo: renderizar + eventos
rerenderizar(canvas_id)(String) → StringRe-renderiza el último layout (útil después de un evento que cambió variables)

Compilación con wasm-bindgen

El crate es crate-type = ["cdylib"] y depende de wasm-bindgen 0.2, js-sys 0.3, web-sys (features de canvas/DOM/eventos), el crate raíz forja (path = "../..") y serde_json. En CI (rust.yml) se compila con:

WASM_OPT=false wasm-pack build crates/forja-wasm-gui --target web \
  --out-dir ../../wasm-output-gui --out-name forja_wasm_gui --no-opt
wasm-opt --enable-bulk-memory --enable-nontrapping-float-to-int \
  --enable-sign-ext -O3 wasm-output-gui/forja_wasm_gui_bg.wasm -o …

Los artefactos (forja_wasm_gui.js + forja_wasm_gui_bg.wasm) se publican en GitHub Releases; el workflow de deploy de docs los descarga a docs/src/wasm/ y docs/public/wasm/.

Relación con forja-gui-rt y el playground

ComponenteRelación
forja-gui-rtRuntime GUI nativo (Xilem/Masonry/Vello) para apps de escritorio y el Native Activity Android. forja-wasm-gui es una reimplementación independiente en Canvas 2D que no comparte código de rendering, pero imita su semántica de widgets y su sistema de variables reactivas
Playground webdocs/src/pages/playground.astro carga forja_wasm_gui.js (con un stub en docs/src/wasm/ cuando el WASM no está disponible) y llama forjaWasmGui.ejecutar_gui('forja-canvas', source) para renderizar la GUI del código del usuario
Crate raíz forjaAporta el compilador completo: forja::compilar_con_ast() produce el AST que luego se convierte en Layout
Estado: el crate es un submodule git (forja-lang/forja-wasm-gui) y su GUI es un subconjunto funcional del runtime nativo: columnas, filas, z-stacks, labels, botones, inputs de texto, títulos y spacers. Los widgets avanzados se muestran como Unimplemented.