Valendo

Compilar desde el Código Fuente

Electron 43, React 19, TypeScript 7, Vite 7, Tailwind 4.

git clone https://github.com/samaBR85/Valendo-TeleprompterSuite.git
cd Valendo-TeleprompterSuite
npm install
npm run dev

Si npm install no descarga el binario de Electron, ejecuta node node_modules/electron/install.js.

En Windows, Abrir Valendo.bat hace la instalación y la compilación en el primer doble clic, para quienes no tienen una terminal abierta.

Comandos

ComandoQué hace
npm run devDesarrollo, con hot reload
npm run buildEmpaqueta main, preload y renderer en out/
npm testLa suite de pruebas
npm run typechecktsc --noEmit
npm run start:debugEjecuta la aplicación compilada con depuración remota en el puerto 9222
npm run verifyComprueba los criterios de aceptación contra la aplicación en ejecución (necesita start:debug)
npm run dist:winEl instalador de Windows (NSIS) en dist/
npm run dist:macLas imágenes de disco de macOS, arm64 y x64, en dist/

dist:mac solo funciona en macOS — las herramientas de firma de Apple no existen en otros sistemas. El flujo de release compila cada plataforma en su propio runner.

Macs Intel

No hay descarga para Intel. La aplicación se compila y ejecuta perfectamente en macOS Intel — npm run dist:mac -- --x64 produce la imagen de disco — pero la compilación no se publica, porque los runners Intel de macOS de GitHub nunca estuvieron disponibles: el trabajo quedó en cola durante tres intentos consecutivos sin llegar a empezar. Un instalador que no se puede producir de forma fiable es una promesa, no una release.

Reabrirlo es un cambio de dos líneas en la matriz del flujo de trabajo, y el script de compilación de ffmpeg ya es agnóstico respecto a la arquitectura — compila para cualquier máquina en la que se ejecute.

Releases

.github/workflows/release.yml compila Windows y macOS arm64 cada vez que se empuja una etiqueta v*, y adjunta los instaladores a la release. Los runners macos-14 son Apple Silicon, que es donde hay que compilar la imagen de disco arm64.

Ejecutar el flujo de trabajo manualmente (Actions → Release → Run workflow) compila los mismos artefactos sin crear una release, y los deja como artefactos de trabajo descargables — útil para probar una compilación antes de decidir que merece una etiqueta.

La compilación dist:mac está firmada ad-hoc: Apple Silicon se niega a abrir un binario sin ninguna firma, pero la firma ad-hoc no dice nada sobre quién la construyó. Una compilación que haces tú mismo se ejecuta sin problemas, porque nada se descargó para ponerlo en cuarentena. El .dmg de la página de descarga es una compilación aparte, firmada con un Developer ID y notarizada por Apple, así que también abre con doble clic.

Estructura

src/main/       ventanas, monitores, estado autoritativo, persistencia
src/preload/    el puente IPC expuesto al renderer
src/shared/     lógica pura y comprobable: ancla, líneas, velocidad, historial, comandos
src/renderer/   prompter (compartido), interfaz del operador, ventana de transmisión
scripts/        verificación end-to-end mediante el protocolo Chromium
docs/           capturas de pantalla usadas en el README y en este manual

La forma del asunto

Hay un único estado autoritativo, en el proceso principal, en src/main/state.ts. Los renderers nunca guardan su propia copia de nada que importe; despachan acciones y reflejan lo que vuelve.

src/shared no tiene Electron ni React. Es donde viven el ancla, la composición de líneas, la aritmética de velocidad, el historial de deshacer y el registro de comandos, y es donde está casi toda la lógica de pruebas — la lógica puede demostrarse sin lanzar una ventana.

Pruebas

npm test

La suite cubre la lógica pura y las partes del proceso principal que se pueden alcanzar con una carpeta userData simulada: el ancla tras un reflujo, composición de líneas, velocidad en los tres modos, qué viaja y qué no dentro de un .valendo, migración de proyectos escritos por versiones anteriores y los diccionarios de i18n.

La prueba de i18n merece conocerse: garantiza que los seis diccionarios tienen exactamente el mismo conjunto de claves, que ninguno está vacío y que las marcas {interpolation} sobreviven a la traducción. Olvidar un idioma rompe la compilación en lugar de enviar una etiqueta en blanco.

Comprobaciones end-to-end

scripts/verify.mjs conduce la aplicación en ejecución mediante el Chromium DevTools Protocol: lanza con una carpeta de datos de usuario aislada, despacha entrada real y hace aserciones contra el DOM real. Así es como se comprueban los criterios de aceptación — incluido el que más importa, que la palabra bajo la línea de lectura no se mueve cuando el texto por encima de ella cambia.

npm run start:debug     # en una terminal
npm run verify          # en otra

Versionado

La versión semántica es una decisión humana, definida a mano en package.json. El número de compilación sube solo con cada npm run build, a través de scripts/bump-build.mjs, y aparece en el encabezado de la aplicación y en los créditos como vX.Y.Z - build N.

De este modo, un informe de error que nombra un vX.Y.Z - build N exacto apunta a un paquete preciso, sin que nadie tenga que recordar incrementar un número antes de cortar una release.

ffmpeg redistribuido

Los dos instaladores llevan binarios distintos, bajo licencias diferentes.

Windows. ffmpeg 6.1.1 de gyan.dev, fijado en package-lock.json y descargado a través de ffmpeg-static. GPL 3.0, configurado con --enable-gpl --enable-version3 --enable-libx264.

macOS. ffmpeg 6.1.1 compilado desde el código fuente por la propia CI de este proyecto, en cada release, a través de scripts/build-ffmpeg-mac.sh. Elimina libx264 y codifica mediante el VideoToolbox del propio sistema, lo que mantiene el resultado en LGPL 2.1 — la Mac App Store no acepta software GPL. El propio guard del script hace fallar la compilación si --enable-gpl, --enable-version3 o --enable-nonfree aparecen en el resultado, o si el binario no se reporta como LGPL 2.1.

Ejecútalo directamente para reproducir el binario de macOS:

scripts/build-ffmpeg-mac.sh

No recibe argumentos más allá de un FFMPEG_VERSION opcional (por defecto 6.1.1), e imprime la cadena configuration: resultante y el aviso de licencia al final.

En cualquier caso, la fuente correspondiente para ambas plataformas es la release oficial de FFmpeg 6.1.1, sin modificar: ffmpeg.org/download.html y el repositorio oficial, etiqueta n6.1.1. Desglose completo de licencias: ffmpeg redistribuido.

Como ffmpeg es un ejecutable real, se desempaqueta junto a app.asar en lugar de dentro de él — un binario archivado no puede ejecutarse.

Contribución

Los issues y pull requests son bienvenidos. Dos cosas que conviene saber antes de abrir uno: